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); }
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; }
/// <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); } }