Exemple #1
0
        public void TransformVertices(Bone bone)
        {
            var boneBinding = BoneBindings.FirstOrDefault(x => BoneNames[x.BoneIndex] == bone.Name);

            if (boneBinding != null)
            {
                for (var i = 0; i < boneBinding.RealVertexCount; i++)
                {
                    int vertexIndex = boneBinding.FirstRealVertex + i;
                    MeshVertexData transformedVertex = TransformedVertices[vertexIndex];
                    MeshVertexData relativeVertex = Vertex[vertexIndex];

                    var translatedMatrix = Matrix.CreateTranslation(new Vector3(relativeVertex.Vertex.Coord.X, relativeVertex.Vertex.Coord.Y, relativeVertex.Vertex.Coord.Z)) * bone.AbsoluteMatrix;
                    transformedVertex.Vertex.Coord = Vector3.Transform(Vector3.Zero, translatedMatrix);

                    //Normals...
                    translatedMatrix = Matrix.CreateTranslation(new Vector3(relativeVertex.Vertex.NormalCoord.X, relativeVertex.Vertex.NormalCoord.Y, relativeVertex.Vertex.NormalCoord.Z)) * bone.AbsoluteMatrix;
                    transformedVertex.Vertex.NormalCoord = Vector3.Transform(Vector3.Zero, translatedMatrix);
                }
            }

            foreach (var child in bone.Children)
            {
                TransformVertices(child);
            }
        }
Exemple #2
0
        public void Read(byte[] data)
        {
            using(var reader = new VBReader(new MemoryStream(data))){
                Version = reader.ReadInt32();
                Name = reader.ReadPascalString();
                BoneCount = reader.ReadInt16();

                System.Diagnostics.Debug.WriteLine("========== Skeleton ==========");
                System.Diagnostics.Debug.WriteLine("Version: " + Version);
                System.Diagnostics.Debug.WriteLine("Name: " + Name);
                System.Diagnostics.Debug.WriteLine("BoneCount: " + BoneCount);

                Bones = new Bone[BoneCount];
                for (var i = 0; i < BoneCount; i++){
                    System.Diagnostics.Debug.WriteLine("\n [Bone " + i + "]");
                    Bones[i] = ReadBone(reader);
                }


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

                RootBone = Bones.FirstOrDefault(x => x.ParentName == "NULL");
            }
        }
Exemple #3
0
        public void ComputeBonePositions(Bone bone, Matrix world)
        {
            var translateMatrix = Matrix.CreateTranslation(bone.Translation);
            var rotationMatrix = 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);
            }
        }
Exemple #4
0
        private Bone ReadBone(VBReader reader)
        {
            var bone = new Bone();
            bone.Unknown = reader.ReadInt32();
            bone.Name = reader.ReadPascalString();
            bone.ParentName = reader.ReadPascalString();

            System.Diagnostics.Debug.WriteLine("Name: " + bone.Name);
            System.Diagnostics.Debug.WriteLine("ParentName: " + bone.ParentName);

            bone.HasProps = reader.ReadByte();
            if (bone.HasProps != 0)
            {
                var propertyCount = reader.ReadInt32();
                var property = new PropertyListItem();
                
                for (var i = 0; i < propertyCount; i++){
                    var pairCount = reader.ReadInt32();
                    for (var x = 0; x < pairCount; x++){
                        property.KeyPairs.Add(new KeyValuePair<string, string>(
                            reader.ReadPascalString(),
                            reader.ReadPascalString()
                        ));
                    }
                }
                bone.Properties.Add(property);
            }

            /*if (bone.Name == "ROOT")
            {
                var y = true;
            }*/
            var xx = -reader.ReadFloat();
            bone.Translation = new Vector3(
                xx,
                reader.ReadFloat(),
                reader.ReadFloat()
            );

            bone.Rotation = new Vector4(
                reader.ReadFloat(),
                -reader.ReadFloat(),
                -reader.ReadFloat(),
                reader.ReadFloat()
            );

            bone.CanTranslate = reader.ReadInt32();
            bone.CanRotate = reader.ReadInt32();
            bone.CanBlend = reader.ReadInt32();

            bone.WiggleValue = reader.ReadFloat();
            bone.WigglePower = reader.ReadFloat();

            return bone;
        }
Exemple #5
0
        /// <summary>
        /// Transforms the vertices in a mesh to their location in 3D-space based on 
        /// the location of a bone.
        /// </summary>
        /// <param name="Bne">The bone to start with (should be a skeleton's ROOT bone).</param>
        /// <param name="Effect">The BasicEffect instance used for rendering.</param>
        public void TransformVertices2(ref Skeleton Skel, Bone Bne, ref Matrix World)
        {
            int BoneIndex = 0;
            Matrix WorldMat = World * Bne.AbsoluteTransform;

            for (BoneIndex = 0; BoneIndex < m_BndCount; BoneIndex++)
            {
                if (Bne.BoneName == m_BoneNames[m_BoneBindings[BoneIndex].BoneIndex])
                    break;
            }

            if (BoneIndex < m_BndCount)
            {
                for (int i = 0; i < m_BoneBindings[BoneIndex].VertexCount; i++)
                {
                    int VertexIndex = m_BoneBindings[BoneIndex].FirstVertex + i;
                    Vector3 RelativeVertex = new Vector3(m_VertexData[VertexIndex, 0],
                        m_VertexData[VertexIndex, 1], m_VertexData[VertexIndex, 2]);
                    Vector3 RelativeNormal = new Vector3(m_VertexData[VertexIndex, 3],
                        m_VertexData[VertexIndex, 4], m_VertexData[VertexIndex, 5]);

                    WorldMat *= Matrix.CreateTranslation(RelativeVertex);

                    m_TransformedVertices[VertexIndex].Coord.X = WorldMat.M41;
                    m_TransformedVertices[VertexIndex].Coord.Y = WorldMat.M42;
                    m_TransformedVertices[VertexIndex].Coord.Z = WorldMat.M43;

                    WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeVertex.X,
                        -RelativeVertex.Y, -RelativeVertex.Z));

                    WorldMat *= Matrix.CreateTranslation(RelativeNormal);

                    m_TransformedVertices[VertexIndex].Normal.X = WorldMat.M41;
                    m_TransformedVertices[VertexIndex].Normal.Y = WorldMat.M42;
                    m_TransformedVertices[VertexIndex].Normal.Z = WorldMat.M43;

                    WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeNormal.X,
                        -RelativeNormal.Y, -RelativeNormal.Z));
                }

                for (int i = 0; i < m_BoneBindings[BoneIndex].BlendedVertexCount; i++)
                {
                    int VertexIndex = m_RealVertexCount + m_BoneBindings[BoneIndex].FirstBlendedVert + i;
                    Vector3 RelativeVertex = new Vector3(m_VertexData[VertexIndex, 0],
                        m_VertexData[VertexIndex, 1], m_VertexData[VertexIndex, 2]);
                    Vector3 RelativeNormal = new Vector3(m_VertexData[VertexIndex, 3],
                        m_VertexData[VertexIndex, 4], m_VertexData[VertexIndex, 5]);

                    WorldMat *= Matrix.CreateTranslation(RelativeVertex);

                    m_TransformedVertices[VertexIndex].Coord.X = WorldMat.M41;
                    m_TransformedVertices[VertexIndex].Coord.Y = WorldMat.M42;
                    m_TransformedVertices[VertexIndex].Coord.Z = WorldMat.M43;

                    WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeVertex.X,
                        -RelativeVertex.Y, -RelativeVertex.Z));

                    WorldMat *= Matrix.CreateTranslation(RelativeNormal);

                    m_TransformedVertices[VertexIndex].Normal.X = WorldMat.M41;
                    m_TransformedVertices[VertexIndex].Normal.Y = WorldMat.M42;
                    m_TransformedVertices[VertexIndex].Normal.Z = WorldMat.M43;

                    WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeNormal.X,
                        -RelativeNormal.Y, -RelativeNormal.Z));
                }
            }

            if (Bne.NumChildren == 1)
                TransformVertices2(ref Skel, Skel.Bones[Bne.Children[0]], ref World);
            else if (Bne.NumChildren > 1)
            {
                for (int i = 0; i < Bne.NumChildren; i++)
                    TransformVertices2(ref Skel, Skel.Bones[Bne.Children[i]], ref World);
            }
        }
Exemple #6
0
        public Skeleton(GraphicsDevice Device, byte[] Filedata, Matrix WorldMatrix)
        {
            MemoryStream MemStream = new MemoryStream(Filedata);
            BinaryReader Reader = new BinaryReader(MemStream);
            m_WorldMatrix = WorldMatrix;

            m_Version = Endian.SwapUInt32(Reader.ReadUInt32());
            m_Name = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte()));

            m_BoneCount = Endian.SwapUInt16(Reader.ReadUInt16());
            m_Bones = new Bone[m_BoneCount];

            for (int i = 0; i < m_BoneCount; i++)
            {
                Endian.SwapUInt32(Reader.ReadUInt32()); //1 in hexadecimal... typical useless Maxis value...

                Bone Bne = new Bone(this);

                Bne.ID = i;

                Bne.BoneName = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte()));
                Log.LogThis("BoneName: " + Bne.BoneName, eloglevel.info);
                Bne.ParentName = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte()));

                Bne.HasPropertyList = Reader.ReadByte();

                if (Bne.HasPropertyList == 1)
                    Bne.PList = ReadPropList(Reader);

                //Little Endian
                Bne.Translations = new float[3];
                Bne.Translations[0] = Reader.ReadSingle();
                Bne.Translations[1] = Reader.ReadSingle();
                Bne.Translations[2] = Reader.ReadSingle();

                Bne.Versor = new float[4];
                //These values are given in degrees...
                Bne.Versor[0] = MathHelper.ToRadians(Reader.ReadSingle());
                Bne.Versor[1] = MathHelper.ToRadians(Reader.ReadSingle());
                Bne.Versor[2] = MathHelper.ToRadians(Reader.ReadSingle());
                Bne.Versor[3] = MathHelper.ToRadians(Reader.ReadSingle());

                Bne.CanTranslate = Endian.SwapInt32(Reader.ReadInt32());
                Bne.CanRotate = Endian.SwapInt32(Reader.ReadInt32());
                Bne.CanUseBlending = Endian.SwapInt32(Reader.ReadInt32());
                //Little endian.
                Bne.CanWiggle = Reader.ReadSingle();
                Bne.WiggleAmount = Reader.ReadSingle();

                Bne.BoneEffect = new BasicEffect(Device, null);

                Bne.Children = new int[m_BoneCount - i - 1];

                int Parent = FindBone(Bne.ParentName, i);
                if (Parent != -1)
                {
                    m_Bones[Parent].Children[m_Bones[Parent].NumChildren] = Bne.ID;
                    m_Bones[Parent].NumChildren += 1;
                    Bne.Parent = m_Bones[Parent];
                    Bne.ComputeAbsoluteTransform(m_WorldMatrix);
                }

                m_Bones[i] = Bne;

                /*Log.LogThis("Bone: " + Bne.BoneName, eloglevel.info);
                if (Parent != -1)
                {
                    Log.LogThis("Parent: " + Bne.Parent.BoneName, eloglevel.info);

                    for (int j = 0; j < Bne.Parent.NumChildren; j++)
                        Log.LogThis("Child: " + Bne.Parent.Children[j].BoneName, eloglevel.info);
                }
                else
                    Log.LogThis("Parent: NULL", eloglevel.info);*/
            }

            Reader.Close();
        }
Exemple #7
0
        public Skeleton(GraphicsDevice Device, string Filepath, ref Matrix WorldMatrix)
        {
            BinaryReader Reader = new BinaryReader(File.Open(Filepath, FileMode.Open));
            m_WorldMatrix = WorldMatrix;

            m_Version = Endian.SwapUInt32(Reader.ReadUInt32());
            m_Name = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte()));

            m_BoneCount = Endian.SwapUInt16(Reader.ReadUInt16());
            m_Bones = new Bone[m_BoneCount];

            for (int i = 0; i < m_BoneCount; i++)
            {
                Endian.SwapUInt32(Reader.ReadUInt32()); //1 in hexadecimal... typical useless Maxis value...

                Bone Bne = new Bone(this);

                Bne.ID = i;

                Bne.BoneName = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte()));
                Bne.ParentName = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte()));

                Bne.HasPropertyList = Reader.ReadByte();

                if (Bne.HasPropertyList == 1)
                    Bne.PList = ReadPropList(Reader);

                //Little Endian
                Bne.Translations = new float[3];
                Bne.Translations[0] = Reader.ReadSingle();
                Bne.Translations[1] = Reader.ReadSingle();
                Bne.Translations[2] = Reader.ReadSingle();

                Bne.Versor = new float[4];
                //These values are given in degrees...
                Bne.Versor[0] = MathHelper.ToRadians(Reader.ReadSingle());
                Bne.Versor[1] = MathHelper.ToRadians(Reader.ReadSingle());
                Bne.Versor[2] = MathHelper.ToRadians(Reader.ReadSingle());
                Bne.Versor[3] = MathHelper.ToRadians(Reader.ReadSingle());

                Bne.CanTranslate = Endian.SwapInt32(Reader.ReadInt32());
                Bne.CanRotate = Endian.SwapInt32(Reader.ReadInt32());
                Bne.CanUseBlending = Endian.SwapInt32(Reader.ReadInt32());
                //Little endian.
                Bne.CanWiggle = Reader.ReadSingle();
                Bne.WiggleAmount = Reader.ReadSingle();

                Bne.BoneEffect = new BasicEffect(Device, null);

                Bne.Children = new int[m_BoneCount - i - 1];

                int Parent = FindBone(Bne.ParentName, i);
                if (Parent != -1)
                {
                    m_Bones[Parent].Children[m_Bones[Parent].NumChildren] = Bne.ID;
                    m_Bones[Parent].NumChildren += 1;
                    Bne.Parent = m_Bones[Parent];
                    Bne.ComputeAbsoluteTransform(m_WorldMatrix);
                }

                m_Bones[i] = Bne;
            }

            Reader.Close();
        }
Exemple #8
0
        /// <summary>
        /// Populates a list of vertices (points) that are rendered at the location
        /// of each bone in the skeleton.
        /// </summary>
        private void PopulateSkeletonPoints(ref VertexPositionNormalTexture[] SkelPoints, ref Bone Bne)
        {
            /*if (m_Skeleton != null)
            {
                m_SkelPoints = new VertexPositionNormalTexture[m_Skeleton.Bones.Length];

                for (int i = 0; i < m_Skeleton.Bones.Length; i++)
                {
                    m_WorldMatrixStack.Push(m_WorldMatrixStack.Peek());

                    if (m_SkelPoints[i] == null)
                    {
                        m_SkelPoints[i] = new VertexPositionNormalTexture(m_Skeleton.Bones[i].GlobalTranslation,
                            Vector3.Forward, Vector2.One);

                        m_SkelPoints[i].Position = Vector3.Transform(m_Skeleton.Bones[i].GlobalTranslation,
                            m_Skeleton.Bones[i].AbsoluteTransform);
                    }

                    if (m_Skeleton.Bones[i].NumChildren == 1)
                    {
                        int ChildIndex = m_Skeleton.Bones[i].Children[0].ID;

                        m_SkelPoints[ChildIndex] = new VertexPositionNormalTexture(m_Skeleton.Bones[i].GlobalTranslation 
                            * m_Skeleton.Bones[ChildIndex].GlobalTranslation, Vector3.Forward, Vector2.One);

                        m_SkelPoints[ChildIndex].Position = Vector3.Transform(m_Skeleton.Bones[ChildIndex].GlobalTranslation,
                            m_Skeleton.Bones[ChildIndex].AbsoluteTransform);
                    }
                    else if (m_Skeleton.Bones[i].NumChildren > 1)
                    {
                        for (int j = 0; j < m_Skeleton.Bones[i].NumChildren; j++)
                        {
                            int ChildIndex = m_Skeleton.Bones[i].Children[j].ID;
                            m_SkelPoints[ChildIndex] = new VertexPositionNormalTexture(m_Skeleton.Bones[i].GlobalTranslation
                                * m_Skeleton.Bones[ChildIndex].GlobalTranslation, Vector3.Forward, Vector2.One);

                            m_SkelPoints[ChildIndex].Position = Vector3.Transform(m_Skeleton.Bones[ChildIndex].GlobalTranslation,
                                m_Skeleton.Bones[ChildIndex].AbsoluteTransform);
                        }
                    }

                    mWorldMat = m_WorldMatrixStack.Pop();
                }
            }*/

            mProjectionMat *= Matrix.CreateFromQuaternion(Bne.GlobalRotation);
            mProjectionMat *= Matrix.CreateTranslation(Bne.GlobalTranslation);

            VertexPositionNormalTexture SkelPoint = new VertexPositionNormalTexture(Bne.GlobalTranslation,
                Vector3.Forward, Vector2.One);
            SkelPoint.Position = Vector3.Transform(Bne.GlobalTranslation,
                mProjectionMat);
            /*SkelPoint.Position *= Vector3.Transform(Bne.GlobalTranslation, 
                Matrix.CreateFromQuaternion(Bne.GlobalRotation));*/

            SkelPoints[Bne.ID] = SkelPoint;

            if (Bne.NumChildren == 1)
            {
                PopulateSkeletonPoints(ref SkelPoints, ref m_Skeleton.Bones[Bne.Children[0]]);
            }
            else if (Bne.NumChildren > 1)
            {
                for (int i = 0; i < Bne.NumChildren; i++)
                {
                    m_WorldMatrixStack.Push(mProjectionMat);
                    PopulateSkeletonPoints(ref SkelPoints, ref m_Skeleton.Bones[Bne.Children[i]]);
                    m_WorldMatrixStack.Pop();
                    mProjectionMat = m_WorldMatrixStack.Peek();
                }
            }
        }