示例#1
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Methods
        //---------------------------------------------------------------
        /// <summary>
        /// Helper function loading a lump from file into structs
        /// </summary>
        /// <param name="lump">Vertices, Faces, ...</param>
        /// <param name="structType">type of struct to load into</param>
        /// <returns>list of instances of structType</returns>
        private IList LoadLump(QuakeLumps lump, Type structType)
        {
            LumpLocation location = (LumpLocation)locations[(int)lump];

            stream.Seek(location.Offset, SeekOrigin.Begin);
            int vertexNum = (int)(location.Length / Marshal.SizeOf(structType));

            return(RawSerializer.DeserializeArray(stream, structType, vertexNum));
        }
示例#2
0
        /// <summary>
        /// Loads the model.
        /// </summary>
        /// <param name="stream">Stream to load model from.</param>
        /// <returns>The loaded model.</returns>
        public Model LoadModel(Stream stream)
        {
            BlendMesh mesh;

            // get header and check if it is ok
            MD2_Header header = (MD2_Header)RawSerializer.Deserialize(stream, typeof(MD2_Header));

            if (header.Ident != 844121161 || header.Version != 8)
            {
                return(null);
            }

            // Load skins
            MD2_Skin[] skinNames = (MD2_Skin[])RawSerializer.DeserializeArray(stream, typeof(MD2_Skin), header.NumSkins);

            // Load texture coordinates
            MD2_TextureCoordinate[] textureCoordinates = (MD2_TextureCoordinate[])RawSerializer.DeserializeArray(stream, typeof(MD2_TextureCoordinate), header.NumTextureCoordinates);

            // Load triangless
            MD2_Triangle[] triangles   = (MD2_Triangle[])RawSerializer.DeserializeArray(stream, typeof(MD2_Triangle), header.NumTris);
            IndexStream    indexStream = new IndexStream16(triangles.Length);

            for (int i = 0; i < triangles.Length; i++)
            {
                // indexStream[i] = triangles[i].VertexIndex[j;
            }

            mesh = new BlendMesh(header.NumFrames);

            // Load frames
            for (int i = 0; i < header.NumFrames; i++)
            {
                MD2_Frame      frame    = (MD2_Frame)RawSerializer.Deserialize(stream, typeof(MD2_Frame));
                MD2_Vertex[]   vertices = (MD2_Vertex[])RawSerializer.DeserializeArray(stream, typeof(MD2_Vertex), header.NumVertices);
                VertexUnit     vu       = new VertexUnit(VertexFormat.Position, vertices.Length);
                PositionStream ps       = (PositionStream)vu[typeof(Purple.Graphics.VertexStreams.PositionStream)];
                mesh.Meshes[i] = new Mesh(new SubSet(vu, indexStream));
            }
            return(new Model(mesh, null));
        }
示例#3
0
        /// <summary>
        /// loads a quake3 level from a stream
        /// </summary>
        /// <param name="stream">stream to load from</param>
        /// <returns>level as a mesh</returns>
        public Mesh Load(Stream stream)
        {
            Mesh mesh = new Mesh();

            this.stream = stream;

            // get header and check if it is ok
            QuakeHeader header = (QuakeHeader)RawSerializer.Deserialize(stream, typeof(QuakeHeader));

            if (header.ID != 1347633737 || header.Version != 0x2e)
            {
                return(null);
            }

            // get locations of lumps
            locations = RawSerializer.DeserializeArray(stream, typeof(LumpLocation), (int)QuakeLumps.LumpNumber);

            // get lumps
            IList quakeVertices  = LoadLump(QuakeLumps.Vertices, typeof(QuakeVertex));
            IList quakeFaces     = LoadLump(QuakeLumps.Faces, typeof(QuakeFace));
            IList quakeTextures  = LoadLump(QuakeLumps.Textures, typeof(QuakeTexture));
            IList quakeLightMaps = LoadLump(QuakeLumps.Lightmaps, typeof(QuakeLightMap));


            // Load all texture images and put into array
            IList textures = LoadTextures(quakeTextures);
            // Load lightMaps, create texture and put into array
            IList lightMaps = LoadLightMaps(quakeLightMaps);

            // create list from vertices
            VertexUnit     vertexUnit = new VertexUnit(VertexFormat.PositionTexture2, quakeVertices.Count);
            PositionStream pos        = (PositionStream)vertexUnit[typeof(PositionStream)];
            TextureStream  texStream  = (TextureStream)vertexUnit[typeof(TextureStream)];
            TextureStream  light      = (TextureStream)vertexUnit[typeof(TextureStream), 1];

            int i = 0;

            foreach (QuakeVertex v in quakeVertices)
            {
                pos[i]       = new Math.Vector3(v.Position[0], v.Position[2], -v.Position[1]);
                texStream[i] = new Math.Vector2(v.TextureCoord[0], v.TextureCoord[1]);
                light[i]     = new Math.Vector2(v.LightmapCoord[0], v.LightmapCoord[1]);
                i++;
            }

            // presort faces
            Array.Sort(((Array)quakeFaces));

            // create mesh
            int       oldLightMap = ((QuakeFace)quakeFaces[0]).LightmapID;
            int       oldTexture  = ((QuakeFace)quakeFaces[0]).TextureID;
            ArrayList indices     = new ArrayList();

            for (i = 0; i < quakeFaces.Count; ++i)
            {
                QuakeFace qf = (QuakeFace)quakeFaces[i];
                if (qf.Type == 1)
                {
                    if (qf.TextureID != oldTexture || qf.LightmapID != oldLightMap)
                    {
                        mesh.SubSets.Add(new SubSet(vertexUnit, IndexStream.Create(indices, vertexUnit.Size)));
                        Textures texs = new Textures("color", (ITexture)textures[oldTexture]);
                        if (oldLightMap == -1)
                        {
                            texs["lightMap"] = null;
                        }
                        else
                        {
                            texs["lightMap"] = (ITexture)lightMaps[oldLightMap];
                        }
                        mesh.Textures.Add(texs);
                        indices.Clear();
                    }

                    // add indices => convert from fan to list
                    for (int j = 2; j < qf.NumOfVerts; j++)
                    {
                        indices.Add(qf.VertexIndex);
                        indices.Add(qf.VertexIndex + j - 1);
                        indices.Add(qf.VertexIndex + j);
                    }

                    oldTexture  = qf.TextureID;
                    oldLightMap = qf.LightmapID;
                }
            }
            return(mesh);
        }
示例#4
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));
            }
        }