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