private void LinearKeyframeReduction(LinkedList <Clip.Keyframe> keyframes) { if (keyframes.Count < 3) { return; } for (LinkedListNode <Clip.Keyframe> node = keyframes.First.Next; ;) { LinkedListNode <Clip.Keyframe> next = node.Next; if (next == null) { break; } Clip.Keyframe a = node.Previous.Value; Clip.Keyframe b = node.Value; Clip.Keyframe c = next.Value; float t = (float)((node.Value.Time - node.Previous.Value.Time) / (next.Value.Time - node.Previous.Value.Time)); Vector3 translation = Vector3.Lerp(a.Translation, c.Translation, t); Quaternion rotation = Quaternion.Slerp(a.Rotation, c.Rotation, t); if ((translation - b.Translation).LengthSquared() < TinyLength && Quaternion.Dot(rotation, b.Rotation) > TinyCosAngle) { keyframes.Remove(node); } node = next; } }
private void AnimationDataImport(ModelContent model, NodeContent input, ContentProcessorContext context) { for (int i = 0; i < model.Bones.Count; i++) { bones[model.Bones[i].Name] = i; } boneTransforms = new Matrix[model.Bones.Count]; AnimationDataImportRec(input); if (animationData.Clips.Count == 0) { Clip clip = new Clip(); animationData.Clips.Add(clip); string clipName = "Take 001"; clips[clipName] = clip; clip.Name = clipName; foreach (ModelBoneContent bone in model.Bones) { Clip.Bone clipBone = new Clip.Bone(); clipBone.Name = bone.Name; clip.Bones.Add(clipBone); } } foreach (Clip clip in animationData.Clips) { for (int b = 0; b < bones.Count; b++) { List <Clip.Keyframe> keyframes = clip.Bones[b].Keyframes; if (keyframes.Count == 0 || keyframes[0].Time > 0) { Clip.Keyframe keyframe = new Clip.Keyframe(); keyframe.Time = 0; keyframe.Transform = boneTransforms[b]; keyframes.Insert(0, keyframe); } } } }
private void SetKeyframes() { if (ClipBone.Keyframes.Count > 0) { Keyframe1 = ClipBone.Keyframes[currentKeyframe]; if (currentKeyframe == ClipBone.Keyframes.Count - 1) { Keyframe2 = Keyframe1; } else { Keyframe2 = ClipBone.Keyframes[currentKeyframe + 1]; } } else { // If there are no keyframes, set both to null Keyframe1 = null; Keyframe2 = null; } }
private void AnimationDataImportRec(NodeContent input) { int inputBoneIndex; if (bones.TryGetValue(input.Name, out inputBoneIndex)) { boneTransforms[inputBoneIndex] = input.Transform; } foreach (KeyValuePair <string, AnimationContent> animation in input.Animations) { Clip clip; string clipName = animation.Key; if (!clips.TryGetValue(clipName, out clip)) { clip = new Clip(); animationData.Clips.Add(clip); clips[clipName] = clip; clip.Name = clipName; foreach (ModelBoneContent bone in model.Bones) { Clip.Bone clipBone = new Clip.Bone(); clipBone.Name = bone.Name; clip.Bones.Add(clipBone); } } if (animation.Value.Duration.TotalSeconds > clip.Duration) { clip.Duration = animation.Value.Duration.TotalSeconds; } foreach (KeyValuePair <string, AnimationChannel> channel in animation.Value.Channels) { int boneIndex; if (!bones.TryGetValue(channel.Key, out boneIndex)) { continue; // Ignore if not a named bone } if (AnimationTest(boneIndex)) { continue; } LinkedList <Clip.Keyframe> keyframes = new LinkedList <Clip.Keyframe>(); foreach (AnimationKeyframe keyframe in channel.Value) { Matrix transform = keyframe.Transform; Clip.Keyframe newKeyframe = new Clip.Keyframe(); newKeyframe.Time = keyframe.Time.TotalSeconds; newKeyframe.Transform = transform; keyframes.AddLast(newKeyframe); } LinearKeyframeReduction(keyframes); foreach (Clip.Keyframe keyframe in keyframes) { clip.Bones[boneIndex].Keyframes.Add(keyframe); } } } foreach (NodeContent child in input.Children) { AnimationDataImportRec(child); } }