protected void TransformSkeleton(Matrix4 unscaledTransform, float scale) { Matrix4 invExportTransform = unscaledTransform.Inverse(); Dictionary<string, Matrix4> fullInverseBoneTransforms = new Dictionary<string, Matrix4>(); Skeleton newSkeleton = new Skeleton(skeleton.Name); // Construct new versions of the bones, and build // the inverse bind matrix that will be needed. for (ushort i = 0; i < skeleton.BoneCount; ++i) { Bone bone = skeleton.GetBone(i); Bone newBone = newSkeleton.CreateBone(bone.Name, bone.Handle); fullInverseBoneTransforms[bone.Name] = bone.BindDerivedInverseTransform * invExportTransform; } // Build the parenting relationship for the new skeleton for (ushort i = 0; i < skeleton.BoneCount; ++i) { Bone bone = skeleton.GetBone(i); Bone newBone = newSkeleton.GetBone(i); Bone parentBone = (Bone)bone.Parent; if (parentBone != null) { Bone newParentBone = newSkeleton.GetBone(parentBone.Handle); newParentBone.AddChild(newBone); } } // Set the orientation and position for the various bones for (ushort i = 0; i < newSkeleton.BoneCount; ++i) { Bone bone = skeleton.GetBone(i); string boneName = bone.Name; string parentName = (bone.Parent == null) ? null : bone.Parent.Name; Matrix4 transform = GetLocalBindMatrix(fullInverseBoneTransforms, boneName, parentName, true); Quaternion orientation = GetRotation(transform); Bone newBone = newSkeleton.GetBone(i); newBone.Orientation = orientation; // newBone.Scale = transform.Scale; newBone.Position = scale * transform.Translation; } newSkeleton.SetBindingPose(); for (int i = 0; i < skeleton.AnimationCount; ++i) { Animation anim = skeleton.GetAnimation(i); Animation newAnim = newSkeleton.CreateAnimation(anim.Name, anim.Length); TransformAnimation(unscaledTransform, scale, newAnim, anim, newSkeleton); } skeleton = newSkeleton; }
protected void TransformTrack(Matrix4 exportTransform, NodeAnimationTrack newTrack, NodeAnimationTrack track, Bone bone) { Matrix4 invExportTransform = exportTransform.Inverse(); Bone oldNode = (Bone)track.TargetNode; Bone newNode = (Bone)newTrack.TargetNode; for (int i = 0; i < track.KeyFrames.Count; ++i) { TransformKeyFrame keyFrame = track.GetTransformKeyFrame(i); TransformKeyFrame newKeyFrame = newTrack.CreateNodeKeyFrame(keyFrame.Time); Quaternion oldOrientation = oldNode.Orientation * keyFrame.Rotation; Vector3 oldTranslation = oldNode.Position + keyFrame.Translate; Matrix4 oldTransform = Multiverse.MathLib.MathUtil.GetTransform(oldOrientation, oldTranslation); Matrix4 newTransform = exportTransform * oldTransform * invExportTransform; Quaternion newOrientation = GetRotation(newTransform); Vector3 newTranslation = newTransform.Translation; newKeyFrame.Rotation = newNode.Orientation.Inverse() * newOrientation; newKeyFrame.Translate = newTranslation - newNode.Position; //if (oldNode.Name == "Lower_Torso_BIND_jjj") { // log.DebugFormat("New translation: {0}; New Position: {1}", newTranslation, newNode.Position); //} } }