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