private void ProcessAnimationRecursive(NodeContent input, AnimationClips animationClips)
        {
            foreach(KeyValuePair<string, AnimationContent> animation in input.Animations)
            {
                // do we have this animation before?
                AnimationClips.Clip clip;
                if (!animationClips.Clips.TryGetValue(animation.Key, out clip))
                {
                    //never before seen clip
                    System.Diagnostics.Trace.WriteLine("New clip: " + animation.Key);
                    clip = new AnimationClips.Clip();
                    clip.Name = animation.Key;
                    clip.Duration = animation.Value.Duration.TotalSeconds;
                    clip.Keyframes = new List<AnimationClips.Keyframe>[bones.Count];
                    for (int b = 0; b < bones.Count; b++)
                        clip.Keyframes[b] = new List<AnimationClips.Keyframe>();

                    animationClips.Clips[animation.Key] = clip;
                }

                //for each canell, determine the bone and then process all of the keyframes for that bone
                foreach (KeyValuePair<string, AnimationChannel> channel in animation.Value.Channels)
                {
                    // what is the bone index?
                    int boneIndex;
                    if (!bones.TryGetValue(channel.Key, out boneIndex))
                        continue; //ignore if not a named bone

                    foreach (AnimationKeyframe keyframe in channel.Value)
                    {
                        Matrix transform = keyframe.Transform; //keyframe transformation
                        AnimationClips.Keyframe newKeyFrame = new AnimationClips.Keyframe();
                        newKeyFrame.Time = keyframe.Time.TotalSeconds;

                        transform.Right = Vector3.Normalize(transform.Right);
                        transform.Up = Vector3.Normalize(transform.Up);
                        transform.Backward = Vector3.Normalize(transform.Backward);
                        newKeyFrame.Rotation = Quaternion.CreateFromRotationMatrix(transform);
                        newKeyFrame.Translastion = transform.Translation;

                        clip.Keyframes[boneIndex].Add(newKeyFrame);
                    }
                }
            }
            //System.Diagnostics.Trace.WriteLine(input.Name);

            foreach (NodeContent child in input.Children)
            {
                ProcessAnimationRecursive(child, animationClips);
            }
        }
        protected override AnimationClips Read(ContentReader input, AnimationClips existingInstance)
        {
            AnimationClips clips = new AnimationClips();

            // Determine how many clips there are.
            int clipCnt = input.ReadInt32();

            for (int c = 0; c < clipCnt; c++)
            {
                // Create a clip and load  it up
                AnimationClips.Clip clip = new AnimationClips.Clip();
                clip.Name     = input.ReadString();
                clip.Duration = input.ReadDouble();

                // Determine how many bones there are.
                int boneCnt = input.ReadInt32();
                clip.Keyframes = new List <AnimationClips.Keyframe> [boneCnt];

                for (int i = 0; i < boneCnt; i++)
                {
                    // Determine how many keyframes there are.
                    int cnt = input.ReadInt32();
                    List <AnimationClips.Keyframe> boneKeyframes = new List <AnimationClips.Keyframe>(cnt);
                    clip.Keyframes[i] = boneKeyframes;

                    for (int j = 0; j < cnt; j++)
                    {
                        AnimationClips.Keyframe keyframe = new AnimationClips.Keyframe();
                        keyframe.Time         = input.ReadDouble();
                        keyframe.Rotation     = input.ReadQuaternion();
                        keyframe.Translastion = input.ReadVector3();

                        boneKeyframes.Add(keyframe);
                    }
                }

                clips.Clips[clip.Name] = clip;
            }

            return(clips);
        }
예제 #3
0
        private AnimationClips ProcessAnimations(ModelContent model,
                                         NodeContent input, ContentProcessorContext context)
        {
            // First build a lookup table so we can determine the
            // index into the list of bones from a bone name.
            for (int i = 0; i < model.Bones.Count; i++)
            {
                bones[model.Bones[i].Name] = i;
            }

            AnimationClips animationClips = new AnimationClips();

            ProcessAnimationsRecursive(input, animationClips);

            // Ensure all animations have a first key frame for every bone
            foreach (AnimationClips.Clip clip in animationClips.Clips.Values)
            {
                for (int b = 0; b < bones.Count; b++)
                {
                    List<AnimationClips.Keyframe> keyframes = clip.Keyframes[b];
                    if (keyframes.Count == 0 || keyframes[0].Time > 0)
                    {
                        AnimationClips.Keyframe keyframe = new AnimationClips.Keyframe();
                        keyframe.Time = 0;

                        Matrix transform = model.Bones[b].Transform;
                        transform.Right = Vector3.Normalize(transform.Right);
                        transform.Up = Vector3.Normalize(transform.Up);
                        transform.Backward = Vector3.Normalize(transform.Backward);
                        keyframe.Rotation = Quaternion.CreateFromRotationMatrix(transform);
                        keyframe.Translation = transform.Translation;

                        keyframes.Insert(0, keyframe);
                    }
                }
            }

            return animationClips;
        }
예제 #4
0
        /// <summary>
        /// Recursive function that processes the entire scene graph, collecting up
        /// all of the animation data.
        /// </summary>
        /// <param name="input">The input scene graph node</param>
        /// <param name="animationClips">The animation clips object we put animation in</param>
        private void ProcessAnimationsRecursive(NodeContent input, AnimationClips animationClips)
        {
            foreach (KeyValuePair<string, AnimationContent> animation in input.Animations)
            {
                // Do we have this animation before?
                AnimationClips.Clip clip;
                if (!animationClips.Clips.TryGetValue(animation.Key, out clip))
                {
                    // Never before seen clip
                    // System.Diagnostics.Trace.WriteLine("New clip: " + animation.Key);

                    clip = new AnimationClips.Clip();
                    clip.Name = animation.Key;
                    clip.Duration = animation.Value.Duration.TotalSeconds;
                    clip.Keyframes = new List<AnimationClips.Keyframe>[bones.Count];
                    for (int b = 0; b < bones.Count; b++)
                        clip.Keyframes[b] = new List<AnimationClips.Keyframe>();

                    animationClips.Clips[animation.Key] = clip;
                }
                else if (animation.Value.Duration.TotalSeconds > clip.Duration)
                {
                    clip.Duration = animation.Value.Duration.TotalSeconds;
                }

                //
                // For each channel, determine the bone and then process all of the
                // keyframes for that bone.
                //

                foreach (KeyValuePair<string, AnimationChannel> channel in animation.Value.Channels)
                {
                    // What is the bone index?
                    int boneIndex;

                    // Get rid of unnamed bones
                    if (!bones.TryGetValue(channel.Key, out boneIndex))
                    {
                        continue;           // Ignore if not a named bone
                    }

                    // Get rid of useless animations
                    if (!skinned && IsUselessAnimation(boneIndex))
                    {
                        // System.Diagnostics.Debug.WriteLine("Removed " + boneIndex.ToString());
                        continue;           // Ignore if useless
                    }

                    foreach (AnimationKeyframe keyframe in channel.Value)
                    {
                        Matrix transform = keyframe.Transform;      // Keyframe transformation

                        AnimationClips.Keyframe newKeyframe = new AnimationClips.Keyframe();
                        newKeyframe.Time = keyframe.Time.TotalSeconds;

                        transform.Right = Vector3.Normalize(transform.Right);
                        transform.Up = Vector3.Normalize(transform.Up);
                        transform.Backward = Vector3.Normalize(transform.Backward);
                        newKeyframe.Rotation = Quaternion.CreateFromRotationMatrix(transform);
                        newKeyframe.Translation = transform.Translation;

                        clip.Keyframes[boneIndex].Add(newKeyframe);
                    }

                    // Linear keyframe reduction (remove from clip.Keyframes)
                    System.Diagnostics.Debug.WriteLine(clip.Keyframes[boneIndex].Count);
                    LinkedList<AnimationClips.Keyframe> keyframes = new LinkedList<AnimationClips.Keyframe>();
                    foreach (AnimationClips.Keyframe keyframe in clip.Keyframes[boneIndex])
                    {
                        keyframes.AddLast(keyframe);
                    }
                    LinearKeyframeReduction(keyframes);
                    clip.Keyframes[boneIndex] = keyframes.ToList<AnimationClips.Keyframe>();
                    System.Diagnostics.Debug.WriteLine(clip.Keyframes[boneIndex].Count);

                }
            }

               // System.Diagnostics.Trace.WriteLine(input.Name);

            foreach (NodeContent child in input.Children)
            {
                ProcessAnimationsRecursive(child, animationClips);
            }
        }