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