Пример #1
0
        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));
            }
        }
Пример #2
0
        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");
        }
Пример #3
0
 public MD3Part(BlendMesh mesh, SortedList links)
 {
     this.Mesh  = mesh;
     this.Links = links;
 }