Пример #1
0
        public static Pmo.CoordinateFormat GetVertexFormat(MeshDescriptor desc)
        {
            Vector3 ResizedVector = new Vector3();

            // Check if 8 bits per coordinate.
            bool is8bits = true;

            foreach (PositionColoredTextured vert in desc.Vertices)
            {
                ResizedVector = new Vector3(((vert.X / 100.0f) * 128.0f), ((vert.Y / 100.0f) * 128.0f), ((vert.Z / 100.0f) * 128.0f));

                if (ResizedVector.X > 255 || ResizedVector.Y > 255 || ResizedVector.Z > 255)
                {
                    is8bits = false;
                    break;
                }
            }
            if (is8bits)
            {
                return(Pmo.CoordinateFormat.NORMALIZED_8_BITS);
            }

            // Check if 16 bits per coordinate.
            bool is16bits = true;

            foreach (PositionColoredTextured vert in desc.Vertices)
            {
                ResizedVector = new Vector3(((vert.X / 100.0f) * 32768.0f), ((vert.Y / 100.0f) * 32768.0f), ((vert.Z / 100.0f) * 32768.0f));

                if (ResizedVector.X > 65535 || ResizedVector.Y > 65535 || ResizedVector.Z > 65535)
                {
                    is16bits = false;
                    break;
                }
            }
            if (is16bits)
            {
                return(Pmo.CoordinateFormat.NORMALIZED_16_BITS);
            }

            return(Pmo.CoordinateFormat.FLOAT_32_BITS);
        }
Пример #2
0
        private static void CreateMesh <MESH>(IMeshConstructor <MESH> constructor, MeshDescriptor des)
        {
            constructor.PushTriangleMesh(des.Vertices, des.Faces);

            for (int i = 0; i < des.Vertices; i++)
            {
                constructor.AddVertex(CGAL_GetPoint2f(i));
            }

            for (int i = 0; i < des.Faces; i++)
            {
                TriangleIndex triangle = CGAL_GetTriangle(i);
                constructor.AddFace(triangle);
            }

            for (int i = 0; i < des.Faces; i++)
            {
                TriangleIndex triangle = CGAL_GetNeighbor(i);
                constructor.AddFaceConnection(i, triangle);
            }
        }
Пример #3
0
        private static void CreateLine <MESH>(IMeshConstructor <MESH> constructor, MeshDescriptor des)
        {
            constructor.PushEdgeMesh(des.Vertices, des.Edges);

            for (int i = 0; i < des.Vertices; i++)
            {
                Vector2f v = CGAL_GetSkeletonPoint(i);
                constructor.AddVertex(v);
            }

            for (int i = 0; i < des.Edges; i++)
            {
                EdgeIndex edge = CGAL_GetSkeletonEdge(i);
                constructor.AddEdge(edge);
            }

            int numConnections = CGAL_NumEdgeConnection();

            for (int i = 0; i < numConnections; i++)
            {
                EdgeConnection con = CGAL_GetEdgeConnection(i);
                constructor.AddEdgeConnection(con);
            }
        }
Пример #4
0
        private static void CreateMesh <MESH>(IMeshConstructor <MESH> constructor, MeshDescriptor des)
        {
            constructor.PushTriangleMesh(des.Vertices, des.Faces);

            for (int i = 0; i < des.Vertices; i++)
            {
                constructor.AddVertex(CGAL_GetPoint2f(i));
            }

            for (int i = 0; i < des.Faces; i++)
            {
                TriangleIndex triangle = CGAL_GetTriangle(i);
                Vector2f      a        = CGAL_GetPoint2f(triangle.i0);
                Vector2f      b        = CGAL_GetPoint2f(triangle.i1);
                Vector2f      c        = CGAL_GetPoint2f(triangle.i2);

                Vector2f p = (a + b + c) / 3.0f;

                if (PolygonIntersection2.ContainsPoint(p))
                {
                    constructor.AddFace(triangle);
                }
            }
        }
Пример #5
0
 private static extern int CGAL_Triangulate(out MeshDescriptor descriptor);
Пример #6
0
 public void SetRenderMesh(MeshDescriptor meshDesc)
 {
     RenderMesh = meshDesc.mesh;
 }
Пример #7
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);
        }
Пример #8
0
 private static extern int CGAL_CreateExteriorSkeleton(double maxOffset, bool includeBorder, out MeshDescriptor descriptor);
Пример #9
0
 private static extern int CGAL_CreateInteriorSkeleton(bool includeBorder, out MeshDescriptor descriptor);
Пример #10
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);
        }
Пример #11
0
        public static List <MeshGroup> FromFbx(string filePath)
        {
            List <MeshGroup> group = new List <MeshGroup>();

            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                Stream str = File.OpenRead(TexList[TexList.Count - 1]);

                PngImage png     = new PngImage(str);
                Tm2      tmImage = Tm2.Create(png);
                TextureData.Add(tmImage);
            }

            for (int i = 0; i < scene.RootNode.ChildCount; i++)
            {
                Node      child            = scene.RootNode.Children[i];
                MeshGroup currentMeshGroup = new MeshGroup();
                currentMeshGroup.MeshDescriptors = new List <MeshDescriptor>();

                // Get meshes by ID.
                foreach (int j in child.MeshIndices)
                {
                    MeshDescriptor meshDescriptor = new MeshDescriptor();
                    Mesh           x = scene.Meshes[j];

                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var k = 0; k < vertices.Length; k++)
                    {
                        vertices[k].X  = x.Vertices[k].X * Scale;
                        vertices[k].Y  = x.Vertices[k].Y * Scale;
                        vertices[k].Z  = x.Vertices[k].Z * Scale;
                        vertices[k].Tu = x.TextureCoordinateChannels[0][k].X;
                        vertices[k].Tv = 1.0f - x.TextureCoordinateChannels[0][k].Y;
                        vertices[k].R  = x.VertexColorChannels[0][i].R;
                        vertices[k].G  = x.VertexColorChannels[0][i].G;
                        vertices[k].B  = x.VertexColorChannels[0][i].B;
                        vertices[k].A  = x.VertexColorChannels[0][i].A;
                    }

                    meshDescriptor.Vertices     = vertices;
                    meshDescriptor.Indices      = x.GetIndices();
                    meshDescriptor.IsOpaque     = false;
                    meshDescriptor.TextureIndex = x.MaterialIndex;


                    currentMeshGroup.MeshDescriptors.Add(meshDescriptor);
                }

                group.Add(currentMeshGroup);
            }

            return(group);
        }
Пример #12
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);
        }