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