public void Read(byte[] data)
        {
            using(var reader = new VBFile(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");
            }
        }
        private void TransformVertices(Mesh mesh, Bone bone)
        {
            //var x = mesh.BoneBindings;
            var boneBinding = mesh.BoneBindings.FirstOrDefault(x => mesh.BoneNames[x.BoneIndex] == bone.Name);

            if (boneBinding != null){
                for (var i = 0; i < boneBinding.RealVertexCount; i++)
                {
                    var vertexIndex = boneBinding.FirstRealVertex + i;
                    var transformedVertex = mesh.TransformedVertex[vertexIndex];
                    var relativeVertex = mesh.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);

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

                }

                for (var i = 0; i < boneBinding.BlendVertexCount; i++)
                {
                    var vertexIndex = boneBinding.FirstBlendVertex + i;
                    var transformedVertex = mesh.TransformedVertex[vertexIndex];
                    var relativeVertex = mesh.Vertex[vertexIndex];

                }

                //for (var i = 0; i < boneBinding.BlendVertexCount; i++)
                //{
                //    var vertexIndex = boneBinding.FirstBlendVertex + i;
                //    var transformedVertex = mesh.TransformedVertex[vertexIndex];
                //    var relativeVertex = mesh.Vertex[vertexIndex];

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

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

            foreach (var child in bone.Children){
                TransformVertices(mesh, child);
            }
        }
        private 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);
            }
        }
        private Bone ReadBone(VBFile 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;
        }