예제 #1
0
        public void ExportOBJ(string filename)
        {
            MDLBlock mdl;// = (Blocks[BlockHeader.MAGIC_MODEL3] ?? Blocks[BlockHeader.MAGIC_MODEL2]) as MDLBlock;

            if (Blocks.ContainsKey(BlockHeader.MAGIC_MODEL2))
            {
                mdl = Blocks[BlockHeader.MAGIC_MODEL2] as MDLBlock;
            }
            else if (Blocks.ContainsKey(BlockHeader.MAGIC_MODEL3))
            {
                mdl = Blocks[BlockHeader.MAGIC_MODEL3] as MDLBlock;
            }
            else
            {
                throw new Exception("No supported MDL block found.");
            }

            GeometryBlock geo;// = Blocks[BlockHeader.MAGIC_GEOMETRY2] as GeometryBlock;

            if (Blocks.ContainsKey(BlockHeader.MAGIC_GEOMETRY1))
            {
                geo = Blocks[BlockHeader.MAGIC_GEOMETRY1] as GeometryBlock;
            }
            else if (Blocks.ContainsKey(BlockHeader.MAGIC_GEOMETRY2))
            {
                geo = Blocks[BlockHeader.MAGIC_GEOMETRY2] as GeometryBlock;
            }
            else
            {
                throw new Exception("No supported GEO block found.");
            }

            using (StreamWriter matwriter = new StreamWriter(Path.ChangeExtension(filename, ".mtl")))
                using (StreamWriter writer = new StreamWriter(filename))
                {
                    writer.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(filename) + ".mtl");

                    int m            = 0;
                    int vertexOffset = 0;
                    foreach (GeometryBlock.LOD lod in geo.LODs)
                    {
                        writer.WriteLine("g LOD" + lod.Type.ToString());
                        foreach (RenderGroup group in lod.RenderGroups)
                        {
                            // Write a new material
                            MaterialProps mat = mdl.Materials[group.Material];
                            matwriter.WriteLine("newmtl " + Path.GetFileNameWithoutExtension(filename) + "_" + m);
                            matwriter.WriteLine("Ka " + (mat.Ambient.X + mat.Emissive.X) + " " + (mat.Ambient.Y + mat.Emissive.Y) + " " + (mat.Ambient.Z + mat.Emissive.Z));
                            matwriter.WriteLine("Kd " + mat.Diffuse.X + " " + mat.Diffuse.Y + " " + mat.Diffuse.Z);
                            matwriter.WriteLine("Ks " + mat.Specular.X + " " + mat.Specular.Y + " " + mat.Specular.Z);
                            matwriter.WriteLine("Ns " + mat.Shininess);
                            matwriter.WriteLine("d " + (1.0f - mat.Transparency));

                            foreach (TextureBlend blend in group.TextureBlends)
                            {
                                if (blend.Effect == Texture.MapType.Base)
                                {
                                    matwriter.WriteLine("map_Kd " + Path.GetFileName(mdl.TextureReferences[blend.TextureIndex].MapName));
                                    // Write Texture
                                    if (Program.Filesystem != null)
                                    {
                                        using (MemoryStream ms = new MemoryStream(Program.Filesystem.GetFileData(Program.Filesystem.GetFileEntry(mdl.TextureReferences[blend.TextureIndex].MapName.Replace(".tga", ".PC TEXTURE")))))
                                            using (BinaryReader texReader = new BinaryReader(ms))
                                            {
                                                Texture tex = new Texture(texReader);
                                                tex.DumpTGA(Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(mdl.TextureReferences[blend.TextureIndex].MapName)) + ".tga");
                                            }
                                    }
                                }
                            }

                            writer.WriteLine("usemtl " + Path.GetFileNameWithoutExtension(filename) + "_" + m);
                            writer.WriteLine("o LOD" + lod.Type.ToString() + "_group" + lod.RenderGroups.IndexOf(group));

                            // Write vertices
                            for (int v = 0; v < group.VertexCount; v++)
                            {
                                writer.WriteLine("v " + (Context.Current.Game == Context.NextGenGame.LegoRacers2 ? -1.0f : 1.0f) * ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.PositionOffset) + " " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.PositionOffset + 4) + " " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.PositionOffset + 8));
                                writer.WriteLine("vn " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.NormalOffset) + " " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.NormalOffset + 4) + " " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.NormalOffset + 8));
                                writer.WriteLine("vt " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.UVOffset) + " " + ParseFloat(group.VertexBuffer.VertexData, v * (int)group.VertexBuffer.VertexSize + (int)group.VertexBuffer.UVOffset + 4));
                            }

                            for (int i = 0; i < group.IndexBuffer.IndexCount; i += 3)
                            {
                                int i1 = BitConverter.ToUInt16(group.IndexBuffer.IndexData, i * 2) + vertexOffset + 1;
                                int i2 = BitConverter.ToUInt16(group.IndexBuffer.IndexData, i * 2 + 2) + vertexOffset + 1;
                                int i3 = BitConverter.ToUInt16(group.IndexBuffer.IndexData, i * 2 + 4) + vertexOffset + 1;

                                /*if (Context.Current.Game == Context.NextGenGame.LegoRacers2)
                                 * {
                                 *  // Flip the order of the indices
                                 *  int temp = i1;
                                 *  i1 = i2;
                                 *  i2 = i3;
                                 *  i3 = temp;
                                 * }*/
                                writer.WriteLine("f " + i1 + "/" + i1 + "/" + i1 + " " + i2 + "/" + i2 + "/" + i2 + " " + i3 + "/" + i3 + "/" + i3);
                            }

                            vertexOffset += group.VertexCount;
                            m++;
                        }
                    }
                }
        }
예제 #2
0
        public void ExportOBJ(string filename)
        {
            using (System.IO.StreamWriter objWriter = new StreamWriter(filename, false))
                using (System.IO.StreamWriter mtlWriter = new StreamWriter(Path.ChangeExtension(filename, ".mtl"), false))
                {
                    objWriter.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(filename) + ".mtl");

                    HashSet <string> writtenMaterials = new HashSet <string>();

                    int vertexOffset = 0;

                    foreach (RenderGroup rg in this.RenderGroups)
                    {
                        TextureBlend baseTexture  = rg.TextureBlends.First(tb => tb.Effect == Texture.MapType.Base);
                        string       texturePath  = BitmapIndices[baseTexture.TextureIndex].MapName;
                        string       materialName = Path.GetFileNameWithoutExtension(texturePath);

                        // Create the material if it's the first time it's being used
                        if (!writtenMaterials.Contains(materialName))
                        {
                            mtlWriter.WriteLine("newmtl " + materialName);
                            MaterialProps mat = this.MaterialIndices[rg.Material];
                            mtlWriter.WriteLine("Ka " + (mat.Ambient.X + mat.Emissive.X) + " " + (mat.Ambient.Y + mat.Emissive.Y) + " " + (mat.Ambient.Z + mat.Emissive.Z));
                            mtlWriter.WriteLine("Kd " + mat.Diffuse.X + " " + mat.Diffuse.Y + " " + mat.Diffuse.Z);
                            mtlWriter.WriteLine("Ks " + mat.Specular.X + " " + mat.Specular.Y + " " + mat.Specular.Z);
                            mtlWriter.WriteLine("Ns " + mat.Shininess);
                            mtlWriter.WriteLine("d " + (1.0f - mat.Transparency));

                            // Write Texture
                            if (Program.Filesystem != null)
                            {
                                if (texturePath.EndsWith(".tga"))
                                {
                                    mtlWriter.WriteLine("map_Kd " + Path.GetFileName(texturePath));
                                    using (MemoryStream ms = new MemoryStream(Program.Filesystem.GetFileData(Program.Filesystem.GetFileEntry(texturePath.Replace(".tga", "." + Context.Current.Platform.ToString() + " TEXTURE")))))
                                        using (BinaryReader texReader = new BinaryReader(ms))
                                        {
                                            Texture tex = new Texture(texReader);
                                            tex.DumpTGA(Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(texturePath)) + ".tga");
                                        }
                                }
                                else if (texturePath.EndsWith(".ifl"))
                                {
                                    using (MemoryStream iflMs = new MemoryStream(Program.Filesystem.GetFileData(Program.Filesystem.GetFileEntry(texturePath))))
                                    {
                                        IFLFile ifl = new IFLFile(iflMs, texturePath);
                                        mtlWriter.WriteLine("map_Kd " + Path.GetFileName(ifl.Frames[0].TextureFilename));
                                        using (MemoryStream ms = new MemoryStream(Program.Filesystem.GetFileData(Program.Filesystem.GetFileEntry(Path.Combine(Path.GetDirectoryName(texturePath), ifl.Frames[0].TextureFilename.Replace(".tga", "." + Context.Current.Platform.ToString() + " TEXTURE"))))))
                                            using (BinaryReader texReader = new BinaryReader(ms))
                                            {
                                                Texture tex = new Texture(texReader);
                                                tex.DumpTGA(Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(ifl.Frames[0].TextureFilename)) + ".tga");
                                            }
                                    }
                                }
                            }
                        }

                        objWriter.WriteLine("usemtl " + materialName);

                        // Write vertices
                        for (int v = 0; v < rg.VertexCount; v++)
                        {
                            objWriter.WriteLine("v " + (Context.Current.Game == Context.NextGenGame.LegoRacers2 ? -1.0f : -1.0f) * ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.PositionOffset) + " " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.PositionOffset + 4) + " " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.PositionOffset + 8));
                            objWriter.WriteLine("vn " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.NormalOffset) + " " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.NormalOffset + 4) + " " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.NormalOffset + 8));
                            objWriter.WriteLine("vt " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.UVOffset) + " " + ParseFloat(rg.VertexBuffer.VertexData, v * (int)rg.VertexBuffer.VertexSize + (int)rg.VertexBuffer.UVOffset + 4));
                        }

                        for (int i = 0; i < rg.IndexBuffer.IndexCount; i += 3)
                        {
                            int i1 = BitConverter.ToUInt16(rg.IndexBuffer.IndexData, i * 2) + vertexOffset + 1;
                            int i2 = BitConverter.ToUInt16(rg.IndexBuffer.IndexData, i * 2 + 2) + vertexOffset + 1;
                            int i3 = BitConverter.ToUInt16(rg.IndexBuffer.IndexData, i * 2 + 4) + vertexOffset + 1;

                            /*if (Context.Current.Game == Context.NextGenGame.LegoRacers2)
                             * {
                             *  // Flip the order of the indices
                             *  int temp = i1;
                             *  i1 = i2;
                             *  i2 = i3;
                             *  i3 = temp;
                             * }*/
                            objWriter.WriteLine("f " + i1 + "/" + i1 + "/" + i1 + " " + i2 + "/" + i2 + "/" + i2 + " " + i3 + "/" + i3 + "/" + i3);
                        }

                        vertexOffset += rg.VertexCount;
                    }
                }
        }