private static Animation CreateAnimation(SerializableAnimation animationContent) { Animation animation = new Animation(animationContent.name); animation.SetLength(animationContent.length); foreach (SerializableTrack trackContent in animationContent.tracks) { AnimationTrack track = animation.CreateTrack(trackContent.name); for (int i = 0; i < trackContent.keyframes.Count; i++) { SerializableKeyFrame keyFrameContent = trackContent.keyframes[i]; AnimationKeyFrame keyFrame = new AnimationKeyFrame { rotation = keyFrameContent.rotation, scale = keyFrameContent.scale, translation = keyFrameContent.translation, time = keyFrameContent.time }; track.AddKeyFrame(keyFrame); } } return animation; }
//----------------------------------------------------------------------- public void InterpolateToKeyframe(AnimationKeyFrame keyframe, float weight) { weight = 1 - weight; float frameTime = MathHelper.Lerp(this.time, keyframe.time, weight); this.rotation = Quaternion.Lerp(this.rotation, keyframe.rotation, weight); this.scale = this.scale * (1 - weight) + keyframe.scale * weight; this.translation = this.translation * (1 - weight) + keyframe.translation * weight; }
//----------------------------------------------------------------------- public float GetKeyFramesAtTime(float time, out AnimationKeyFrame keyframeA, out AnimationKeyFrame keyframeB) { //this code might be wrong // https://github.com/FrictionalGames/HPL1Engine/blob/master/sources/graphics/AnimationTrack.cpp#L152 float totalAnimLength = parent.GetLength(); time = MathHelper.Clamp(time, 0, totalAnimLength); //If longer than max time return last frame and first if (time >= maxFrameTime) { keyframeA = keyframes[keyframes.Count - 1]; keyframeB = keyframes[0]; return(0.0f); } //Find the second frame. int keyframeIndexB = -1; for (int i = 0; i < keyframes.Count; i++) { if (time <= keyframes[i].time) { keyframeIndexB = i; break; } } //If first frame was found, the lowest time is not 0. //If so return the first frame only. if (keyframeIndexB == 0) { keyframeA = keyframes[0]; keyframeB = keyframes[0]; return(0.0f); } //Get the frames keyframeA = keyframes[keyframeIndexB - 1]; keyframeB = keyframes[keyframeIndexB]; float deltaTime = keyframeB.time - keyframeA.time; return((time - keyframeA.time) / deltaTime); }
//----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- public void AddKeyFrame(AnimationKeyFrame frame) { float time = frame.time; if (time > maxFrameTime || keyframes.Count == 0) { keyframes.Add(frame); maxFrameTime = time; } else { int i; for (i = 0; i < keyframes.Count; i++) { if (time < keyframes[i].time) break; } keyframes.Insert(i, frame); } }
//----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- public void AddKeyFrame(AnimationKeyFrame frame) { float time = frame.time; if (time > maxFrameTime || keyframes.Count == 0) { keyframes.Add(frame); maxFrameTime = time; } else { int i; for (i = 0; i < keyframes.Count; i++) { if (time < keyframes[i].time) { break; } } keyframes.Insert(i, frame); } }
//----------------------------------------------------------------------- public AnimationKeyFrame GetInterpolatedKeyFrame(float time) { AnimationKeyFrame resultKeyFrame = new AnimationKeyFrame(time); AnimationKeyFrame keyFrameA; AnimationKeyFrame keyFrameB; float frameTime = GetKeyFramesAtTime(time, out keyFrameA, out keyFrameB); if(frameTime == 0.0f) { resultKeyFrame.rotation = keyFrameA.rotation; resultKeyFrame.scale = keyFrameA.scale; resultKeyFrame.translation = keyFrameA.translation; } else { resultKeyFrame.rotation = Quaternion.Lerp(keyFrameA.rotation, keyFrameB.rotation, frameTime); resultKeyFrame.scale = keyFrameA.scale * (1 - frameTime) + keyFrameB.scale * frameTime; resultKeyFrame.translation = keyFrameA.translation * (1 - frameTime) + keyFrameB.translation * frameTime; } return resultKeyFrame; }
//----------------------------------------------------------------------- public AnimationKeyFrame GetInterpolatedKeyFrame(float time) { AnimationKeyFrame resultKeyFrame = new AnimationKeyFrame(time); AnimationKeyFrame keyFrameA; AnimationKeyFrame keyFrameB; float frameTime = GetKeyFramesAtTime(time, out keyFrameA, out keyFrameB); if (frameTime == 0.0f) { resultKeyFrame.rotation = keyFrameA.rotation; resultKeyFrame.scale = keyFrameA.scale; resultKeyFrame.translation = keyFrameA.translation; } else { resultKeyFrame.rotation = Quaternion.Lerp(keyFrameA.rotation, keyFrameB.rotation, frameTime); resultKeyFrame.scale = keyFrameA.scale * (1 - frameTime) + keyFrameB.scale * frameTime; resultKeyFrame.translation = keyFrameA.translation * (1 - frameTime) + keyFrameB.translation * frameTime; } return(resultKeyFrame); }
//----------------------------------------------------------------------- public float GetKeyFramesAtTime(float time, out AnimationKeyFrame keyframeA, out AnimationKeyFrame keyframeB) { //this code might be wrong // https://github.com/FrictionalGames/HPL1Engine/blob/master/sources/graphics/AnimationTrack.cpp#L152 float totalAnimLength = parent.GetLength(); time = MathHelper.Clamp(time, 0, totalAnimLength); //If longer than max time return last frame and first if(time >= maxFrameTime) { keyframeA = keyframes[keyframes.Count-1]; keyframeB = keyframes[0]; return 0.0f; } //Find the second frame. int keyframeIndexB=-1; for(int i=0; i< keyframes.Count; i++) { if (time <= keyframes[i].time) { keyframeIndexB = i; break; } } //If first frame was found, the lowest time is not 0. //If so return the first frame only. if(keyframeIndexB == 0) { keyframeA = keyframes[0]; keyframeB = keyframes[0]; return 0.0f; } //Get the frames keyframeA = keyframes[keyframeIndexB - 1]; keyframeB = keyframes[keyframeIndexB]; float deltaTime = keyframeB.time - keyframeA.time; return (time - keyframeA.time) / deltaTime; }
//----------------------------------------------------------------------- public void InterpolateToKeyframe(AnimationKeyFrame keyframe, float weight) { weight = 1 - weight; float frameTime = MathHelper.Lerp(this.time, keyframe.time, weight); this.rotation = Quaternion.Lerp(this.rotation, keyframe.rotation, weight); this.scale = this.scale * (1 - weight) + keyframe.scale * weight; this.translation = this.translation * (1 - weight) + keyframe.translation * weight; }