示例#1
0
        /// <summary>
        /// Try to apply skeleton to model.
        /// </summary>
        public void Apply(SkinnedMesh skinnedMesh)
        {
            // Create the bones
            for (int i = 0; i < meshSkeleton.nbBones; i++)
            {
                string boneName = meshSkeleton.names[i];
                if (skinnedMesh.GetJointIndex(boneName) == -1)
                {
                    var joint = skinnedMesh.AddJoint();
                    joint.Name = boneName;
                }
            }

            // Set the hierarchy
            for (int i = 0; i < meshSkeleton.nbBones; i++)
            {
                short parent = meshSkeleton.parentIdx[i];
                if (parent != -1) // root
                {
                    var parentJoint = RenderSkeleton.GetJointByName(skinnedMesh, meshSkeleton.names[parent]);
                    if (parentJoint != null)
                    {
                        parentJoint.AddChildren(skinnedMesh.GetAllJoints()[i]);
                    }
                }
            }

            // Set the transformations
            for (int i = 0; i < meshSkeleton.nbBones; i++)
            {
                string boneName = meshSkeleton.names[i];

                var joint = RenderSkeleton.GetJointByName(skinnedMesh, boneName);
                if (joint == null)
                {
                    continue;
                }

                joint.LocalMatrix = meshSkeleton.matrix[i];

                joint.Animatedposition = meshSkeleton.positions[i];
                joint.Animatedrotation = meshSkeleton.rotations[i];
                joint.Animatedscale    = meshSkeleton.scales[i];
            }

            // Compute the global matrix
            List <SJoint> roots = RenderSkeleton.GetRootJoints(skinnedMesh);

            for (int i = 0; i < roots.Count; ++i)
            {
                RenderSkeleton.ComputeGlobal(skinnedMesh, roots[i]);
            }

            // The matrix of the bones
            for (int i = 0; i < CData.boneData.nbBones; i++)
            {
                var jointIdx = skinnedMesh.GetJointIndex(CData.boneData.jointNames[i]);
                if (jointIdx == -1)
                {
                    continue;                 //if the mesh bone is not in the animation rig (ie. dynamic)
                }
                SJoint joint = skinnedMesh.GetAllJoints()[jointIdx];

                Matrix matrix = CData.boneData.boneMatrices[i];

                Vector3Df position = matrix.Translation;
                Matrix    invRot   = matrix.GetInverse();
                //invRot.rotateVect(position);

                Vector3Df rotation = invRot.GetRotationDegrees(invRot.Scale);
                //rotation = core::vector3df(0, 0, 0);
                position = -position;
                Vector3Df scale = matrix.Scale;

                if (joint != null)
                {
                    // Build GlobalMatrix:
                    Matrix positionMatrix = new Matrix();
                    positionMatrix.Translation = position;
                    Matrix scaleMatrix = new Matrix();
                    scaleMatrix.Scale = scale;
                    Matrix rotationMatrix = new Matrix();
                    rotationMatrix.SetRotationRadians(rotation * CommonData.PI_OVER_180);

                    //joint.GlobalMatrix = scaleMatrix * rotationMatrix * positionMatrix;
                    //joint.LocalMatrix = joint.GlobalMatrix;

                    //joint.Animatedposition = joint.LocalMatrix.Translation;
                    //joint.Animatedrotation = new Quaternion(joint.LocalMatrix.GetRotationDegrees(joint.LocalMatrix.Scale)).MakeInverse();
                    //joint.Animatedscale = joint.LocalMatrix.Scale;

                    var bone = new W3_DataCache.BoneEntry();
                    bone.name         = joint.Name;
                    bone.offsetMatrix = matrix;
                    CData.w3_DataCache.bones.Add(bone);
                }
            }

            // Apply skin
            for (int i = 0; i < CData.w3_DataCache.vertices.Count; i++)
            {
                var entry = CData.w3_DataCache.vertices[i];

                // Check if it's a valid entry
                if (entry.boneId >= CData.w3_DataCache.bones.Count ||
                    entry.meshBufferId >= skinnedMesh.MeshBufferCount ||
                    entry.vertexId >= skinnedMesh.GetMeshBuffer(entry.meshBufferId).VertexCount)
                {
                    // Console.WriteLine("Fail to skin : the vertex entry is not valid.");
                    continue;
                }


                int jointID = skinnedMesh.GetJointIndex(CData.w3_DataCache.bones[(int)entry.boneId].name);
                if (jointID == -1)
                {
                    // Console.WriteLine("Fail to skin : joint not found." );
                    continue;
                }

                SJoint  joint  = skinnedMesh.GetAllJoints()[jointID];
                SWeight weight = skinnedMesh.AddWeight(joint);
                weight.BufferId = entry.meshBufferId;
                weight.VertexId = entry.vertexId;
                weight.Strength = entry.strength;
            }

            // Add weights

            /*for (int i = 0; i < w3_DataCache.vertices.Count; i++)
             * {
             *  uint boneId = w3_DataCache.vertices[i].boneId;
             *  ushort bufferId = w3_DataCache.vertices[i].meshBufferId;
             *  uint vertexId = w3_DataCache.vertices[i].vertexId;
             *  float fweight = w3_DataCache.vertices[i].strength;
             *
             *  if (boneId >= skinnedMesh.GetAllJoints().Count) // If bone doesnt exist
             *      continue;
             *
             *  SJoint joint = skinnedMesh.GetAllJoints()[(int)boneId];
             *
             *  SWeight w = skinnedMesh.AddWeight(joint);
             *  w.BufferId = bufferId;
             *  w.Strength = fweight;
             *  w.VertexId = vertexId;
             * }*/
        }