The details of my Animation evaluation functions
/** Gets the float "result" as the sampled key frame value for the specfied animation track. */
public static SampleAnimationFloat(animation:BABYLON.Animation, time: number):number {
let result:number = 0;
if (animation != null && animation.dataType === BABYLON.Animation.ANIMATIONTYPE_FLOAT) {
const keys:BABYLON.IAnimationKey[] = animation.getKeys();
if (time < keys[0].frame) {
time = keys[0].frame;
} else if (time > keys[keys.length - 1].frame) {
time = keys[keys.length - 1].frame;
}
// ..
if ((<any>animation)._state == null) (<any>animation)._state = { key: 0, repeatCount: 0, loopMode: BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, workValue: BABYLON.Matrix.Zero() };
result = BABYLON.Utilities.InterpolateAnimation<number>(animation, time, (<any>animation)._state);
}
return result;
}
/** Set the passed vector2 "result" as the sampled key frame value for the specfied animation track. */
public static SampleAnimationVector2(animation:BABYLON.Animation, time: number):BABYLON.Vector2 {
let result:BABYLON.Vector2 = null;
if (animation != null && animation.dataType === BABYLON.Animation.ANIMATIONTYPE_VECTOR2) {
const keys:BABYLON.IAnimationKey[] = animation.getKeys();
if (time < keys[0].frame) {
time = keys[0].frame;
} else if (time > keys[keys.length - 1].frame) {
time = keys[keys.length - 1].frame;
}
if ((<any>animation)._state == null) (<any>animation)._state = { key: 0, repeatCount: 0, loopMode: BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, workValue: BABYLON.Matrix.Zero() };
result = BABYLON.Utilities.InterpolateAnimation<BABYLON.Vector2>(animation, time, (<any>animation)._state);
}
return result;
}
/** Set the passed vector3 "result" as the sampled key frame value for the specfied animation track. */
public static SampleAnimationVector3(animation:BABYLON.Animation, time: number):BABYLON.Vector3 {
let result:BABYLON.Vector3 = null;
if (animation != null && animation.dataType === BABYLON.Animation.ANIMATIONTYPE_VECTOR3) {
const keys:BABYLON.IAnimationKey[] = animation.getKeys();
if (time < keys[0].frame) {
time = keys[0].frame;
} else if (time > keys[keys.length - 1].frame) {
time = keys[keys.length - 1].frame;
}
if ((<any>animation)._state == null) (<any>animation)._state = { key: 0, repeatCount: 0, loopMode: BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, workValue: BABYLON.Matrix.Zero() };
result = BABYLON.Utilities.InterpolateAnimation<BABYLON.Vector3>(animation, time, (<any>animation)._state);
}
return result;
}
/** Set the passed quaternion "result" as the sampled key frame value for the specfied animation track. */
public static SampleAnimationQuaternion(animation:BABYLON.Animation, time: number):BABYLON.Quaternion {
let result:BABYLON.Quaternion = null;
if (animation != null && animation.dataType === BABYLON.Animation.ANIMATIONTYPE_QUATERNION) {
const keys:BABYLON.IAnimationKey[] = animation.getKeys();
if (time < keys[0].frame) {
time = keys[0].frame;
} else if (time > keys[keys.length - 1].frame) {
time = keys[keys.length - 1].frame;
}
if ((<any>animation)._state == null) (<any>animation)._state = { key: 0, repeatCount: 0, loopMode: BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, workValue: BABYLON.Matrix.Zero() };
result = BABYLON.Utilities.InterpolateAnimation<BABYLON.Quaternion>(animation, time, (<any>animation)._state);
}
return result;
}
/** Set the passed matrix "result" as the sampled key frame value for the specfied animation track. */
public static SampleAnimationMatrix(animation:BABYLON.Animation, time: number):BABYLON.Matrix {
let result:BABYLON.Matrix = null;
if (animation != null && animation.dataType === BABYLON.Animation.ANIMATIONTYPE_MATRIX) {
const keys:BABYLON.IAnimationKey[] = animation.getKeys();
if (time < keys[0].frame) {
time = keys[0].frame;
} else if (time > keys[keys.length - 1].frame) {
time = keys[keys.length - 1].frame;
}
if ((<any>animation)._state == null) (<any>animation)._state = { key: 0, repeatCount: 0, loopMode: BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, workValue: BABYLON.Matrix.Zero() };
result = BABYLON.Utilities.InterpolateAnimation<BABYLON.Matrix>(animation, time, (<any>animation)._state);
}
return result;
}
/** Creates a targeted float animation for tweening. */
public static CreateTweenAnimation(name:string, targetProperty:string, startValue:number, endValue:number, frameRate:number = 30, loopMode:number = BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT):BABYLON.Animation {
const keyFrames:any[] = [];
keyFrames.push({
frame: 0,
value: startValue,
});
keyFrames.push({
frame: frameRate,
value: endValue,
});
const result = new BABYLON.Animation(name, targetProperty, frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, loopMode);
result.setKeys(keyFrames);
return result;
}
/** Gets the last key frame index value. */
public static GetLastKeyFrameIndex(animation:BABYLON.Animation):number {
let result:number = 0;
if (animation != null) {
const keys:BABYLON.IAnimationKey[] = animation.getKeys();
if (keys != null && keys.length > 0) {
const lastKey:BABYLON.IAnimationKey = keys[keys.length - 1];
if (lastKey != null) {
result = lastKey.frame;
}
}
}
return result;
}
/** Private internal frame interpolation helper */
private static InterpolateAnimation<T>(animation:BABYLON.Animation, frame: number, state: BABYLON._IAnimationState): T {
return animation._interpolate(frame, state) as T;
}