public static WavefrontModel FromDMC4Model(DMC4Model model)
        {
            WavefrontModel convertedModel = new WavefrontModel();
            float3[] vertices = new float3[model.Vertices.Length];
            float3[] normals = new float3[model.Vertices.Length];
            float3[] texcoords = new float3[model.Vertices.Length];
            for (int i = 0; i < model.Vertices.Length; i++)
            {
                vertices[i] = new float3((float)model.Vertices[i].Position.X / (float)model.Vertices[i].Position.W,
                    (float)model.Vertices[i].Position.Y / (float)model.Vertices[i].Position.W,
                    (float)model.Vertices[i].Position.Z / (float)model.Vertices[i].Position.W);
                normals[i] = new float3((float)model.Vertices[i].Normals.X / (float)model.Vertices[i].Normals.W,
                    (float)model.Vertices[i].Normals.Y / (float)model.Vertices[i].Normals.W,
                    (float)model.Vertices[i].Normals.Z / (float)model.Vertices[i].Normals.W);
                texcoords[i] = new float3((float)model.Vertices[i].TEXCOORD0.X / (float)short.MaxValue,
                    (float)model.Vertices[i].TEXCOORD0.Y / (float)short.MaxValue,
                    0.0f);

            }
            short[] tris = new short[model.Triangles.Length];
            for (int i = 0; i < model.Triangles.Length; i++)
            {
                tris[i] = (short)(model.Triangles[i] + 1);//Triangle indexing in Wavefront starts from 1
            }
            //Remap vertices (denormalization)
            foreach (var vertex in vertices)
            {
                vertex.X = vertex.X * (model.MaxBoundingbox.X - model.MinBoundingbox.X) + model.MinBoundingbox.X;
                vertex.Y = vertex.Y * (model.MaxBoundingbox.Y - model.MinBoundingbox.Y) + model.MinBoundingbox.Y;
                vertex.Z = vertex.Z * (model.MaxBoundingbox.Z - model.MinBoundingbox.Z) + model.MinBoundingbox.Z;
            }

            convertedModel.Vertices = vertices;
            convertedModel.Normals = normals;
            convertedModel.TextureCoordinates = texcoords;
            convertedModel.Triangles = tris;

            return convertedModel;
        }
 public string PrintNormal(float3 normal)
 {
     return "vn " + normal.X.ToString(CultureInfo.InvariantCulture) + " " + normal.Y.ToString(CultureInfo.InvariantCulture) + " " + normal.Z.ToString(CultureInfo.InvariantCulture);
 }
 public string PrintTextureCoord(float3 texcoord)
 {
     return "vt " + texcoord.X.ToString(CultureInfo.InvariantCulture) + " " + texcoord.Y.ToString(CultureInfo.InvariantCulture) + " " + texcoord.Z.ToString(CultureInfo.InvariantCulture);
 }
 //Data to string
 public string PrintVertex(float3 vertex)
 {
     return "v " + vertex.X.ToString(CultureInfo.InvariantCulture) + " " + vertex.Y.ToString(CultureInfo.InvariantCulture) + " " + vertex.Z.ToString(CultureInfo.InvariantCulture);
 }
        public void LoadModel(string filepath)
        {
            byte[] data = File.ReadAllBytes(filepath);

            //Fileheader
            byte[] filetype = data.Take(3).ToArray();
            string s = Encoding.UTF8.GetString(filetype, 0, filetype.Length);
            if (s == "MOD")//This is probably the correct file
            {
                //**************
                // Parse header
                //**************
                ADDR_VERT_START = BitConverter.ToInt32(data.Skip(HEADADDR_ADDR_VERT_START).Take(4).ToArray(),0);
                ADDR_TRI_START = BitConverter.ToInt32(data.Skip(HEADADDR_ADDR_TRI_START).Take(4).ToArray(), 0);
                MinBoundingbox = new float3(BitConverter.ToSingle(data.Skip(HEADADDR_MINBB_START).Take(12).ToArray(),0),
                    BitConverter.ToSingle(data.Skip(HEADADDR_MINBB_START).Take(12).ToArray(), 4),
                    BitConverter.ToSingle(data.Skip(HEADADDR_MINBB_START).Take(12).ToArray(),8));
                MaxBoundingbox = new float3(BitConverter.ToSingle(data.Skip(HEADADDR_MAXBB_START).Take(12).ToArray(), 0),
                    BitConverter.ToSingle(data.Skip(HEADADDR_MAXBB_START).Take(12).ToArray(), 4),
                    BitConverter.ToSingle(data.Skip(HEADADDR_MAXBB_START).Take(12).ToArray(), 8));

                //************
                // Parse data
                //************
                if((ADDR_VERT_START - ADDR_TRI_START)%32 == 0)
                {
                    int vertexCount = (ADDR_TRI_START - ADDR_VERT_START) / 32;
                    //Create vertices
                    Vertices = new DefaultVertexDeclaration[vertexCount];
                    for (int i = 0; i < vertexCount; i++)
                    {
                        int address = ADDR_VERT_START + i * 32;
                        DefaultVertexDeclaration vertex = DefaultVertexDeclaration.FromByteCode(data.Skip(address).Take(32).ToArray());
                        Vertices[i] = vertex;
                    }

                    //Create triangles
                    int indexCount = (data.Length - ADDR_TRI_START) / 2;
                    short[] indices = new short[indexCount];
                    for (int i = 0; i < indexCount; i++)
                    {
                        int address = ADDR_TRI_START + i * 2;
                        short index = (short)(BitConverter.ToInt16(data, address));
                        indices[i] = index;
                    }
                    //parse indices into faces/triangles
                    List<short> faces = new List<short>();
                    bool triangleMode = true;
                    bool forward = true;
                    for (int i = 0; i < indices.Length - 2; i++)
                    {
                        if (i > 0 && indices[i - 1] == indices[i])
                            triangleMode = true;
                        if (triangleMode)
                        {
                            //Triangle mode is enabled we are currently looking at triangles
                            if (forward)
                            {
                                faces.Add(indices[i]);
                                faces.Add(indices[i+1]);
                                faces.Add(indices[i+2]);
                            }
                            else
                            {
                                faces.Add(indices[i + 2]);
                                faces.Add(indices[i + 1]);
                                faces.Add(indices[i]);
                            }
                            forward = !forward;
                        }

                        if ((i+3)<indices.Length && indices[i + 2] == indices[i + 3]){
                            forward = true;
                            triangleMode = false;
                            i += 3;//Skip some steps, faster analysis
                        }

                    }
                    Triangles = faces.ToArray();
                }

            }
        }