} // AddAnimationNodes #endregion #region Process Root Animation /// <summary> /// Converts an intermediate format content pipeline AnimationContent /// object to our runtime AnimationClip format. /// </summary> internal static RootAnimationClip ProcessRootAnimation(AnimationContent animation, string name) { List<RootKeyframe> keyframes = new List<RootKeyframe>(); // The root animation is controlling the root of the bones AnimationChannel channel = animation.Channels[name]; // Add the transformations on the root of the model foreach (AnimationKeyframe keyframe in channel) { keyframes.Add(new RootKeyframe((float)(keyframe.Time.TotalSeconds), keyframe.Transform)); } // Sort the merged keyframes by time. keyframes.Sort(CompareKeyframeTimes); #region Key Frame Reduction // We drop key frame data where the bone transformation is equal to the previous key frame. List<RootKeyframe> keyframesReduced = new List<RootKeyframe>(); keyframesReduced.Add(keyframes[0]); for (int i = 1; i < keyframes.Count; i++) { if (keyframes[i - 1].Transform != keyframes[i].Transform) { keyframesReduced.Add(keyframes[i]); } } keyframes = keyframesReduced; // Sort the merged keyframes by time. keyframes.Sort(CompareKeyframeTimes); #endregion if (keyframes.Count == 0) throw new InvalidContentException("Animation has no keyframes."); if (animation.Duration <= TimeSpan.Zero) throw new InvalidContentException("Animation has a zero duration."); RootKeyframe[] keyframesArray = new RootKeyframe[keyframes.Count]; for (int i = 0; i < keyframes.Count; i++) { keyframesArray[i] = keyframes[i]; } return new RootAnimationClip((float)(animation.Duration.TotalSeconds), keyframesArray); } // ProcessRootAnimation
} // Play /// <summary> /// Starts playing a clip /// </summary> /// <param name="name">Animation name</param> /// <param name="playbackRate">Speed to playback</param> /// <param name="duration">Length of time to play in seconds (max is looping, 0 is once)</param> public void Play(string name, float playbackRate, float duration) { if (!rootAnimations.ContainsKey(name)) { throw new ArgumentException("Root Animation Component: the animation name does not exist."); } // Store the clip and reset playing data currentAnimationClip = rootAnimations[name]; currentKeyFrameIndex = 0; currentKeyFrame = currentAnimationClip.Keyframes[0]; CurrentTimeValue = 0; elapsedPlaybackTime = 0; paused = false; // Store the data about how we want to playback this.playbackRate = playbackRate; this.duration = duration; previousAnimationTransform = ((GameObject3D)Owner).Transform.LocalMatrix; } // Play
} // CompareKeyframeTimes /// <summary> /// Comparison function for sorting keyframes into ascending time order. /// </summary> static int CompareKeyframeTimes(RootKeyframe a, RootKeyframe b) { return a.Time.CompareTo(b.Time); } // CompareKeyframeTimes