function update(game: Game, entity: Entity, delta: number) {
let transform = game.World.Transform[entity];
let animate = game.World.Animate[entity];
if (animate.Trigger) {
let next = animate.States[animate.Trigger];
if (next && next !== animate.Current) {
if (animate.Current.Time === 0) {
animate.Current = next;
} else if (animate.Current.Flags & AnimationFlag.EarlyExit) {
animate.Current.Time = 0;
animate.Current = next;
}
}
animate.Trigger = undefined;
}
let current_keyframe: AnimationKeyframe | null = null;
let next_keyframe: AnimationKeyframe | null = null;
for (let keyframe of animate.Current.Keyframes) {
if (animate.Current.Time < keyframe.Timestamp) {
next_keyframe = keyframe;
break;
} else {
current_keyframe = keyframe;
}
}
if (current_keyframe && next_keyframe) {
let keyframe_duration = next_keyframe.Timestamp - current_keyframe.Timestamp;
let current_keyframe_time = animate.Current.Time - current_keyframe.Timestamp;
let interpolant = current_keyframe_time / keyframe_duration;
if (next_keyframe.Ease) {
interpolant = next_keyframe.Ease(interpolant);
}
if (current_keyframe.Translation && next_keyframe.Translation) {
vec3_lerp(
transform.Translation,
current_keyframe.Translation,
next_keyframe.Translation,
interpolant
);
game.World.Signature[entity] |= Has.Dirty;
}
if (current_keyframe.Rotation && next_keyframe.Rotation) {
quat_slerp(
transform.Rotation,
current_keyframe.Rotation,
next_keyframe.Rotation,
interpolant
);
game.World.Signature[entity] |= Has.Dirty;
}
if (current_keyframe.Scale && next_keyframe.Scale) {
vec3_lerp(transform.Scale, current_keyframe.Scale, next_keyframe.Scale, interpolant);
game.World.Signature[entity] |= Has.Dirty;
}
}
let new_time = animate.Current.Time + delta;
if (new_time < animate.Current.Duration) {
animate.Current.Time = new_time;
return;
} else {
animate.Current.Time = 0;
}
if (animate.Current.Flags & AnimationFlag.Alternate) {
for (let keyframe of animate.Current.Keyframes.reverse()) {
keyframe.Timestamp = animate.Current.Duration - keyframe.Timestamp;
}
}
if (!(animate.Current.Flags & AnimationFlag.Loop)) {
animate.Current = animate.States["idle"];
}
}