} // ProcessRootAnimation

        #endregion

        #region Process Rigid Animation

        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent object to our runtime AnimationClip format.
        /// </summary>
        static ModelAnimationClip ProcessRigidAnimation(string animationName, Dictionary<string, int> boneMap, NodeContent input, ModelContent model)
        {
            List<ModelKeyframe> keyframes = new List<ModelKeyframe>();
            TimeSpan duration = TimeSpan.Zero;

            AddTransformationNodes(animationName, boneMap, input, keyframes, ref duration);

            // Sort the merged keyframes by time.
            keyframes.Sort(CompareKeyframeTimes);

            if (keyframes.Count == 0)
                throw new InvalidContentException("Animation has no keyframes.");

            if (duration <= TimeSpan.Zero)
                throw new InvalidContentException("Animation has a zero duration.");

            ModelKeyframe[] keyframesArray = new ModelKeyframe[keyframes.Count];
            for (int i = 0; i < keyframes.Count; i++)
            {
                keyframesArray[i] = keyframes[i];
            }
            return new ModelAnimationClip((float)(duration.TotalSeconds), keyframesArray);
        } // ProcessRigidAnimation
Example #2
0
 /// <summary>
 /// Comparison function for sorting keyframes into ascending time order.
 /// </summary>
 static int CompareKeyframeTimes(ModelKeyframe a, ModelKeyframe b)
 {
     return(a.Time.CompareTo(b.Time));
 }
Example #3
0
        } // ProcessAnimations

        #endregion

        #region Process Animation

        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent object to our runtime AnimationClip format.
        /// </summary>
        static ModelAnimationClip ProcessAnimation(AnimationContent animation, Dictionary <string, int> boneMap)
        {
            List <ModelKeyframe> keyframes = new List <ModelKeyframe>();

            // For each input animation channel.
            foreach (KeyValuePair <string, AnimationChannel> channel in animation.Channels)
            {
                // Look up what bone this channel is controlling.
                int boneIndex;

                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(string.Format("Found animation for bone '{0}', which is not part of the skeleton.", channel.Key));
                }

                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new ModelKeyframe((ushort)boneIndex, (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 <ModelKeyframe> keyframesReduced = new List <ModelKeyframe>();
            for (int i = 0; i < ModelAnimationClip.MaxBones; i++)
            {
                int           currentBone  = i;
                ModelKeyframe lastKeyFrame = new ModelKeyframe(255, 0, Matrix.Identity);
                foreach (ModelKeyframe modelKeyframe in keyframes)
                {
                    if (modelKeyframe.Bone == (ushort)currentBone && (lastKeyFrame.Bone != (ushort)currentBone || lastKeyFrame.Position != modelKeyframe.Position ||
                                                                      lastKeyFrame.Rotation != modelKeyframe.Rotation || lastKeyFrame.Scale != modelKeyframe.Scale))
                    {
                        keyframesReduced.Add(modelKeyframe);
                    }
                    lastKeyFrame = modelKeyframe;
                }
            }
            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.");
            }

            ModelKeyframe[] keyframesArray = new ModelKeyframe[keyframes.Count];
            for (int i = 0; i < keyframes.Count; i++)
            {
                keyframesArray[i] = keyframes[i];
            }
            return(new ModelAnimationClip((float)(animation.Duration.TotalSeconds), keyframesArray));
        } // ProcessAnimation