Пример #1
0
        public Skeleton(Stream Data)
        {
            m_Reader = new FileReader(Data, true);

            m_Reader.ReadUInt32(); //Version
            Name = m_Reader.ReadPascalString();
            BoneCount = m_Reader.ReadUShort();

            for(int i = 0; i < BoneCount; i++)
            {
                Bones.Add(new Bone(m_Reader, i));
            }

            /** Construct tree **/
            foreach (Bone bone in Bones)
                bone.Children = Bones.Where(x => x.ParentName == bone.Name).ToArray();

            RootBone = Bones.FirstOrDefault(x => x.ParentName == "NULL");

            m_Reader.Close();
        }
Пример #2
0
        /// <summary>
        /// Transforms all vertices in a given mesh to their correct positions.
        /// </summary>
        /// <param name="Msh">The mesh to transform.</param>
        /// <param name="bone">The bone to transform to.</param>
        private void TransformVertices(Mesh Msh, Bone bone, MeshType MshType)
        {
            switch (MshType)
            {
                case MeshType.Head:
                    for (int i = 0; i < Msh.TotalVertexCount; i++)
                    {
                        //Transform the head vertices' position by the absolute transform
                        //for the headbone (which is always bone 17) to render the head in place.
                        Msh.TransformedVertices[i].Position = Vector3.Transform(Msh.RealVertices[i].Position,
                            Skel.Bones[16].AbsoluteMatrix);

                        Msh.TransformedVertices[i].TextureCoordinate = Msh.RealVertices[i].TextureCoordinate;

                        //Transform the head normals' position by the absolute transform
                        //for the headbone (which is always bone 17) to render the head in place.
                        Msh.TransformedVertices[i].Normal = Vector3.Transform(Msh.RealVertices[i].Normal,
                            Skel.Bones[16].AbsoluteMatrix);
                    }

                    return;

                case MeshType.Body:
                    BoneBinding boneBinding = Msh.BoneBindings.FirstOrDefault(x => Msh.Bones[(int)x.BoneIndex] == bone.Name);

                    if (boneBinding != null)
                    {
                        for (int i = 0; i < boneBinding.RealVertexCount; i++)
                        {
                            int vertexIndex = (int)boneBinding.FirstRealVertexIndex + i;
                            VertexPositionNormalTexture relativeVertex = Msh.RealVertices[vertexIndex];

                            Matrix translatedMatrix = Matrix.CreateTranslation(new Vector3(relativeVertex.Position.X, relativeVertex.Position.Y, relativeVertex.Position.Z)) * bone.AbsoluteMatrix;
                            Msh.TransformedVertices[vertexIndex].Position = Vector3.Transform(Vector3.Zero, translatedMatrix);

                            Msh.TransformedVertices[vertexIndex].TextureCoordinate = relativeVertex.TextureCoordinate;

                            //Normals...
                            translatedMatrix = Matrix.CreateTranslation(new Vector3(relativeVertex.Normal.X, relativeVertex.Normal.Y, relativeVertex.Normal.Z)) * bone.AbsoluteMatrix;
                            Msh.TransformedVertices[vertexIndex].Normal = Vector3.Transform(Vector3.Zero, translatedMatrix);
                        }
                    }

                    foreach (var child in bone.Children)
                        TransformVertices(Msh, child, MshType);

                    break;

                case MeshType.LHand:
                    for (int i = 0; i < Msh.TotalVertexCount; i++)
                    {
                        //Transform the left hand vertices' position by the absolute transform
                        //for the left handbone (which is always bone 10) to render the left hand in place.
                        Msh.TransformedVertices[i].Position = Vector3.Transform(Msh.RealVertices[i].Position,
                            Skel.Bones[9].AbsoluteMatrix);

                        //Transform the left hand normals' position by the absolute transform
                        //for the left handbone (which is always bone 10) to render the left hand in place.
                        Msh.TransformedVertices[i].Normal = Vector3.Transform(Msh.RealVertices[i].Normal,
                            Skel.Bones[9].AbsoluteMatrix);
                    }

                    return;

                case MeshType.RHand:
                    for (int i = 0; i < Msh.TotalVertexCount; i++)
                    {
                        //Transform the right hand vertices' position by the absolute transform
                        //for the right handbone (which is always bone 15) to render the right hand in place.
                        Msh.TransformedVertices[i].Position = Vector3.Transform(Msh.RealVertices[i].Position,
                            Skel.Bones[14].AbsoluteMatrix);

                        //Transform the right hand normals' position by the absolute transform
                        //for the right handbone (which is always bone 15) to render the right hand in place.
                        Msh.TransformedVertices[i].Normal = Vector3.Transform(Msh.RealVertices[i].Normal,
                            Skel.Bones[14].AbsoluteMatrix);
                    }

                    return;
            }
        }
Пример #3
0
        /// <summary>
        /// Computes the absolute positions for all bones in a Skeleton.
        /// </summary>
        /// <param name="bone">The first bone in the skeleton.</param>
        /// <param name="world">World matrix.</param>
        public void ComputeBonePositions(Bone bone, Matrix world)
        {
            var translateMatrix = Matrix.CreateTranslation(bone.Translation);
            var rotationMatrix = Helpers.FindQuaternionMatrix(bone.Rotation);

            var myWorld = (rotationMatrix * translateMatrix) * world;
            bone.AbsolutePosition = Vector3.Transform(Vector3.Zero, myWorld);
            bone.AbsoluteMatrix = myWorld;

            foreach (var child in bone.Children)
            {
                ComputeBonePositions(child, myWorld);
            }
        }