private MD3Part LoadMD3(string part) { using (Stream stream = fileSystem.Open(path + part + ".md3")) { // get header and check if it is ok MD3_Header header = (MD3_Header)RawSerializer.Deserialize(stream, typeof(MD3_Header)); if (header.Id != 860898377 || header.Version != 15) { return(null); } // load bone frames MD3_Frame[] frames = (MD3_Frame[])RawSerializer.DeserializeArray(stream, typeof(MD3_Frame), header.NumFrames); // load tags SortedList links = GetLinks((MD3_Tag[])RawSerializer.DeserializeArray(stream, typeof(MD3_Tag), header.NumTags * header.NumFrames)); long meshOffset = stream.Position; // one mesh for every frame BlendMesh mesh = new BlendMesh(header.NumFrames); // load meshes for (int iMesh = 0; iMesh < header.NumMeshes; iMesh++) { stream.Position = meshOffset; MD3_MeshHeader meshHeader = (MD3_MeshHeader)RawSerializer.Deserialize(stream, typeof(MD3_MeshHeader)); MD3_Skin[] skins = (MD3_Skin[])RawSerializer.DeserializeArray(stream, typeof(MD3_Skin), meshHeader.NumSkins); stream.Position = meshOffset + meshHeader.TriangleOffset; MD3_Triangle[] triangles = (MD3_Triangle[])RawSerializer.DeserializeArray(stream, typeof(MD3_Triangle), meshHeader.NumTriangles); stream.Position = meshOffset + meshHeader.TexCoordOffset; MD3_TexCoord[] texCoords = (MD3_TexCoord[])RawSerializer.DeserializeArray(stream, typeof(MD3_TexCoord), meshHeader.NumVertices); stream.Position = meshOffset + meshHeader.VertexOffset; MD3_Vertex[] vertices = (MD3_Vertex[])RawSerializer.DeserializeArray(stream, typeof(MD3_Vertex), meshHeader.NumFrames * meshHeader.NumVertices); float scale = 64.0f; string name = StringHelper.Convert(meshHeader.Name); ITexture tx = (ITexture)textures[name]; Triangle[] tris = new Triangle[triangles.Length]; for (int i = 0; i < triangles.Length; i++) { tris[i].A = (triangles[i]).A; tris[i].B = (triangles[i]).B; tris[i].C = (triangles[i]).C; } IndexStream indexStream = IndexStream16.FromTriangles(tris); int vertCount = meshHeader.NumVertices; // *meshHeader.NumFrames; for (int iFrame = 0; iFrame < meshHeader.NumFrames; iFrame++) { VertexUnit vertexUnit = new VertexUnit(VertexFormat.PositionNormalTexture, vertCount); PositionStream pos = (PositionStream)vertexUnit[typeof(PositionStream)]; NormalStream normal = (NormalStream)vertexUnit[typeof(NormalStream)]; TextureStream tex = (TextureStream)vertexUnit[typeof(TextureStream)]; for (int i = 0; i < vertCount; i++) { int vertIndex = iFrame * meshHeader.NumVertices + i; pos[i] = new Vector3(vertices[vertIndex].X / scale, vertices[vertIndex].Z / scale, -vertices[vertIndex].Y / scale); int texIndex = i % meshHeader.NumVertices; tex[i] = new Vector2(texCoords[texIndex].U, texCoords[texIndex].V); //Normal vector int compressedNormal = ((MD3_Vertex)vertices[vertIndex]).Normal; float lng = (compressedNormal & 0xFF) * Math.Basic.PI / 128; float lat = ((compressedNormal >> 8) & 0xFF) * Math.Basic.PI / 128; normal[i] = new Vector3(Math.Trigonometry.Cos(lat) * Math.Trigonometry.Sin(lng), Math.Trigonometry.Cos(lng), -Math.Trigonometry.Sin(lat) * Math.Trigonometry.Sin(lng)); } if (mesh.Meshes[iFrame] == null) { mesh.Meshes[iFrame] = new Mesh(); } mesh.Meshes[iFrame].SubSets.Add(new SubSet(vertexUnit, indexStream)); mesh.Meshes[iFrame].Textures.Add(new Textures("color", tx)); } // Increase the offset into the file meshOffset += meshHeader.MeshSize; } return(new MD3Part(mesh, links)); } }
private void readObject(BlendChunk chunk) { List <BlendVertex> vertexList = new List <BlendVertex>(); List <int> loopList = new List <int>(); setData(chunk.raw); BlendObject bObj = new BlendObject(this); bObj.read(); // Console.WriteLine("bobject.type=" + bObj.type); if (bObj.type != 1) { return; //not a mesh bobject (could be camera, light, etc.) } obj = new OpenGLObject(); model.AddObject(obj); obj.SetName(bObj.id.name.Substring(2)); // Console.WriteLine("bobject=" + obj.name); chunk = findChunkByPtr(bObj.data); if (chunk == null) { throw new Exception("GL_BLEND:Unable to find Mesh for Object"); } BlendMesh mesh = new BlendMesh(this); setData(chunk.raw); // Console.WriteLine("Mesh@" + Int32.toString(raw.fileOffset, 16)); mesh.read(); obj.GetOrigin().x = bObj.loc[0]; org[0] = bObj.loc[0]; obj.GetOrigin().y = bObj.loc[1]; org[1] = bObj.loc[1]; obj.GetOrigin().z = bObj.loc[2]; org[2] = bObj.loc[2]; //find mvert chunk = findChunkByPtr(mesh.mvert); if (chunk == null) { throw new Exception("GL_BLEND:Unable to find MVert for Mesh"); } setData(chunk.raw); for (int a = 0; a < chunk.nr; a++) { BlendMVert mvert = new BlendMVert(this); mvert.read(); // obj.AddVertex(mvert.co); BlendVertex v = new BlendVertex(); v.xyz = mvert.v; vertexList.Add(v); } //find mloop chunk = findChunkByPtr(mesh.mloop); if (chunk == null) { throw new Exception("GL_BLEND:Unable to find MLoop for Mesh"); } setData(chunk.raw); for (int a = 0; a < chunk.nr; a++) { BlendMLoop mloop = new BlendMLoop(this); mloop.read(); loopList.Add(mloop.v); } //find mloopuv /* //use the UVMaps _in the CustomData instead - this fis only the active one * raw = findChunkByPtr(mesh.mloopuv); * if (raw == null) { * throw new Exception("GL_BLEND:Unable to find MLoopUV for Mesh"); * } * setData(raw.raw); * Console.WriteLine("MLoopUV:nr=" + raw.nr); * for(int a=0;a<raw.nr;a++) { * MLoopUV mloopuv = new MLoopUV(); * mloopuv.read(); * } */ //find mpoly chunk = findChunkByPtr(mesh.mpoly); if (chunk == null) { throw new Exception("GL_BLEND:Unable to find MPoly for Mesh"); } setData(chunk.raw); //TODO : calc which vertex needed to be dup'ed for each unique uv value (Blender does this _in their 3ds export script) int type = -1; int pcnt = -1; int vidx = 0; //MPoly = faces for (int a = 0; a < chunk.nr; a++) { BlendMPoly mpoly = new BlendMPoly(this); mpoly.read(); switch (mpoly.totloop) { case 3: if (type == GL_QUADS) { throw new Exception("GL_BLEND:Mixed QUADS/TRIANGLES not supported"); } type = GL_TRIANGLES; pcnt = 3; break; case 4: if (type == GL_TRIANGLES) { throw new Exception("GL_BLEND:Mixed QUADS/TRIANGLES not supported"); } type = GL_QUADS; pcnt = 4; break; default: throw new Exception("GL_BLEND:Polygon not supported:nr=" + mpoly.totloop); } int loopidx = mpoly.loopstart; for (int p = 0; p < pcnt; p++) { int idx = loopList.Get(loopidx++); obj.AddVertex(vertexList.Get(idx).xyz); obj.AddPoly(new int[] { vidx++ }); } } obj.SetType(type); //find customdata types readLayer(mesh.vdata.layers, "vdata"); readLayer(mesh.edata.layers, "edata"); readLayer(mesh.fdata.layers, "fdata"); readLayer(mesh.pdata.layers, "pdata"); readLayer(mesh.ldata.layers, "ldata"); }
public MD3Part(BlendMesh mesh, SortedList links) { this.Mesh = mesh; this.Links = links; }