public static void SplitClip(AnimationTrack track, AnimationClip clip, int frame)
        {
            if (frame <= clip.BeginFrame || frame > clip.EndFrame)
            {
                throw new InvalidOperationException();
            }
            var index   = track.Clips.IndexOf(clip);
            var newClip = clip.Clone();

            newClip.BeginFrame = frame;
            newClip.EndFrame   = clip.EndFrame;
            newClip.InFrame    = frame - clip.BeginFrame + clip.InFrame;
            Core.Operations.SetProperty.Perform(clip, nameof(AnimationClip.EndFrame), frame);
            Core.Operations.InsertIntoList <AnimationClipList, AnimationClip> .Perform(track.Clips, index + 1, newClip);
        }
Exemple #2
0
        public AnimationClip GenerateMountAnimation(AnimationClip mountAnimation, AnimationClip riderAnimation)
        {
            Vector3 translationOffset    = new Vector3((float)_animationSettings.Translation.X.Value, (float)_animationSettings.Translation.Y.Value, (float)_animationSettings.Translation.Z.Value);
            Vector3 rotationOffset       = new Vector3((float)_animationSettings.Rotation.X.Value, (float)_animationSettings.Rotation.Y.Value, (float)_animationSettings.Rotation.Z.Value);
            var     rotationOffsetMatrix = Quaternion.CreateFromYawPitchRoll(MathHelper.ToRadians(rotationOffset.X), MathHelper.ToRadians(rotationOffset.Y), MathHelper.ToRadians(rotationOffset.Z));

            var newRiderAnim = riderAnimation.Clone();

            newRiderAnim.MergeStaticAndDynamicFrames();

            View3D.Animation.AnimationEditor.LoopAnimation(newRiderAnim, (int)_animationSettings.LoopCounter.Value);

            // Resample
            if (_animationSettings.FitAnimation)
            {
                newRiderAnim = View3D.Animation.AnimationEditor.ReSample(_riderSkeleton, newRiderAnim, mountAnimation.DynamicFrames.Count, mountAnimation.PlayTimeInSec);
            }

            newRiderAnim.StaticFrame = null;

            var maxFrameCount = Math.Min(mountAnimation.DynamicFrames.Count, newRiderAnim.DynamicFrames.Count);

            for (int i = 0; i < maxFrameCount; i++)
            {
                var mountFrame = AnimationSampler.Sample(i, 0, _mountSkeleton, new List <AnimationClip> {
                    mountAnimation
                });
                var mountBoneWorldMatrix = _mountVertexPositionResolver.GetVertexTransformWorld(mountFrame, _mountVertexId);
                mountBoneWorldMatrix.Decompose(out var _, out var mountVertexRot, out var mountVertexPos);

                // Make sure the rider moves along in the world with the same speed as the mount
                var mountMovement = mountFrame.BoneTransforms[0].Translation;
                newRiderAnim.DynamicFrames[i].Position[0] = mountMovement;// mountAnimation.DynamicFrames[i].Position[0];
                newRiderAnim.DynamicFrames[i].Rotation[0] = Quaternion.Identity;

                var origianlRotation = Quaternion.Identity;
                if (_animationSettings.KeepRiderRotation)
                {
                    var riderFrame = AnimationSampler.Sample(i, 0, _riderSkeleton, new List <AnimationClip> {
                        newRiderAnim
                    });
                    var riderBoneWorldmatrix = riderFrame.GetSkeletonAnimatedWorld(_riderSkeleton, _riderBoneIndex);
                    riderBoneWorldmatrix.Decompose(out var _, out origianlRotation, out var _);
                }

                var originalPosition = newRiderAnim.DynamicFrames[i].Position[_riderBoneIndex];
                var originalRotation = newRiderAnim.DynamicFrames[i].Rotation[_riderBoneIndex];

                var newRiderPosition = mountVertexPos + translationOffset - mountFrame.BoneTransforms[0].Translation;
                var newRiderRotation = Quaternion.Multiply(Quaternion.Multiply(mountVertexRot, origianlRotation), rotationOffsetMatrix);

                var riderPositionDiff = newRiderPosition - originalPosition;
                var riderRotationDiff = newRiderRotation * Quaternion.Inverse(originalRotation);

                newRiderAnim.DynamicFrames[i].Position[_riderBoneIndex] = newRiderPosition;
                newRiderAnim.DynamicFrames[i].Rotation[_riderBoneIndex] = newRiderRotation;

                // Find all the bones at the same level (normally attachmentpoints) and move them as well
                var parentBoneIndex = _riderSkeleton.GetParentBone(_riderBoneIndex);
                if (parentBoneIndex != -1)
                {
                    var childNodes = _riderSkeleton.GetChildBones(parentBoneIndex);

                    for (int boneId = 0; boneId < childNodes.Count; boneId++)
                    {
                        var id = childNodes[boneId];
                        if (id == _riderBoneIndex)
                        {
                            continue;
                        }
                        newRiderAnim.DynamicFrames[i].Position[id] += riderPositionDiff;
                        newRiderAnim.DynamicFrames[i].Rotation[id]  = riderRotationDiff * newRiderAnim.DynamicFrames[i].Rotation[id];
                    }
                }
            }

            return(newRiderAnim);
        }