/// <summary> /// Called during the update loop to move the animation forward /// </summary> /// <param name="gameTime"></param> public virtual void Update(GameTime gameTime) { if (currentClipValue == null) { return; } if (paused) { return; } TimeSpan time = gameTime.ElapsedGameTime; // Adjust for the rate if (playbackRate != 1.0f) { time = TimeSpan.FromMilliseconds(time.TotalMilliseconds * playbackRate); } elapsedPlaybackTime += time; // See if we should terminate if (elapsedPlaybackTime >= duration && duration != TimeSpan.Zero || elapsedPlaybackTime >= currentClipValue.Duration && duration == TimeSpan.Zero) { if (Completed != null) { Completed(this, EventArgs.Empty); } currentClipValue = null; return; } // Update the animation position. time += currentTimeValue; // If we reached the end, loop back to the start. while (time >= currentClipValue.Duration) { time -= currentClipValue.Duration; } CurrentTimeValue = time; OnUpdate(); }
/// <summary> /// Starts playing a clip /// </summary> /// <param name="clip">Animation clip to play</param> /// <param name="playbackRate">Speed to playback</param> /// <param name="duration">Length of time to play (max is looping, 0 is once)</param> public void StartClip(ModelAnimationClip clip, float playbackRate, TimeSpan duration) { if (clip == null) { throw new ArgumentNullException("Clip required"); } // Store the clip and reset playing data currentClipValue = clip; currentKeyframe = 0; CurrentTimeValue = TimeSpan.Zero; elapsedPlaybackTime = TimeSpan.Zero; paused = false; // Store the data about how we want to playback this.playbackRate = playbackRate; this.duration = duration; // Call the virtual to allow initialization of the clip InitClip(); }
protected override AnimationData Read(ContentReader input, AnimationData existingInstance) { if (existingInstance != null) { return(existingInstance); } List <Matrix> bindPose = null; List <Matrix> invBindPose = null; Dictionary <string, ModelAnimationClip> modelAnim = null; Dictionary <string, ModelAnimationClip> rootAnim = null; List <int> skeleHierarchy = null; BinaryDataReader ad; int size = input.ReadInt32(); VirtualStream vs = new VirtualStream(input.BaseStream, input.BaseStream.Position, size); ad = new BinaryDataReader(vs); #region BindPoseTag if (ad.Contains(BindPoseCountTag)) { int count = ad.GetDataInt32(BindPoseCountTag); bindPose = new List <Matrix>(count); ContentBinaryReader br2 = ad.GetData(BindPoseTag); for (int i = 0; i < count; i++) { bindPose.Add(br2.ReadMatrix()); } br2.Close(); } #endregion #region InvBindPoseTag if (ad.Contains(InvBindPoseCountTag)) { int count = ad.GetDataInt32(InvBindPoseCountTag); invBindPose = new List <Matrix>(count); ContentBinaryReader br2 = ad.GetData(InvBindPoseTag); for (int i = 0; i < count; i++) { invBindPose.Add(br2.ReadMatrix()); } br2.Close(); } #endregion #region AnimationClipTag if (ad.Contains(ModelAnimationClipCountTag)) { int count = ad.GetDataInt32(ModelAnimationClipCountTag); modelAnim = new Dictionary <string, ModelAnimationClip>(count); ContentBinaryReader br2 = ad.GetData(ModelAnimationClipTag); for (int i = 0; i < count; i++) { string key = br2.ReadStringUnicode(); TimeSpan duration = TimeSpan.FromSeconds(br2.ReadDouble()); int frameCount = br2.ReadInt32(); List <ModelKeyframe> frames = new List <ModelKeyframe>(frameCount); for (int j = 0; j < frameCount; j++) { int bone = br2.ReadInt32(); TimeSpan totalSec = TimeSpan.FromSeconds(br2.ReadDouble()); Matrix transform = br2.ReadMatrix(); ModelKeyframe frame = new ModelKeyframe(bone, totalSec, transform); frames.Add(frame); } ModelAnimationClip clip = new ModelAnimationClip(duration, frames); modelAnim.Add(key, clip); } br2.Close(); } #endregion #region RootAnimationClipTag if (ad.Contains(RootAnimationClipCountTag)) { int count = ad.GetDataInt32(RootAnimationClipCountTag); rootAnim = new Dictionary <string, ModelAnimationClip>(count); ContentBinaryReader br2 = ad.GetData(RootAnimationClipTag); for (int i = 0; i < count; i++) { string key = br2.ReadStringUnicode(); TimeSpan duration = TimeSpan.FromSeconds(br2.ReadDouble()); int frameCount = br2.ReadInt32(); List <ModelKeyframe> frames = new List <ModelKeyframe>(frameCount); for (int j = 0; j < frameCount; j++) { int bone = br2.ReadInt32(); TimeSpan totalSec = TimeSpan.FromSeconds(br2.ReadDouble()); Matrix transform = br2.ReadMatrix(); ModelKeyframe frame = new ModelKeyframe(bone, totalSec, transform); frames.Add(frame); } ModelAnimationClip clip = new ModelAnimationClip(duration, frames); rootAnim.Add(key, clip); } br2.Close(); } #endregion #region BoneHierarchyTag if (ad.Contains(BoneHierarchyCountTag)) { int count = ad.GetDataInt32(BoneHierarchyCountTag); skeleHierarchy = new List <int>(count); ContentBinaryReader br2 = ad.GetData(BoneHierarchyTag); for (int i = 0; i < count; i++) { skeleHierarchy.Add(br2.ReadInt32()); } br2.Close(); } #endregion return(new AnimationData(modelAnim, rootAnim, bindPose, invBindPose, skeleHierarchy)); }
/// <summary> /// Starts decoding the specified animation clip. /// </summary> public void StartClip(ModelAnimationClip clip) { StartClip(clip, 1.0f, TimeSpan.MaxValue); }