Esempio n. 1
0
        private static Pmo MeshGroup2PMO(MeshGroup meshGroup)
        {
            Pmo pmo = new Pmo();

            List <MeshDescriptor> Descriptors = meshGroup.MeshDescriptors;

            // Max 65K vertices.
            uint descriptorVertexCount = 0;
            uint indicesVertexCount    = 0;

            foreach (MeshDescriptor d in Descriptors)
            {
                descriptorVertexCount += (uint)d.Vertices.Length;
                indicesVertexCount    += (uint)d.Indices.Length;
            }

            // Mesh data.
            for (int i = 0; i < Descriptors.Count; i++)
            {
                MeshDescriptor desc        = Descriptors[i];
                int[]          vertIndices = desc.Indices;
                Pmo.MeshChunks chunk       = new Pmo.MeshChunks();

                // Obtain info for PMO Vertex Flag.
                bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                chunk.SectionInfo             = new Pmo.MeshSection();
                chunk.SectionInfo.Attribute   = 0;
                chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                // Set extra flags.
                if (UsesUniformColor)
                {
                    var UniformColor = (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].A * 256f));
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].B * 256f)) << 8;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].G * 256f)) << 16;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].R * 256f)) << 24;
                    chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                    chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                    chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                }
                else
                {
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                }
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                chunk.SectionInfo.VertexSize += 0;                                                                                                                     // Weights.
                chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8  : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }
                chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4;                                                            // VertexColor
                chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices


                for (int v = 0; v < desc.Indices.Length; v++)
                {
                    int index = vertIndices[v];

                    Vector4 Color = new Vector4();
                    Color.X = desc.Vertices[index].R * 2;
                    Color.Y = desc.Vertices[index].G * 2;
                    Color.Z = desc.Vertices[index].B * 2;
                    Color.W = desc.Vertices[index].A * 2;
                    chunk.colors.Add(Color);

                    Vector3 vec;
                    vec.X = desc.Vertices[index].X / 10000.0f;
                    vec.Y = desc.Vertices[index].Y / 10000.0f;
                    vec.Z = desc.Vertices[index].Z / 10000.0f;
                    chunk.vertices.Add(vec);

                    Vector2 Coords;
                    Coords.X = desc.Vertices[index].Tu;
                    Coords.Y = desc.Vertices[index].Tv;
                    chunk.textureCoordinates.Add(Coords);
                }

                pmo.Meshes.Add(chunk);
            }

            // Header.
            pmo.header                = new Pmo.Header();
            pmo.header.MagicCode      = 0x4F4D50;
            pmo.header.TextureCount   = (ushort)TextureData.Count; // TODO.
            pmo.header.Unk0A          = 0x80;
            pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
            pmo.header.VertexCount    = (ushort)indicesVertexCount;
            pmo.header.TriangleCount  = (ushort)indicesVertexCount;
            pmo.header.TriangleCount /= 3;
            pmo.header.ModelScale     = 1.0f;
            pmo.header.BoundingBox    = new float[32];

            // Texture block.
            if (TextureData.Count > 0)
            {
                pmo.textureInfo = new Pmo.TextureInfo[TextureData.Count];

                for (int t = 0; t < TextureData.Count; t++)
                {
                    Tm2 tm = TextureData[t];
                    pmo.textureInfo[t]             = new Pmo.TextureInfo();
                    pmo.textureInfo[t].TextureName = TexList[t];
                    pmo.textureInfo[t].Unknown     = new UInt32[4];
                    pmo.texturesData.Add(TextureData[t]);
                }
            }

            return(pmo);
        }
Esempio n. 2
0
        private static Assimp.Scene GetPMOScene(Pmo pmo)
        {
            Assimp.Scene scene = new Assimp.Scene();
            scene.RootNode = new Assimp.Node("root");

            // Add materials.
            List <Material> matList = new List <Material>();

            for (int t = 0; t < pmo.header.TextureCount; t++)
            {
                Material mat = new Material();
                mat.Clear();
                mat.Name = pmo.textureInfo[t].TextureName;
                scene.Materials.Add(mat);
            }

            // Add skeleton.
            List <Node> Skeleton = new List <Node>();

            for (int b = 0; b < pmo.skeletonHeader.BoneCount; b++)
            {
                Pmo.BoneData bn = pmo.boneList[b];

                Assimp.Matrix4x4 mtx = new Assimp.Matrix4x4();
                mtx.A1 = bn.Transform.M11;
                mtx.A2 = bn.Transform.M12;
                mtx.A3 = bn.Transform.M13;
                mtx.A4 = bn.Transform.M14;
                mtx.B1 = bn.Transform.M21;
                mtx.B2 = bn.Transform.M22;
                mtx.B3 = bn.Transform.M23;
                mtx.B4 = bn.Transform.M24;
                mtx.C1 = bn.Transform.M31;
                mtx.C2 = bn.Transform.M32;
                mtx.C3 = bn.Transform.M33;
                mtx.C4 = bn.Transform.M34;
                mtx.D1 = bn.Transform.M41;
                mtx.D2 = bn.Transform.M42;
                mtx.D3 = bn.Transform.M43;
                mtx.D4 = bn.Transform.M44;

                Assimp.Matrix4x4 nd_mtx = mtx;
                nd_mtx.Transpose();
                if (bn.ParentBoneIndex == 0xFFFF)
                {
                    Node curNode = new Node(bn.JointName);
                    curNode.Transform = nd_mtx;
                    scene.RootNode.Children.Add(curNode);
                    Skeleton.Add(curNode);
                }
                else
                {
                    Node curNode = new Node(bn.JointName, Skeleton[bn.ParentBoneIndex]);

                    nd_mtx.A4 *= 100.0f;
                    nd_mtx.B4 *= 100.0f;
                    nd_mtx.C4 *= 100.0f;

                    curNode.Transform = nd_mtx;
                    Skeleton.Add(curNode);
                    scene.RootNode.FindNode(Skeleton[bn.ParentBoneIndex].Name).Children.Add(curNode);
                }
            }

            // Add meshes.
            for (int i = 0; i < pmo.Meshes.Count; i++)
            {
                Assimp.Mesh    mesh  = new Assimp.Mesh($"Mesh{i}", Assimp.PrimitiveType.Triangle);
                Pmo.MeshChunks chunk = pmo.Meshes[i];

                // Add vertices, vertex color and normals.
                for (int j = 0; j < chunk.vertices.Count; j++)
                {
                    mesh.Vertices.Add(new Assimp.Vector3D(
                                          chunk.vertices[j].X * pmo.header.ModelScale * 100.0f,
                                          chunk.vertices[j].Y * pmo.header.ModelScale * 100.0f,
                                          chunk.vertices[j].Z * pmo.header.ModelScale * 100.0f));

                    mesh.VertexColorChannels[0].Add(new Color4D(1.0f, 1.0f, 1.0f, 1.0f));
                    mesh.Normals.Add(new Vector3D());
                }
                mesh.SetIndices(chunk.Indices.ToArray(), 3);
                mesh.MaterialIndex = chunk.SectionInfo.TextureID;
                scene.Meshes.Add(mesh);

                for (int v = 0; v < chunk.vertices.Count; v++)
                {
                    // Build bone influences.
                    for (int z = 0; z < chunk.SectionInfo_opt1.SectionBoneIndices.Length; z++)
                    {
                        if (chunk.SectionInfo_opt1.SectionBoneIndices[z] != 0xFF)
                        {
                            Pmo.BoneData currentBone = new Pmo.BoneData();

                            int currentIndex = chunk.SectionInfo_opt1.SectionBoneIndices[z];
                            currentBone = pmo.boneList[currentIndex];

                            string           boneName = currentBone.JointName;
                            Assimp.Matrix4x4 mtx      = new Assimp.Matrix4x4();
                            mtx.A1 = currentBone.Transform.M11;
                            mtx.A2 = currentBone.Transform.M12;
                            mtx.A3 = currentBone.Transform.M13;
                            mtx.A4 = currentBone.Transform.M14;
                            mtx.B1 = currentBone.Transform.M21;
                            mtx.B2 = currentBone.Transform.M22;
                            mtx.B3 = currentBone.Transform.M23;
                            mtx.B4 = currentBone.Transform.M24;
                            mtx.C1 = currentBone.Transform.M31;
                            mtx.C2 = currentBone.Transform.M32;
                            mtx.C3 = currentBone.Transform.M33;
                            mtx.C4 = currentBone.Transform.M34;
                            mtx.D1 = currentBone.Transform.M41;
                            mtx.D2 = currentBone.Transform.M42;
                            mtx.D3 = currentBone.Transform.M43;
                            mtx.D4 = currentBone.Transform.M44;
                            Matrix3x3 mtx3 = new Matrix3x3(mtx);

                            mtx.Transpose();

                            mtx.A4 *= 100.0f;
                            mtx.B4 *= 100.0f;
                            mtx.C4 *= 100.0f;


                            mtx3.Transpose();

                            List <VertexWeight> weight = new List <VertexWeight>();

                            VertexWeight vW = new VertexWeight();
                            vW.VertexID = v;

                            float currentWeight = chunk.jointWeights[v].weights[z];

                            switch (chunk.jointWeights[v].coordFormart)
                            {
                            case Pmo.CoordinateFormat.NO_VERTEX:
                                break;

                            case Pmo.CoordinateFormat.NORMALIZED_8_BITS:
                                currentWeight *= 127.0f;
                                currentWeight /= 128.0f;
                                break;

                            case Pmo.CoordinateFormat.NORMALIZED_16_BITS:
                                currentWeight *= 32767.0f;
                                currentWeight /= 32768.0f;
                                break;

                            case Pmo.CoordinateFormat.FLOAT_32_BITS:
                                break;
                            }

                            vW.Weight = currentWeight;
                            weight.Add(vW);

                            Bone tempBone = scene.Meshes[i].Bones.Find(x => x.Name == boneName);
                            int  boneInd  = scene.Meshes[i].Bones.FindIndex(0, x => x.Name == boneName);

                            if (tempBone == null)
                            {
                                Bone bone = new Bone(boneName, mtx3, weight.ToArray());
                                scene.Meshes[i].Bones.Add(bone);
                            }
                            else
                            {
                                scene.Meshes[i].Bones[boneInd].VertexWeights.Add(vW);
                            }
                        }
                    }
                }
            }

            scene.RootNode.MeshIndices.AddRange(Enumerable.Range(0, scene.MeshCount));

            return(scene);
        }
Esempio n. 3
0
        private static Pmp MeshGroupList2PMP(List <MeshGroup> meshGroup)
        {
            Pmp pmp = new Pmp();

            pmp.header.MagicCode    = 0x504D50;
            pmp.header.TextureCount = (ushort)TexList.Count;
            pmp.header.ObjectCount  = (ushort)meshGroup.Count;
            pmp.header.ModelCount   = (ushort)meshGroup.Count;
            pmp.header.Padding      = new int[2];
            pmp.PmoList             = new List <Pmo>();
            pmp.objectInfo          = new List <Pmp.ObjectInfo>();
            pmp.TextureList         = new List <Pmp.PMPTextureInfo>();
            pmp.TextureDataList     = new List <Tm2>();

            Pmo pmo = new Pmo();

            foreach (MeshGroup group in meshGroup)
            {
                List <MeshDescriptor> Descriptors    = group.MeshDescriptors;
                List <int>            textureIndices = new List <int>();

                // Max 65K vertices.
                ushort descriptorVertexCount = 0;
                foreach (MeshDescriptor d in Descriptors)
                {
                    descriptorVertexCount += (ushort)d.Vertices.Length;
                    textureIndices.Add(d.TextureIndex);
                }

                // Mesh data.
                for (int i = 0; i < Descriptors.Count; i++)
                {
                    MeshDescriptor desc  = Descriptors[i];
                    Pmo.MeshChunks chunk = new Pmo.MeshChunks();

                    // Obtain info for PMO Vertex Flag.
                    bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                    Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                    Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                    chunk.SectionInfo             = new Pmo.MeshSection();
                    chunk.SectionInfo.Attribute   = 0;
                    chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                    chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                    chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                    // Set extra flags.
                    if (UsesUniformColor)
                    {
                        var UniformColor = (uint)(desc.Vertices[0].A / 255f);
                        UniformColor += (uint)(desc.Vertices[0].B / 255f) << 8;
                        UniformColor += (uint)(desc.Vertices[0].G / 255f) << 16;
                        UniformColor += (uint)(desc.Vertices[0].R / 255f) << 24;
                        chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                        chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                        chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                    }
                    else
                    {
                        chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                    }
                    //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                    //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, 2);
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, 2);

                    chunk.SectionInfo.VertexSize += 0;                                                                                                                    // Weights.
                    TextureCoordinateFormat       = Pmo.CoordinateFormat.NORMALIZED_16_BITS;
                    chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8 : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                    if (chunk.SectionInfo.VertexSize % 4 != 0)
                    {
                        chunk.SectionInfo.VertexSize += 2;
                    }
                    chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4;                                                            // VertexColor
                    VertexFormat = Pmo.CoordinateFormat.NORMALIZED_16_BITS;
                    chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices
                    if (chunk.SectionInfo.VertexSize % 4 != 0)
                    {
                        chunk.SectionInfo.VertexSize += 2;
                    }


                    for (int v = 0; v < desc.Vertices.Length; v++)
                    {
                        Vector4 Color = new Vector4();
                        Color.X = desc.Vertices[v].R * 256;
                        Color.Y = desc.Vertices[v].G * 256;
                        Color.Z = desc.Vertices[v].B * 256;
                        Color.W = 128;
                        chunk.colors.Add(Color);

                        Vector3 vec;
                        vec.X = desc.Vertices[v].X / 10000.0f;
                        vec.Y = desc.Vertices[v].Y / 10000.0f;
                        vec.Z = desc.Vertices[v].Z / 10000.0f;
                        chunk.vertices.Add(vec);

                        Vector2 Coords;
                        Coords.X = desc.Vertices[v].Tu;
                        Coords.Y = desc.Vertices[v].Tv;
                        chunk.textureCoordinates.Add(Coords);
                    }

                    pmo.Meshes.Add(chunk);
                }

                // Header.
                pmo.header                = new Pmo.Header();
                pmo.header.MagicCode      = 0x4F4D50;
                pmo.header.Number         = 1;
                pmo.header.Group          = 1;
                pmo.header.Version        = 3;
                pmo.header.TextureCount   = (byte)textureIndices.Count; // TODO.
                pmo.header.Flag           = 0x800;
                pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
                pmo.header.VertexCount    = descriptorVertexCount;
                pmo.header.TriangleCount  = pmo.header.VertexCount;
                pmo.header.TriangleCount /= 3;
                pmo.header.ModelScale     = 1.0f;
                pmo.header.BoundingBox    = new float[32];

                // Texture block.
                if (textureIndices.Count > 0)
                {
                    pmo.textureInfo = new Pmo.TextureInfo[textureIndices.Count];

                    for (int t = 0; t < textureIndices.Count; t++)
                    {
                        Tm2 tm = TextureData[textureIndices[t]];
                        pmo.textureInfo[t]             = new Pmo.TextureInfo();
                        pmo.textureInfo[t].TextureName = TexList[textureIndices[t]];
                        pmo.textureInfo[t].Unknown     = new UInt32[4];
                        pmo.texturesData.Add(tm);

                        Pmp.PMPTextureInfo pmpInfo = new Pmp.PMPTextureInfo();
                        pmpInfo.TextureName = pmo.textureInfo[t].TextureName;
                        pmpInfo.Unknown     = new uint[4];
                        pmp.TextureList.Add(pmpInfo);
                    }
                }

                Pmp.ObjectInfo info = new Pmp.ObjectInfo();
                info.PMO_Offset = 0x20 + (0x30 * (uint)meshGroup.Count) + 0;

                pmp.PmoList.Add(pmo);
                pmp.objectInfo.Add(info);
            }

            pmp.TextureDataList = TextureData;

            return(pmp);
        }
Esempio n. 4
0
        private static Pmo MeshGroup2PMO(MeshGroup meshGroup)
        {
            Pmo pmo = new Pmo();

            List <MeshDescriptor> Descriptors = meshGroup.MeshDescriptors;

            // Max 65K vertices.
            uint descriptorVertexCount = 0;
            uint indicesVertexCount    = 0;

            foreach (MeshDescriptor d in Descriptors)
            {
                descriptorVertexCount += (uint)d.Vertices.Length;
                indicesVertexCount    += (uint)d.Indices.Length;
            }

            // Mesh data.
            for (int i = 0; i < Descriptors.Count; i++)
            {
                MeshDescriptor desc        = Descriptors[i];
                int[]          vertIndices = desc.Indices;
                Pmo.MeshChunks chunk       = new Pmo.MeshChunks();

                // Obtain info for PMO Vertex Flag.
                bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                chunk.SectionInfo             = new Pmo.MeshSection();
                chunk.SectionInfo.Attribute   = 0;
                chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                // Set extra flags.
                if (UsesUniformColor)
                {
                    var UniformColor = (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].A * 256f));
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].B * 256f)) << 8;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].G * 256f)) << 16;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].R * 256f)) << 24;
                    chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                    chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                    chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                }
                else
                {
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                }
                //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                uint texFormat = 3;
                uint posFormat = 3;

                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, texFormat);
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, posFormat);

                chunk.SectionInfo.VertexSize += 0;                                                                                                                     // Weights.
                TextureCoordinateFormat       = (Pmo.CoordinateFormat)texFormat;
                chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8  : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }

                chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4; // VertexColor

                VertexFormat = (Pmo.CoordinateFormat)posFormat;
                chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }

                for (int v = 0; v < desc.Indices.Length; v++)
                {
                    int index = vertIndices[v];

                    Vector4 Color = new Vector4();
                    Color.X = desc.Vertices[index].R * 256;
                    Color.Y = desc.Vertices[index].G * 256;
                    Color.Z = desc.Vertices[index].B * 256;
                    Color.W = 128;
                    chunk.colors.Add(Color);

                    Vector3 vec;
                    vec.X = desc.Vertices[index].X / 10000.0f;
                    vec.Y = desc.Vertices[index].Y / 10000.0f;
                    vec.Z = desc.Vertices[index].Z / 10000.0f;
                    chunk.vertices.Add(vec);

                    Vector2 Coords;
                    Coords.X = desc.Vertices[index].Tu;
                    Coords.Y = desc.Vertices[index].Tv;
                    chunk.textureCoordinates.Add(Coords);
                }

                pmo.Meshes.Add(chunk);
            }

            // Header.
            pmo.header                = new Pmo.Header();
            pmo.header.MagicCode      = 0x4F4D50;
            pmo.header.Number         = 1;
            pmo.header.Group          = 1;
            pmo.header.Version        = 3;
            pmo.header.TextureCount   = (byte)TextureData.Count; // TODO.
            pmo.header.Flag           = 0x800;
            pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
            pmo.header.VertexCount    = (ushort)indicesVertexCount;
            pmo.header.TriangleCount  = (ushort)indicesVertexCount;
            pmo.header.TriangleCount /= 3;
            pmo.header.ModelScale     = 1.0f;
            pmo.header.BoundingBox    = new float[32];

            // Texture block.
            if (TextureData.Count > 0)
            {
                pmo.textureInfo = new Pmo.TextureInfo[TextureData.Count];

                for (int t = 0; t < TextureData.Count; t++)
                {
                    Tm2 tm = TextureData[t];
                    pmo.textureInfo[t]             = new Pmo.TextureInfo();
                    pmo.textureInfo[t].TextureName = TexList[t];
                    pmo.textureInfo[t].Unknown     = new UInt32[4];
                    pmo.texturesData.Add(TextureData[t]);
                }
            }

            //pmo.header.SkeletonOffset = pmo.header.MeshOffset0 + 0;
            pmo.skeletonHeader = new Pmo.SkeletonHeader();
            pmo.boneList       = new Pmo.BoneData[0];

            /*pmo.skeletonHeader.MagicValue = 0x4E4F42;
             * pmo.skeletonHeader.BoneCount = (ushort)BoneData.Count;
             * pmo.skeletonHeader.SkinnedBoneCount = (ushort)BoneData.Count;
             * pmo.skeletonHeader.nStdBone = 2;
             *
             * pmo.boneList = new Pmo.BoneData[BoneData.Count];
             *
             * for(int b = 0; b < pmo.boneList.Length; b++)
             * {
             *  Pmo.BoneData bn = new Pmo.BoneData();
             *  bn.BoneIndex = (ushort)b;
             *
             *  Assimp.Node curNode = new Assimp.Node();
             *  ushort p = 0;
             *  foreach(var nd in NodeData)
             *  {
             *      p++;
             *      if(nd.Name == BoneData[b].Name)
             *      {
             *          curNode = nd;
             *          p--;
             *          break;
             *      }
             *  }
             *
             *  bn.ParentBoneIndex = p;
             *  bn.JointName = BoneData[b].Name;
             *
             *  Matrix4x4 mtx = new Matrix4x4();
             *  mtx.M11 = BoneData[b].OffsetMatrix.A1;
             *  mtx.M12 = BoneData[b].OffsetMatrix.A2;
             *  mtx.M13 = BoneData[b].OffsetMatrix.A3;
             *  mtx.M14 = BoneData[b].OffsetMatrix.A4;
             *  mtx.M21 = BoneData[b].OffsetMatrix.B1;
             *  mtx.M22 = BoneData[b].OffsetMatrix.B2;
             *  mtx.M23 = BoneData[b].OffsetMatrix.B3;
             *  mtx.M24 = BoneData[b].OffsetMatrix.B4;
             *  mtx.M31 = BoneData[b].OffsetMatrix.C1;
             *  mtx.M32 = BoneData[b].OffsetMatrix.C2;
             *  mtx.M33 = BoneData[b].OffsetMatrix.C3;
             *  mtx.M34 = BoneData[b].OffsetMatrix.C4;
             *  mtx.M41 = BoneData[b].OffsetMatrix.D1;
             *  mtx.M42 = BoneData[b].OffsetMatrix.D2;
             *  mtx.M43 = BoneData[b].OffsetMatrix.D3;
             *  mtx.M44 = BoneData[b].OffsetMatrix.D4;
             *
             *  bn.Transform = mtx;
             *  bn.InverseTransform = mtx;
             *  pmo.boneList[b] = bn;
             * }*/

            return(pmo);
        }