SetBindingPose() 공개 메소드

Sets the current position / orientation to be the 'binding pose' ie the layout in which bones were originally bound to a mesh.
public SetBindingPose ( ) : void
리턴 void
 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;
 }
        public void Import(Skeleton skeleton)
        {
            // store a local reference to the skeleton for modification
            this.skeleton = skeleton;

            XmlDocument document = new XmlDocument();
            document.Load(stream);
            foreach (XmlNode childNode in document.ChildNodes) {
                switch (childNode.Name) {
                    case "skeleton":
                        ReadSkeleton(childNode);
                        break;
                    default:
                        DebugMessage(childNode);
                        break;
                }
            }
            skeleton.SetBindingPose();
        }
예제 #3
0
		public void ImportSkeleton( Stream stream, Skeleton skeleton )
		{
			// store a local reference to the mesh for modification
			this.skeleton = skeleton;

			BinaryReader reader = new BinaryReader( stream, System.Text.Encoding.UTF8 );

			// start off by taking a look at the header
			ReadFileHeader( reader );

			SkeletonChunkID chunkID = 0;

			while ( !IsEOF( reader ) )
			{
				chunkID = ReadChunk( reader );

				switch ( chunkID )
				{
					case SkeletonChunkID.Bone:
						ReadBone( reader );
						break;

					case SkeletonChunkID.BoneParent:
						ReadBoneParent( reader );
						break;

					case SkeletonChunkID.Animation:
						ReadAnimation( reader );
						break;

					case SkeletonChunkID.AttachmentPoint:
						ReadAttachmentPoint( reader );
						break;

					default:
						LogManager.Instance.Write( "Can only parse bones, parents, and animations at the top level during skeleton loading." );
						LogManager.Instance.Write( "Unexpected chunk: " + chunkID.ToString() );
						break;
				} // switch
			} // while

			// assume bones are stored in binding pose
			skeleton.SetBindingPose();
		}
        /// <summary>
        ///   Build the bind pose for the skeleton based on the bind pose of the 
        ///   various Controllers (skin clusters).
        ///   This will also set up bones for the tag points.
        /// </summary>
        /// <param name="transform">the transform matrix to convert from the 
        ///                         system used by the modeling tool to the 
        ///                         system that will be used by multiverse</param>
        /// <param name="skeleton">Skeleton that will be built by this call</param>
        protected void BuildSkeletonAtBindPose( Matrix4 transform,
                                    Skeleton skeleton )
        {
            // Construct a list of bones that are of interest to us
            // This will be every bone that influences the skin, including the
            // parent bones (since they indirectly influence the skin).
            List<string> boneNames = new List<string>();
            foreach( Controller controller in Controllers.Values )
            {
                SkinController skinController = controller as SkinController;
                if( skinController == null )
                    continue;
                foreach( string key in skinController.InverseBindMatrices.Keys )
                {
                    string boneName = key;
                    // The entries in the skin controller may use sid.  If so,
                    // change these to use the bone name.
                    if( NodeSidMap.ContainsKey( boneName ) )
                        boneName = NodeSidMap[ boneName ];
                    if( boneNames.Contains( boneName ) )
                        continue;
                    boneNames.Add( boneName );
                    // Add all the parent bones
                    string currentBone = boneName;
                    while( BoneParents.ContainsKey( currentBone ) )
                    {
                        string parentBone = BoneParents[ currentBone ];
                        if( parentBone == null )
                            break;
                        if( !boneNames.Contains( parentBone ) )
                            boneNames.Add( parentBone );
                        currentBone = parentBone;
                    }
                }
            }
            Matrix4 unitConversionMatrix = Matrix4.Identity;
            unitConversionMatrix.Scale = new Vector3( m_UnitConversion, m_UnitConversion, m_UnitConversion );
            Matrix4 worldTransform = transform * unitConversionMatrix;

            // Build the invBindMatrices with the inverse bind matrices for
            // the bones
            Dictionary<string, Matrix4> invBindMatrices =
                new Dictionary<string, Matrix4>();
            Quaternion worldRotate;
            Vector3 worldScale, worldTranslate;
            Matrix4.DecomposeMatrix( ref worldTransform, out worldTranslate, out worldRotate, out worldScale );
            foreach( string boneName in boneNames )
            {
                Matrix4 bonePoseTransform = GetBonePoseTransform( boneName );

                Quaternion bonePoseRotate;
                Vector3 bonePoseTranslate, bonePoseScale;
                Matrix4.DecomposeMatrix( ref bonePoseTransform, out bonePoseTranslate, out bonePoseRotate, out bonePoseScale );

                Vector3 boneTranslate = worldTranslate + worldRotate * MathHelpers.ScaleVector( worldScale, bonePoseTranslate );
                Quaternion boneOrient = worldRotate * bonePoseRotate;

                Matrix4 boneTransform = Multiverse.MathLib.MathUtil.GetTransform( boneOrient, boneTranslate );
                invBindMatrices[ boneName ] = boneTransform.Inverse();
            }
            ProcessBones( invBindMatrices, skeleton, null );
            skeleton.SetBindingPose();
        }