Esempio n. 1
0
        private static void WriteMaterialLib(Geometry_000F g, StreamWriter MTLWriter, ref int untexturedMaterials)
        {
            string textureName;

            if (g.materialList.materialList[0].materialStruct.isTextured != 0)
            {
                textureName = g.materialList.materialList[0].texture.diffuseTextureName.stringString;
            }
            else
            {
                textureName = "default_" + untexturedMaterials.ToString();
                untexturedMaterials++;
            }

            MTLWriter.WriteLine("newmtl " + textureName + "_m");
            MTLWriter.WriteLine("Ka 0.2 0.2 0.2");
            MTLWriter.WriteLine("Kd 0.8 0.8 0.8");
            MTLWriter.WriteLine("Ks 0 0 0");
            MTLWriter.WriteLine("Ns 10");
            MTLWriter.WriteLine("d 1.0");
            MTLWriter.WriteLine("illum 4");
            if (g.materialList.materialList[0].materialStruct.isTextured != 0)
            {
                MTLWriter.WriteLine("map_Kd " + textureName + ".png");
            }
            MTLWriter.WriteLine();
        }
Esempio n. 2
0
        private void AddGeometry(SharpDevice device, Geometry_000F g, Matrix transformMatrix)
        {
            List <string> materialList = new List <string>();

            foreach (Material_0007 m in g.materialList.materialList)
            {
                if (m.texture != null)
                {
                    string textureName = m.texture.diffuseTextureName.stringString;
                    materialList.Add(textureName);
                }
                else
                {
                    materialList.Add(DefaultTexture);
                }
            }

            if ((g.geometryStruct.geometryFlags2 & GeometryFlags2.isNativeGeometry) != 0)
            {
                AddNativeData(device, g.geometryExtension, materialList, transformMatrix);
                return;
            }

            List <Vector3>       vertexList1   = new List <Vector3>();
            List <Vector3>       normalList    = new List <Vector3>();
            List <Vector2>       textCoordList = new List <Vector2>();
            List <SharpDX.Color> colorList     = new List <SharpDX.Color>();

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexPositions) != 0)
            {
                MorphTarget m = g.geometryStruct.morphTargets[0];
                foreach (Vertex3 v in m.vertices)
                {
                    Vector3 pos = (Vector3)Vector3.Transform(new Vector3(v.X, v.Y, v.Z), transformMatrix);
                    vertexList1.Add(pos);
                    vertexListG.Add(pos);
                }
            }

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasNormals) != 0)
            {
                for (int i = 0; i < vertexList1.Count; i++)
                {
                    normalList.Add(new Vector3(g.geometryStruct.morphTargets[0].normals[i].X, g.geometryStruct.morphTargets[0].normals[i].Y, g.geometryStruct.morphTargets[0].normals[i].Z));
                }
            }

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexColors) != 0)
            {
                for (int i = 0; i < vertexList1.Count; i++)
                {
                    RenderWareFile.Color c = g.geometryStruct.vertexColors[i];
                    colorList.Add(new SharpDX.Color(c.R, c.G, c.B, c.A));
                }
            }
            else
            {
                for (int i = 0; i < vertexList1.Count; i++)
                {
                    colorList.Add(new SharpDX.Color(1f, 1f, 1f, 1f));
                }
            }

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasTextCoords) != 0)
            {
                for (int i = 0; i < vertexList1.Count; i++)
                {
                    Vertex2 tc = g.geometryStruct.textCoords[i];
                    textCoordList.Add(new Vector2(tc.X, tc.Y));
                }
            }
            else
            {
                for (int i = 0; i < vertexList1.Count; i++)
                {
                    textCoordList.Add(new Vector2());
                }
            }

            List <SharpSubSet> SubsetList = new List <SharpSubSet>();
            List <int>         indexList  = new List <int>();
            int previousIndexCount        = 0;

            for (int i = 0; i < materialList.Count; i++)
            {
                foreach (Triangle t in g.geometryStruct.triangles)
                {
                    if (t.materialIndex == i)
                    {
                        indexList.Add(t.vertex1);
                        indexList.Add(t.vertex2);
                        indexList.Add(t.vertex3);

                        triangleList.Add(new Triangle(t.materialIndex, (ushort)(t.vertex1 + triangleListOffset), (ushort)(t.vertex2 + triangleListOffset), (ushort)(t.vertex3 + triangleListOffset)));
                    }
                }

                if (indexList.Count - previousIndexCount > 0)
                {
                    SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount,
                                                   TextureManager.GetTextureFromDictionary(materialList[i]), materialList[i]));
                }

                previousIndexCount = indexList.Count();
            }

            triangleListOffset += vertexList1.Count;

            if (SubsetList.Count > 0)
            {
                VertexColoredTextured[] vertices = new VertexColoredTextured[vertexList1.Count];
                for (int i = 0; i < vertices.Length; i++)
                {
                    vertices[i] = new VertexColoredTextured(vertexList1[i], textCoordList[i], colorList[i]);
                }
                AddToMeshList(SharpMesh.Create(device, vertices, indexList.ToArray(), SubsetList));
            }
            else
            {
                AddToMeshList(null);
            }
        }
Esempio n. 3
0
        private static void WriteNativeData(StreamWriter writer, Geometry_000F g)
        {
            NativeDataGC n = null;

            foreach (RWSection rw in g.geometryExtension.extensionSectionList)
            {
                if (rw is BinMeshPLG_050E binmesh)
                {
                    if (binmesh.numMeshes == 0)
                    {
                        return;
                    }
                }
                if (rw is NativeDataPLG_0510 native)
                {
                    n = native.nativeDataStruct.nativeData;
                    break;
                }
            }

            if (n == null)
            {
                throw new Exception();
            }

            List <Vertex3>   vertexList_init    = new List <Vertex3>();
            List <Color>     colorList_init     = new List <Color>();
            List <TextCoord> textCoordList_init = new List <TextCoord>();
            List <Vertex3>   normalList_init    = new List <Vertex3>();
            List <Triangle>  triangleList       = new List <Triangle>();

            foreach (Declaration d in n.declarations)
            {
                if (d.declarationType == Declarations.Vertex)
                {
                    foreach (Vertex3 v in d.entryList)
                    {
                        vertexList_init.Add(v);
                    }
                }
                else if (d.declarationType == Declarations.Color)
                {
                    foreach (Color c in d.entryList)
                    {
                        colorList_init.Add(c);
                    }
                }
                else if (d.declarationType == Declarations.TextCoord)
                {
                    foreach (TextCoord t in d.entryList)
                    {
                        textCoordList_init.Add(t);
                    }
                }
                else if (d.declarationType == Declarations.Normal)
                {
                    foreach (Vertex3 v in d.entryList)
                    {
                        normalList_init.Add(v);
                    }
                }
                else
                {
                    throw new Exception();
                }
            }

            foreach (TriangleDeclaration td in n.triangleDeclarations)
            {
                foreach (TriangleList tl in td.TriangleListList)
                {
                    List <Vertex3>   vertexList_final    = new List <Vertex3>();
                    List <Color>     colorList_final     = new List <Color>();
                    List <TextCoord> textCoordList_final = new List <TextCoord>();
                    List <Vertex3>   normalList_final    = new List <Vertex3>();

                    foreach (int[] objectList in tl.entries)
                    {
                        for (int j = 0; j < objectList.Count(); j++)
                        {
                            if (n.declarations[j].declarationType == Declarations.Vertex)
                            {
                                vertexList_final.Add(vertexList_init[objectList[j]]);
                            }
                            else if (n.declarations[j].declarationType == Declarations.Color)
                            {
                                colorList_final.Add(colorList_init[objectList[j]]);
                            }
                            else if (n.declarations[j].declarationType == Declarations.TextCoord)
                            {
                                textCoordList_final.Add(textCoordList_init[objectList[j]]);
                            }
                            else if (n.declarations[j].declarationType == Declarations.Normal)
                            {
                                normalList_final.Add(normalList_init[objectList[j]]);
                            }
                            else
                            {
                                throw new Exception();
                            }
                        }
                    }

                    bool control = true;

                    for (int i = 2; i < vertexList_final.Count(); i++)
                    {
                        if (control)
                        {
                            triangleList.Add(new Triangle
                            {
                                materialIndex = (ushort)td.MaterialIndex,
                                vertex1       = (ushort)(i - 2),
                                vertex2       = (ushort)(i - 1),
                                vertex3       = (ushort)(i)
                            });
                        }
                        else
                        {
                            triangleList.Add(new Triangle
                            {
                                materialIndex = (ushort)td.MaterialIndex,
                                vertex1       = (ushort)(i - 2),
                                vertex2       = (ushort)(i),
                                vertex3       = (ushort)(i - 1)
                            });
                        }

                        control = !control;
                    }

                    //Write vertex list to obj
                    foreach (Vertex3 i in vertexList_final)
                    {
                        writer.WriteLine("v " + i.X.ToString() + " " + i.Y.ToString() + " " + i.Z.ToString());
                    }
                    writer.WriteLine();

                    //Write uv list to obj
                    if (textCoordList_final.Count() > 0)
                    {
                        foreach (TextCoord i in textCoordList_final)
                        {
                            writer.WriteLine("vt " + i.X.ToString() + " " + (-i.Y).ToString());
                        }
                    }
                    writer.WriteLine();

                    //Write normal list to obj
                    if (normalList_final.Count() > 0)
                    {
                        foreach (Vertex3 i in normalList_final)
                        {
                            writer.WriteLine("vn " + i.X.ToString() + " " + i.Y.ToString() + " " + i.Z.ToString());
                        }
                    }
                    writer.WriteLine();

                    // Write vcolors to obj
                    if (colorList_final.Count() > 0)
                    {
                        foreach (Color i in colorList_final)
                        {
                            writer.WriteLine("vc " + i.R.ToString() + " " + i.G.ToString() + " " + i.B.ToString() + " " + i.A.ToString());
                        }
                    }
                    writer.WriteLine();

                    foreach (Triangle t in triangleList)
                    {
                        List <char> v1 = new List <char>(8);
                        List <char> v2 = new List <char>(8);
                        List <char> v3 = new List <char>(8);

                        int n1 = t.vertex1 + totalVertexIndices;
                        int n2 = t.vertex2 + totalVertexIndices;
                        int n3 = t.vertex3 + totalVertexIndices;

                        v1.AddRange(n1.ToString());
                        v2.AddRange(n2.ToString());
                        v3.AddRange(n3.ToString());

                        if (((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) & (g.geometryStruct.geometryFlags & (int)GeometryFlags.hasNormals) != 0)
                        {
                            v1.AddRange("/" + n1.ToString() + "/" + n1.ToString());
                            v2.AddRange("/" + n2.ToString() + "/" + n2.ToString());
                            v3.AddRange("/" + n3.ToString() + "/" + n3.ToString());
                        }
                        else if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0)
                        {
                            v1.AddRange("/" + n1.ToString());
                            v2.AddRange("/" + n2.ToString());
                            v3.AddRange("/" + n3.ToString());
                        }
                        else if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasNormals) != 0)
                        {
                            v1.AddRange("//" + n1.ToString());
                            v2.AddRange("//" + n2.ToString());
                            v3.AddRange("//" + n3.ToString());
                        }
                        writer.WriteLine("f " + new string(v1.ToArray()) + " " + new string(v2.ToArray()) + " " + new string(v3.ToArray()));
                    }

                    writer.WriteLine();

                    totalVertexIndices += vertexList_final.Count();
                }
            }
        }
Esempio n. 4
0
        private static void ExportGeometryToOBJ(StreamWriter writer, Geometry_000F g, ref int untexturedMaterials)
        {
            List <string> MaterialList = new List <string>();

            foreach (Material_0007 m in g.materialList.materialList)
            {
                if (m.texture != null)
                {
                    string textureName = m.texture.diffuseTextureName.stringString;
                    //if (!MaterialList.Contains(textureName))
                    MaterialList.Add(textureName);
                }
                else
                {
                    MaterialList.Add("default");
                }
            }

            GeometryStruct_0001 gs = g.geometryStruct;

            if (g.materialList.materialList[0].materialStruct.isTextured != 0)
            {
                writer.WriteLine("g obj_" + g.materialList.materialList[0].texture.diffuseTextureName.stringString);
                writer.WriteLine("usemtl " + g.materialList.materialList[0].texture.diffuseTextureName.stringString + "_m");
            }
            else
            {
                writer.WriteLine("g obj_default_" + untexturedMaterials.ToString());
                writer.WriteLine("usemtl default_" + untexturedMaterials.ToString() + "_m");
                untexturedMaterials++;
            }
            writer.WriteLine();

            if (gs.geometryFlags2 == 0x0101)
            {
                WriteNativeData(writer, g);
                return;
            }

            foreach (MorphTarget m in gs.morphTargets)
            {
                if (m.hasVertices != 0)
                {
                    foreach (Vertex3 v in m.vertices)
                    {
                        writer.WriteLine("v " + v.X.ToString() + " " + v.Y.ToString() + " " + v.Z.ToString());
                    }
                    writer.WriteLine();
                }

                if (m.hasNormals != 0)
                {
                    foreach (Vertex3 vn in m.normals)
                    {
                        writer.WriteLine("vn " + vn.X.ToString() + " " + vn.Y.ToString() + " " + vn.Z.ToString());
                    }
                    writer.WriteLine();
                }

                if ((gs.geometryFlags & (int)GeometryFlags.hasVertexColors) != 0)
                {
                    foreach (Color c in gs.vertexColors)
                    {
                        writer.WriteLine("vc " + c.R.ToString() + " " + c.G.ToString() + " " + c.B.ToString() + " " + c.A.ToString());
                    }
                    writer.WriteLine();
                }

                if ((gs.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0)
                {
                    foreach (TextCoord tc in gs.textCoords)
                    {
                        writer.WriteLine("vt " + tc.X.ToString() + " " + tc.Y.ToString());
                    }
                    writer.WriteLine();
                }

                foreach (Triangle t in gs.triangles)
                {
                    List <char> v1 = new List <char>(8);
                    List <char> v2 = new List <char>(8);
                    List <char> v3 = new List <char>(8);

                    int n1 = t.vertex1 + totalVertexIndices;
                    int n2 = t.vertex2 + totalVertexIndices;
                    int n3 = t.vertex3 + totalVertexIndices;

                    if (m.hasVertices != 0)
                    {
                        v1.AddRange(n1.ToString());
                        v2.AddRange(n2.ToString());
                        v3.AddRange(n3.ToString());
                    }
                    if (((gs.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) & (m.hasNormals != 0))
                    {
                        v1.AddRange("/" + n1.ToString() + "/" + n1.ToString());
                        v2.AddRange("/" + n2.ToString() + "/" + n2.ToString());
                        v3.AddRange("/" + n3.ToString() + "/" + n3.ToString());
                    }
                    else if ((gs.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0)
                    {
                        v1.AddRange("/" + n1.ToString());
                        v2.AddRange("/" + n2.ToString());
                        v3.AddRange("/" + n3.ToString());
                    }
                    else if (m.hasNormals != 0)
                    {
                        v1.AddRange("//" + n1.ToString());
                        v2.AddRange("//" + n2.ToString());
                        v3.AddRange("//" + n3.ToString());
                    }
                    writer.WriteLine("f " + new string(v1.ToArray()) + " " + new string(v2.ToArray()) + " " + new string(v3.ToArray()));
                }

                totalVertexIndices += m.vertices.Count();
                writer.WriteLine();
            }
        }
Esempio n. 5
0
        void AddGeometry(Geometry_000F g)
        {
            List <string> MaterialList = new List <string>();

            foreach (Material_0007 m in g.materialList.materialList)
            {
                if (m.texture != null)
                {
                    string textureName = m.texture.diffuseTextureName.stringString;
                    if (!MaterialList.Contains(textureName))
                    {
                        MaterialList.Add(textureName);
                    }
                }
                else
                {
                    MaterialList.Add(DefaultTexture);
                }
            }

            if (g.geometryStruct.geometryFlags2 == 0x0101)
            {
                AddNativeData(g.geometryExtension, MaterialList);
                return;
            }

            List <VertexColoredTextured> vertexList = new List <VertexColoredTextured>();

            if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasVertexPositions) != 0)
            {
                foreach (Vertex3 v in g.geometryStruct.morphTargets[0].vertices)
                {
                    vertexList.Add(new VertexColoredTextured(new Vector3(v.X, v.Y, v.Z),
                                                             new Vector2(),
                                                             SharpDX.Color.White
                                                             ));
                    this.vertexList.Add(new Vector3(v.X, v.Y, v.Z));
                }
            }

            if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasVertexColors) != 0)
            {
                for (int i = 0; i < vertexList.Count; i++)
                {
                    RenderWareFile.Color c = g.geometryStruct.vertexColors[i];

                    VertexColoredTextured v = vertexList[i];
                    v.Color       = new SharpDX.Color(c.R, c.G, c.B, c.A);
                    vertexList[i] = v;
                }
            }
            else
            {
                for (int i = 0; i < vertexList.Count; i++)
                {
                    VertexColoredTextured v = vertexList[i];
                    v.Color       = SharpDX.Color.White;
                    vertexList[i] = v;
                }
            }

            if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0)
            {
                for (int i = 0; i < vertexList.Count; i++)
                {
                    TextCoord tc = g.geometryStruct.textCoords[i];

                    VertexColoredTextured v = vertexList[i];
                    v.TextureCoordinate = new Vector2(tc.X, tc.Y);
                    vertexList[i]       = v;
                }
            }

            List <SharpSubSet> SubsetList = new List <SharpSubSet>();
            List <int>         indexList  = new List <int>();
            int previousIndexCount        = 0;

            for (int i = 0; i < MaterialList.Count; i++)
            {
                foreach (Triangle t in g.geometryStruct.triangles)
                {
                    if (t.materialIndex == i)
                    {
                        indexList.Add(t.vertex1);
                        indexList.Add(t.vertex2);
                        indexList.Add(t.vertex3);

                        triangleList.Add(t);
                    }
                }

                if (indexList.Count - previousIndexCount > 0)
                {
                    if (BSPRenderer.TextureStream.ContainsKey(MaterialList[i]))
                    {
                        SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount, BSPRenderer.TextureStream[MaterialList[i]]));
                    }
                    else
                    {
                        SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount, BSPRenderer.whiteDefault));
                    }
                }

                previousIndexCount = indexList.Count();
            }

            if (SubsetList.Count > 0)
            {
                meshList.Add(SharpMesh.Create(SharpRenderer.device, vertexList.ToArray(), indexList.ToArray(), SubsetList));
            }
        }
        private void AddGeometry(SharpDevice device, Geometry_000F g, Matrix transformMatrix)
        {
            List <string> MaterialList = new List <string>();

            foreach (Material_0007 m in g.materialList.materialList)
            {
                if (m.texture != null)
                {
                    string textureName = m.texture.diffuseTextureName.stringString;
                    if (!MaterialList.Contains(textureName))
                    {
                        MaterialList.Add(textureName);
                    }
                }
                else
                {
                    MaterialList.Add(DefaultTexture);
                }
            }

            if ((g.geometryStruct.geometryFlags2 & GeometryFlags2.isNativeGeometry) != 0)
            {
                AddNativeData(device, g.geometryExtension, MaterialList, transformMatrix);
                return;
            }

            List <VertexColoredTextured> vertexList = new List <VertexColoredTextured>();

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexPositions) != 0)
            {
                foreach (Vertex3 v in g.geometryStruct.morphTargets[0].vertices)
                {
                    Vector3 Position = (Vector3)Vector3.Transform(new Vector3(v.X, v.Y, v.Z), transformMatrix);

                    vertexList.Add(new VertexColoredTextured(Position, new Vector2(), SharpDX.Color.White));
                    vertexListG.Add(Position);
                }
            }

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexColors) != 0)
            {
                for (int i = 0; i < vertexList.Count; i++)
                {
                    RenderWareFile.Color c = g.geometryStruct.vertexColors[i];

                    VertexColoredTextured v = vertexList[i];
                    v.Color       = new SharpDX.Color(c.R, c.G, c.B, c.A);
                    vertexList[i] = v;
                }
            }
            else
            {
                for (int i = 0; i < vertexList.Count; i++)
                {
                    VertexColoredTextured v = vertexList[i];
                    v.Color       = SharpDX.Color.White;
                    vertexList[i] = v;
                }
            }

            if ((g.geometryStruct.geometryFlags & GeometryFlags.hasTextCoords) != 0)
            {
                for (int i = 0; i < vertexList.Count; i++)
                {
                    Vertex2 tc = g.geometryStruct.textCoords[i];

                    VertexColoredTextured v = vertexList[i];
                    v.TextureCoordinate = new Vector2(tc.X, tc.Y);
                    vertexList[i]       = v;
                }
            }

            List <SharpSubSet> SubsetList = new List <SharpSubSet>();
            List <int>         indexList  = new List <int>();
            int previousIndexCount        = 0;

            for (int i = 0; i < MaterialList.Count; i++)
            {
                foreach (Triangle t in g.geometryStruct.triangles)
                {
                    if (t.materialIndex == i)
                    {
                        indexList.Add(t.vertex1);
                        indexList.Add(t.vertex2);
                        indexList.Add(t.vertex3);

                        triangleList.Add(new Triangle(t.materialIndex, (ushort)(t.vertex1 + triangleListOffset), (ushort)(t.vertex2 + triangleListOffset), (ushort)(t.vertex3 + triangleListOffset)));
                    }
                }

                if (indexList.Count - previousIndexCount > 0)
                {
                    SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount,
                                                   TextureManager.GetTextureFromDictionary(MaterialList[i]), MaterialList[i]));
                }

                previousIndexCount = indexList.Count();
            }

            triangleListOffset += vertexList.Count;

            if (SubsetList.Count > 0)
            {
                meshList.Add(SharpMesh.Create(device, vertexList.ToArray(), indexList.ToArray(), SubsetList));
            }
        }
Esempio n. 7
0
        private static void ExportGeometryToOBJ(StreamWriter writer, Geometry_000F g, ref List <Triangle> triangleList, ref int totalVertexIndices, ref int untexturedMaterials, bool flipUVs)
        {
            List <string> materialList = new List <string>();

            foreach (Material_0007 m in g.materialList.materialList)
            {
                if (m.texture != null)
                {
                    string textureName = m.texture.diffuseTextureName.stringString;
                    //if (!MaterialList.Contains(textureName))
                    materialList.Add(textureName);
                }
                else
                {
                    materialList.Add("default");
                }
            }

            GeometryStruct_0001 gs = g.geometryStruct;

            if (gs.geometryFlags2 == (GeometryFlags2)0x0101)
            {
                GetNativeTriangleList(writer, g.geometryExtension, materialList, ref triangleList, ref totalVertexIndices, flipUVs);
                return;
            }

            if (g.materialList.materialList[0].materialStruct.isTextured != 0)
            {
                string mn = g.materialList.materialList[0].texture.diffuseTextureName.stringString;

                if (string.IsNullOrEmpty(lastMaterial) || lastMaterial != mn)
                {
                    writer.WriteLine("g obj_" + mn);
                    writer.WriteLine("usemtl " + mn + "_m");
                }

                lastMaterial = mn;
            }
            else
            {
                writer.WriteLine("g obj_default_" + untexturedMaterials.ToString());
                writer.WriteLine("usemtl default_" + untexturedMaterials.ToString() + "_m");
                untexturedMaterials++;
            }
            writer.WriteLine();

            foreach (MorphTarget m in gs.morphTargets)
            {
                if (m.hasVertices != 0)
                {
                    foreach (Vertex3 v in m.vertices)
                    {
                        writer.WriteLine("v " + v.X.ToString() + " " + v.Y.ToString() + " " + v.Z.ToString());
                    }
                    writer.WriteLine();
                }

                if (m.hasNormals != 0)
                {
                    foreach (Vertex3 vn in m.normals)
                    {
                        writer.WriteLine("vn " + vn.X.ToString() + " " + vn.Y.ToString() + " " + vn.Z.ToString());
                    }
                    writer.WriteLine();
                }

                if ((gs.geometryFlags & GeometryFlags.hasVertexColors) != 0)
                {
                    foreach (Color c in gs.vertexColors)
                    {
                        writer.WriteLine("vc " + c.R.ToString() + " " + c.G.ToString() + " " + c.B.ToString() + " " + c.A.ToString());
                    }
                    writer.WriteLine();
                }

                if ((gs.geometryFlags & GeometryFlags.hasTextCoords) != 0)
                {
                    foreach (Vertex2 tc in gs.textCoords)
                    {
                        writer.WriteLine("vt " + tc.X.ToString() + " " + tc.Y.ToString());
                    }
                    writer.WriteLine();
                }

                foreach (RenderWareFile.Triangle t in gs.triangles)
                {
                    List <char> v1 = new List <char>(8);
                    List <char> v2 = new List <char>(8);
                    List <char> v3 = new List <char>(8);

                    int n1 = t.vertex1 + totalVertexIndices;
                    int n2 = t.vertex2 + totalVertexIndices;
                    int n3 = t.vertex3 + totalVertexIndices;

                    if (m.hasVertices != 0)
                    {
                        v1.AddRange(n1.ToString());
                        v2.AddRange(n2.ToString());
                        v3.AddRange(n3.ToString());
                    }
                    if (((gs.geometryFlags & GeometryFlags.hasTextCoords) != 0) & (m.hasNormals != 0))
                    {
                        v1.AddRange("/" + n1.ToString() + "/" + n1.ToString());
                        v2.AddRange("/" + n2.ToString() + "/" + n2.ToString());
                        v3.AddRange("/" + n3.ToString() + "/" + n3.ToString());
                    }
                    else if ((gs.geometryFlags & GeometryFlags.hasTextCoords) != 0)
                    {
                        v1.AddRange("/" + n1.ToString());
                        v2.AddRange("/" + n2.ToString());
                        v3.AddRange("/" + n3.ToString());
                    }
                    else if (m.hasNormals != 0)
                    {
                        v1.AddRange("//" + n1.ToString());
                        v2.AddRange("//" + n2.ToString());
                        v3.AddRange("//" + n3.ToString());
                    }
                    writer.WriteLine("f " + new string(v1.ToArray()) + " " + new string(v2.ToArray()) + " " + new string(v3.ToArray()));
                }

                totalVertexIndices += m.vertices.Count();
                writer.WriteLine();
            }
        }