UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

68 lines (57 loc) 2.19 kB
import { assert } from "../../../core/assert.js"; import { lerp } from "../../../core/math/lerp.js"; import { spline3_hermite } from "../../../core/math/spline/spline3_hermite.js"; import { spline3_hermite_derivative } from "../../../core/math/spline/spline3_hermite_derivative.js"; /** * Subdivide a curve segment by introducing a new keyframe at a given normalized time. * Subdivision does not alter the curve shape in any way, it is intended primarily for editing purposes. * * @param {Keyframe} out keyframe to be added at the point of subdivision, its tangents, time and value will be overwritten * @param {Keyframe} key0 start of the segment * @param {Keyframe} key1 end of the segment * @param {number} t normalized time in [0..1] between key0 and key1 where new frame is to be inserted * @returns {Keyframe} `out`, for convenience * * @see AnimationCurve * @example * const new_frame = animation_curve_subdivide(new Keyframe(), key0, key1, 0.5); * curve.add(new_frame); */ export function animation_curve_subdivide( out, key0, key1, t ) { assert.isObject(out, 'out'); assert.isObject(key0, 'key0'); assert.isObject(key1, 'key1'); assert.equal(out.isKeyframe,true,'out.isKeyframe !== true'); assert.equal(key0.isKeyframe,true,'key0.isKeyframe !== true'); assert.equal(key1.isKeyframe,true,'key1.isKeyframe !== true'); assert.isNumber(t, 't'); assert.ok(t >= 0 && t <= 1); const v0 = key0.value; const v1 = key1.value; const time_span = key1.time - key0.time; // Note that Keyframe tangents are normalized, so we denomalize them before using them const m0 = key0.outTangent * time_span; const m1 = key1.inTangent * time_span; const xm = spline3_hermite( t, v0, v1, m0, m1 ); const vm = spline3_hermite_derivative( t, v0, v1, m0, m1 ); out.time = lerp(key0.time, key1.time, t); out.value = xm; // re-normalize tangent const new_tangent = vm / time_span; out.inTangent = new_tangent; out.outTangent = new_tangent; return out; }