public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var name              = value.ToString();
        var verbalNameParts   = name.Split(BrushMap.Select(item => item.Key).ToArray(), StringSplitOptions.RemoveEmptyEntries);
        var colorKeyNameParts = name.Split(verbalNameParts, StringSplitOptions.RemoveEmptyEntries);

        if (verbalNameParts.Length != colorKeyNameParts.Length)
        {
            return(null);
        }
        var index = 0;
        var nameMappedToColors = new ObservableCollection <ServerNameParts>();

        verbalNameParts.ToList().ForEach(namePart =>
        {
            var brush = BrushMap.FirstOrDefault(item => item.Key == colorKeyNameParts[index]);
            if (brush == null)
            {
                return;
            }
            nameMappedToColors.Add(new ServerNameParts
            {
                NamePart      = namePart,
                NamePartBrush = brush.Brush,
            });
            index++;
        });

        return(new ServerNameObject {
            ServerNamePartsCollection = nameMappedToColors
        });
    }
Beispiel #2
0
 // clean up all resources
 public void CleanUpResource()
 {
     m_activeFile = null;
     m_assetDirContents.Clear();
     BrushMap.Clear();
     AssetMap.Clear();
 }
 void ParseEntity(BrushMap map, ref int line, List<string> lines)
 {
     int braceCt = 0;
     Entity entity = new Entity();
     map.Entities.Add(entity);
     for (; line < lines.Count; ++line)
     {
         string text = lines[line];
         string shortLine = text.Trim();
         string lowerLine = shortLine.ToLower();
         if (lowerLine.Contains("{"))
         {
             ++braceCt;
         }
         else if (lowerLine.Contains("}"))
         {
             --braceCt;
             if (braceCt == 0)
                 return;
         }
         else if (lowerLine.Equals("editor"))
         {
             // Skip Editor data
             SkipBraces(ref line, lines);
         }
         else if (braceCt == 1)
         {
             ParseProperty(shortLine, entity.Properties);
         }
     }
 }
        public override BrushMap ReadMap(string inputFile, Dictionary<string, string> settings)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(" Valve VMF Reader");
            Console.WriteLine("----------------------------------------------------------------");

            Vector3 scale = QMapConverter.Settings.MapScale;

            BrushMap map = new BrushMap();
            List<String> fileData = new List<String>(System.IO.File.ReadLines(inputFile));

            //using (QMapConverter.Util.ConsoleProgress prog = new QMapConverter.Util.ConsoleProgress("Loading map", fileData.Count))
            {
                for (int i = 0; i < fileData.Count; ++i)
                {
                    //prog.Increment();
                    //prog.Write();

                    string line = fileData[i];
                    string shortLine = fileData[i].Trim();
                    string shortLower = shortLine.ToLower();

                    if (shortLower.Equals("world"))
                        ParseWorld(map, ref i, fileData);
                    else if (shortLower.Equals("entity"))
                        ParseEntity(map, ref i, fileData);
                }
            }

            return map;
        }
 public override void WriteMap(string outputFile, BrushMap map)
 {
     using (StreamWriter writer = new StreamWriter(System.IO.File.Create(outputFile)))
     {
         foreach (Entity e in map.Entities)
             WriteEntity(writer, e);
     }
 }
        public override void WriteMap(BrushMap map)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(" Urho3D Model Writer");
            Console.WriteLine("----------------------------------------------------------------");

            SceneBuilder sb = new SceneBuilder(map, QMapConverter.Settings.CellSize);
            List<string> matlist = new List<string>();
            sb.WriteModel(outputFile, matlist);
        }
Beispiel #7
0
 public override void InitializeBrush()
 {
     for (int i = 1; i < BrushMap.GetLength(0) - 1; i++)
     {
         for (int j = 1; j < BrushMap.GetLength(1) - 1; j++)
         {
             BrushMap[i, j] = true;
         }
     }
 }
Beispiel #8
0
 public virtual void InitializeBrush()
 {
     for (int i = 0; i < BrushMap.GetLength(0); i++)
     {
         BrushMap[i, BrushMap.GetLength(1) / 2] = true;
     }
     for (int j = 0; j < BrushMap.GetLength(1); j++)
     {
         BrushMap[BrushMap.GetLength(0) / 2, j] = true;
     }
 }
 public static IEnumerable<List<Face>> FacesByTexture(BrushMap map)
 {
     List<Map.Face> AllFaces = new List<Map.Face>();
     foreach (Map.Entity e in map.Entities)
     {
         foreach (Map.Brush b in e.Brushes)
             AllFaces.AddRange(b.Faces);
     }
     Console.WriteLine("Sorting faces...");
     return AllFaces.GroupBy(p => p.TexName).Select(g => g.ToList());
 }
        public override void WriteMap(BrushMap map)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(" Quake Writer");
            Console.WriteLine("----------------------------------------------------------------");

            using (StreamWriter writer = new StreamWriter(System.IO.File.Create(outputFile)))
            {
                foreach (Entity e in map.Entities)
                    WriteEntity(writer, e);
            }
        }
Beispiel #11
0
 public override void InitializeBrush()
 {
     for (int i = 0; i < BrushMap.GetLength(0); i++)
     {
         for (int j = 0; j < BrushMap.GetLength(1); j++)
         {
             Color c = File.GetPixel(i, j);
             if (c.R != 255 || c.G != 0 || c.B != 0)
             {
                 BrushMap[i, j] = true;
             }
             else
             {
                 BrushMap[i, j] = false;
             }
         }
     }
 }
        public override BrushMap ReadMap(string inputFile, Dictionary<string, string> settings)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("Quake Reader 2");
            Console.WriteLine("----------------------------------------------------------------");

            Vector3 scale = QMapConverter.Settings.MapScale;

            Console.WriteLine(String.Format("Reading file: {0}", inputFile));
            BrushMap map = new BrushMap();
            List<String> fileData = new List<String>(System.IO.File.ReadLines(inputFile));
            int braceDepth = 0;

            Entity currentEntity = null;
            Brush currentBrush = null;
            Patch currentPatch = null;

            Console.Write("Map Load Progress...0/100%", 0 / fileData.Count);
            for (int lineNum = 0; lineNum < fileData.Count; ++lineNum)
            {
                string line = fileData[lineNum];
                float percentage = ((float)lineNum+1) / ((float)fileData.Count);
                percentage *= 100;
                Console.Write(String.Format("\rMap Load Progress...{0}/100%", Math.Floor(percentage)));
                string shortLine = line.Trim();

                // Skip over comment lines
                if (shortLine.StartsWith("//"))
                    continue;

                if (shortLine.CompareTo("{") == 0)
                {
                    ++lineNum;
                    ParseEntity(map, ref lineNum, fileData);
                }
            }
            Console.WriteLine(" ");
            Console.WriteLine("Map Load Complete");
            return map;
        }
 void ParseEntity(BrushMap map, ref int line, List<string> lines)
 {
     Entity entity = new Entity();
     int braceStack = 0;
     for (; line < lines.Count; ++line)
     {
         string text = lines[line];
         string shortLine = text.Trim();
         if (text.StartsWith("//"))
         {
             continue;
         }
         else if (lines[line].Contains("}"))
         {
             --braceStack;
             if (braceStack < 0)
                 break;
         } else if (lines[line].Contains("{")) {
             ++braceStack;
         }
         else if (shortLine.Contains("curve") || shortLine.Contains("patch") || shortLine.Contains("mesh"))
         {
             ParsePatch(entity, ref line, lines);
         }
         else if (braceStack > 0) {
             ParseBrush(entity, ref line, lines);
         }
         else
         {
             string[] terms = text.Split(PROPERTY_SPLIT_CHARS, StringSplitOptions.RemoveEmptyEntries);
             if (terms.Length == 2)
                 entity.Properties[terms[0].Trim()] = terms[1].Trim();
             else
                 entity.Properties[terms[0].Trim()] = "true";
         }
     }
     map.Entities.Add(entity);
 }
        public override BrushMap ReadMap(string inputFile, Dictionary<string, string> settings)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(" Quake Reader");
            Console.WriteLine("----------------------------------------------------------------");

            Vector3 scale = new Vector3(1,1,1);

            if (settings.ContainsKey("scale"))
                scale = QMapConverter.Util.MathExt.Vector3FromString(settings["scale"]);

            BrushMap map = new BrushMap();
            List<String> fileData = new List<String>(System.IO.File.ReadLines(inputFile));
            int braceDepth = 0;
            int lineNum = 0;

            Entity currentEntity = null;
            Brush currentBrush = null;
            Patch currentPatch = null;

            using (QMapConverter.Util.ConsoleProgress prog = new QMapConverter.Util.ConsoleProgress("Loading Map", fileData.Count))
            foreach (string line in fileData)
            {
                ++lineNum;
                prog.Increment();
                prog.Write();
                string shortLine = line.Trim();

                // Skip over comment lines
                if (shortLine.StartsWith("//"))
                    continue;

                if (shortLine.CompareTo("{") == 0)
                {
                    ++braceDepth;
                    if (braceDepth == 1)
                        currentEntity = new Entity();
                    else if (braceDepth == 2)
                        currentBrush = new Brush();
                }
                else if (shortLine.CompareTo("}") == 0)
                {
                    --braceDepth;
                    if (braceDepth == 0 && currentEntity != null)
                    {
                        map.Entities.Add(currentEntity);
                        currentEntity = null;
                    }
                    else if (braceDepth == 1 && (currentBrush != null || currentPatch != null) && currentEntity != null)
                    {
                        if (currentBrush != null)
                        {
                            currentEntity.Brushes.Add(currentBrush);
                            currentBrush = null;
                        }
                        else if (currentPatch != null)
                        {
                            currentEntity.Patches.Add(currentPatch);
                            currentPatch = null;
                        }
                    }
                }
                else
                {
                    if (currentBrush != null)
                    {
                        if (shortLine.ToLower().Equals("curve") || shortLine.ToLower().Contains("patchdef") || shortLine.ToLower().Equals("mesh"))
                        {
                            // Cancel the brush, it's either a patch or a mesh
                            currentBrush = null;
                            currentPatch = new Patch(shortLine.ToLower().Equals("mesh"));
                            continue;
                        }
                        //try
                        {
                            if (!shortLine.Contains('('))
                                continue;
                            Face face = new Face(shortLine, scale);
                            currentBrush.Faces.Add(face);
                        }
                        //catch (Exception ex)
                        //{
                        //    Console.WriteLine(String.Format("ERROR: line {0}", lineNum));
                        //    Console.WriteLine(ex.Message);
                        //    Environment.FailFast("Map Parse Error");
                        //    return null;
                        //}
                    }
                    else if (currentPatch != null)
                    {
                        int termCt = shortLine.Split(SPLIT_CHARS, StringSplitOptions.RemoveEmptyEntries).Count();
                        if (currentPatch.Columns == -1 && termCt == 5 || termCt == 4)
                        {
                            string[] terms = shortLine.Split(SPLIT_CHARS, StringSplitOptions.RemoveEmptyEntries);
                            currentPatch.Rows = int.Parse(terms[0]);
                            currentPatch.Columns = int.Parse(terms[1]);
                        }
                        else if (termCt == 1 && currentPatch.TextureName.Length == 0)
                        {
                            currentPatch.TextureName = shortLine;
                        }
                        else
                        {
                            // Characters on which to split
                            char[] PATCH_SPLIT = { ' ', 'v', 't', 'c', '(', ')' };
                            string[] terms = shortLine.Split(PATCH_SPLIT, StringSplitOptions.RemoveEmptyEntries);
                            if (terms.Length > 0)
                            {
                                // Id format
                                if (shortLine.Count(c => c == '(') > 0)
                                {
                                    List<PatchVert> rowVerts = new List<PatchVert>();
                                    // ( (x y z u v) (x y z u v) (x y z u v) )
                                    for (int i = 0; i < currentPatch.Columns; ++i)
                                    {
                                        PatchVert vert = new PatchVert();
                                        int startSub = i * 5;
                                        // (x y z u v)
                                        vert.Position = Face.ParseVec3(terms, startSub);
                                        vert.UV = Face.ParseVec2(terms, startSub + 3);
                                        rowVerts.Add(vert);
                                        currentPatch.FlatVertices.Add(vert);
                                    }
                                    currentPatch.PatchVertices.Add(rowVerts);
                                }
                                // Treyarch format
                                else if (shortLine.Contains('v'))
                                {
                                    PatchVert vert = new PatchVert();
                                    vert.Position = Face.ParseVec3(terms, 0);
                                    // If we contain a color
                                    if (shortLine.Contains('c'))
                                    {
                                        vert.Color = Face.ParseVec3(terms, 3);
                                        vert.Alpha = float.Parse(terms[6]);
                                        vert.UV = Face.ParseVec2(terms, 7);
                                    }
                                    else
                                        vert.UV = Face.ParseVec2(terms, 3);
                                    currentPatch.FlatVertices.Add(vert);
                                }
                            }
                        }
                    }
                    else if (currentEntity != null)
                    {
                        // Brush Primitives - GtkRadiant format
                        if (shortLine.ToLower().Equals("brushdef"))
                        {
                            currentEntity.Kind = EntityType.Brush;
                        }
                        // Patch
                        else if (shortLine.ToLower().Equals("patchdef2") || shortLine.ToLower().Equals("curve"))
                        {
                            currentEntity.Kind = EntityType.Patch;
                        }
                        else if (shortLine.ToLower().Equals("mesh"))
                        {
                            currentEntity.Kind = EntityType.Mesh;
                        }
                        else
                        {
                            Regex regex = new Regex(@"\w+|""[\w\s]*""");
                            List<string> terms = new List<string>(shortLine.Split('"').ToList());
                            for (int i = 0; i < terms.Count; ++i)
                            {
                                if (String.IsNullOrWhiteSpace(terms[i]))
                                {
                                    terms.RemoveAt(i);
                                    --i;
                                }
                            }

                            // Insert KvP properties, if a Value is non-existent, insert 'true' as it's likely a flag
                            if (terms.Count == 2)
                                currentEntity.Properties[terms[0].Replace("\"", "")] = terms[1].Replace("\"", "");
                            else
                                currentEntity.Properties[terms[0].Replace("\"", "")] = "true";
                        }
                    }
                }
            }
            return map;
        }
        public override void WriteMap(string outputFile, BrushMap map)
        {
            int brushCount = 0;
            int patchCount = 0;
            int meshCount = 0;
            int faceCount = 0;
            int vertCount = 0;
            int triCount = 0;
            Dictionary<string, int> textures = new Dictionary<string,int>();
            foreach (Entity e in map.Entities)
            {
                foreach (Brush b in e.Brushes)
                {
                    brushCount++;
                    faceCount += b.Faces.Count;
                    foreach (Face f in b.Faces)
                    {
                        vertCount += f.Vertices.Count;
                        if (textures.ContainsKey(f.TexName))
                            textures[f.TexName] = textures[f.TexName] + 1;
                        else
                            textures[f.TexName] = 1;
                        triCount += f.Indices.Count / 3;
                    }
                }
                foreach (Patch p in e.Patches)
                {
                    if (p.LiteralMesh)
                        meshCount++;
                    else
                        patchCount++;
                    vertCount += p.Columns * p.Rows;
                    triCount += p.Columns * p.Rows * 2;
                    if (textures.ContainsKey(p.TextureName))
                        textures[p.TextureName] = textures[p.TextureName] + 1;
                    else
                        textures[p.TextureName] = 1;
                }
            }

            int texOnce = 0;
            int texMany = 0;
            foreach (string s in textures.Keys)
            {
                if (textures[s] > 1)
                    texMany++;
                else
                    texOnce++;
            }

            Console.WriteLine("Map Info:");
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("GEOMETRY");
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(String.Format("  {0} entities", map.Entities.Count));
            Console.WriteLine(String.Format("  {0} brushes", brushCount));
            Console.WriteLine(String.Format("        {0} faces", faceCount));
            Console.WriteLine(String.Format("  {0} patches", patchCount));
            Console.WriteLine(String.Format("  {0} meshes", meshCount));
            Console.WriteLine(String.Format("  {0} vertices", vertCount));
            Console.WriteLine(String.Format("  {0} triangles", triCount));
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("TEXTURES");
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(String.Format("  {0} Total Textures", textures.Keys.Count));
            Console.WriteLine(String.Format("  {0} Reused", texMany));
            Console.WriteLine(String.Format("  {0} Unique", texOnce));
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("MEMORY ESTIMATE");
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(String.Format("  {0} Vertices", GetFileSizeString(vertCount * sizeof(float) * 5)));
            Console.WriteLine(String.Format("  {0} Indices", GetFileSizeString(triCount * 3 * sizeof(short))));
            Console.WriteLine(String.Format("  {0} All Geometry", GetFileSizeString(vertCount * sizeof(float) * 5 + triCount * 3 * sizeof(short))));
            Console.WriteLine(String.Format("  {0} Textures", map.Entities.Count));
        }
        public override void WriteMap(BrushMap map)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine(" Urho3D Prefab Writer");
            Console.WriteLine("----------------------------------------------------------------");

            Console.WriteLine("Building material database");
            MaterialDatabase matDb = new MaterialDatabase(Settings.ContentDir);

            Scene scene = new Scene("node");
            Node entRoot = scene.CreateChild("Entities");

            // Write 'void' entity nodes
            using (QMapConverter.Util.ConsoleProgress prog = new QMapConverter.Util.ConsoleProgress("Writing entities", map.Entities.Count))
                for (int i = 0; i < map.Entities.Count; ++i)
                {
                    prog.Increment();
                    prog.Write();
                    Entity entity = map.Entities[i];
                    if (entity.Brushes.Count == 0)
                    {
                        Node brushNode = entRoot.CreateChild();
                        brushNode.WriteVariables(entity.Properties);
                    }
                }

            // Write world geometry elements
            Node geoNode = scene.CreateChild("Geometry");

            string outputPath = System.IO.Path.Combine(Settings.ContentDir, "Data");
            outputPath = System.IO.Path.Combine(outputPath, "Models");
            outputPath = System.IO.Path.Combine(outputPath, System.IO.Path.GetFileNameWithoutExtension(outputFile));
            outputPath = System.IO.Path.Combine(outputPath, "geo.mdl");

            SceneBuilder sb = new SceneBuilder(map, QMapConverter.Settings.CellSize);
            List<string> materials = new List<string>();
            sb.WriteModel(outputPath, materials);

            using (QMapConverter.Util.ConsoleProgress prog = new QMapConverter.Util.ConsoleProgress("Writing geometry", map.Entities.Count))
            {
                Component staticModel = geoNode.CreateComponent("StaticModel");
                string relPath = outputPath.Replace(Settings.ContentDir + "\\", "").Replace("\\","/");
                staticModel.SetAttribute("Model", String.Format("Model;{0}", relPath));
                StringBuilder matString = new StringBuilder();
                foreach (string m in materials)
                {
                    string matFile = matDb.GetMaterial(m);
                    if (matFile != null && matFile.Length > 0)
                    {
                        if (matString.Length > 0)
                            matString.AppendFormat(";Material;{0}", matFile);
                        else
                            matString.AppendFormat("Material;{0}", matFile);
                    }
                }
                if (matString.Length > 0)
                    staticModel.SetAttribute("Material", matString.ToString());
            }

            using (QMapConverter.Util.ConsoleProgress prog = new QMapConverter.Util.ConsoleProgress("Writing file", map.Entities.Count))
                scene.Save(outputFile);

            Console.WriteLine("File written: " + outputFile);
        }
 public override void WriteMap(string outputFile, BrushMap map)
 {
     SceneBuilder sb = new SceneBuilder(map, Settings.CellSize);
     sb.WriteScene(outputFile, Settings.ContentDir, "entity");
 }
        void ParseWorld(BrushMap map, ref int line, List<string> lines)
        {
            int braceDepth = 0;
            Entity worldEntity = new Entity();
            map.Entities.Add(worldEntity);

            for (; line < lines.Count; ++line)
            {
                string text = lines[line];
                string shortLine = text.Trim();
                string lowerLine = shortLine.ToLower();

                if (lowerLine.Contains("{"))
                    ++braceDepth;
                else if (lowerLine.Contains("}"))
                {
                    --braceDepth;
                    if (braceDepth == 0)
                        return;
                }
                else if (lowerLine.Equals("solid")) // Accept solid objects
                    ParseSolid(worldEntity, ref line, lines);
                else if (lowerLine.Equals("hidden")) // Ignore hidden objects?
                    SkipBraces(ref line, lines);
                else if (lowerLine.Equals("group")) // Ignore groups, they're about editor function
                    SkipBraces(ref line, lines);
                else if (braceDepth == 1) // Scene level properties
                    ParseProperty(shortLine, map.SceneProperties);
            }
        }
        public override void WriteMap(BrushMap map)
        {
            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("OBJ Writer");
            Console.WriteLine("----------------------------------------------------------------");

            using (StreamWriter stream = new StreamWriter(System.IO.File.Create(outputFile), UTF8Encoding.UTF8))
            {
                IEnumerable<List<Map.Face>> SortedFaces = Sorting.TexSort.FacesByTexture(map);
                int GroupCt = 0;
                foreach (List<Map.Face> faces in SortedFaces)
                    ++GroupCt;

                // Write "objects" to OBJ
                int CurrentIdx = 0;
                List<Brush> brushes = new List<Brush>();
                foreach (Entity e in map.Entities)
                    brushes.AddRange(e.Brushes);
                using (ConsoleProgress modelProgress = new ConsoleProgress(String.Format("Writing Meshes", CurrentIdx), SortedFaces.Count()))
                {
                    int indexStart = 1;

                    //foreach (Brush b in brushes)
                    foreach (List<Map.Face> faces in SortedFaces)
                    {
                        //List<Face> faces = b.Faces;
                        ++CurrentIdx;
                        modelProgress.Increment();
                        modelProgress.Write();

                        stream.Write(String.Format("o Mesh{0}\n", CurrentIdx));

                        int FaceCount = Map.Face.CountFaces(faces);

                        // Vertex Positions
                        foreach (Map.Face face in faces)
                        {
                            foreach (Vector3 vert in face.Vertices)
                            {
                                WriteVec3(stream, "v", vert);
                            }
                        }

                        // Texture Coordinates
                        foreach (Map.Face face in faces)
                        {
                            foreach (Vector3 vert in face.Vertices)
                            {
                                WriteVec2(stream, "vt", face.GetTexCoord(vert));
                            }
                        }

                        // Vertex Normals
                        foreach (Map.Face face in faces)
                        {
                            Vector3 norm = face.GetNormal();
                            if (Settings.FlipNormals)
                                norm = Vector3.Multiply(norm, -1);
                            foreach (Vector3 vert in face.Vertices)
                            {
                                WriteVec3(stream, "vn", norm);
                            }
                        }

                        foreach (Map.Face face in faces)
                        {
                            for (int i = 0; i < face.Indices.Count; i += 3)
                            {
                                stream.Write("f {0} {1} {2}\n",
                                    indexStart + face.Indices[i],
                                    indexStart + face.Indices[i + 1],
                                    indexStart + face.Indices[i + 2]);
                            }
                            indexStart += face.Vertices.Count;
                        }
                    }

                    List<Patch> patches = new List<Patch>();
                    foreach (Entity e in map.Entities)
                    {
                        foreach (Patch patch in e.Patches)
                        {
                            if (!patch.LiteralMesh && (patch.Columns > 3 || patch.Rows > 3))
                                patch.GenerateQuilt(patches);
                            else
                                patches.Add(patch);
                        }
                    }

                    int currentPatch = 0;
                    foreach (Patch p in patches)
                    {
                        ++currentPatch;
                        if (p.LiteralMesh || p.Columns > 3 || p.Rows > 3)
                        {
                            stream.Write(String.Format("o ExplicitMesh{0}\n", currentPatch));
                            for (int x = 0; x < p.Columns; ++x)
                            {
                                for (int y = 0; y < p.Rows; ++y)
                                {
                                    PatchVert vert = p.FlatVertices[x + y * p.Columns];
                                    stream.Write(String.Format("v {0} {1} {2}\n",
                                        vert.Position.X * -1,
                                        vert.Position.Y,
                                        vert.Position.Z * -1));
                                }
                            }
                            for (int x = 0; x < p.Columns; ++x)
                            {
                                for (int y = 0; y < p.Rows; ++y)
                                {
                                    PatchVert vert = p.FlatVertices[x + y * p.Columns];
                                    stream.Write(String.Format("vt {0} {1}\n", vert.UV.X, vert.UV.Y));
                                }
                            }
                            p.BuildIndices();
                            for (int i = 0; i < p.index.Count; i += 3)
                            {
                                stream.Write(String.Format("f {0} {1} {2}\n",
                                    ((ushort)indexStart + p.index[i]),
                                    ((ushort)indexStart + p.index[i + 1]),
                                    ((ushort)indexStart + p.index[i + 2])));
                            }
                            indexStart += p.FlatVertices.Count;
                        }
                        else
                        {
                            stream.Write(String.Format("o Patch{0}\n", currentPatch));
                            p.Generate(6);
                            for (int i = 0; i < p.vertex.Count; ++i)
                            {
                                stream.Write(String.Format("v {0} {1} {2}\n",
                                    p.vertex[i].X * -1,
                                    p.vertex[i].Y,
                                    p.vertex[i].Z * -1));
                            }
                            for (int i = 0; i < p.uvs.Count; ++i)
                            {
                                stream.Write(String.Format("vt {0} {1}\n", p.uvs[i].X, p.uvs[i].Y));
                            }
                            for (int i = 0; i < p.index.Count; i += 3)
                            {
                                stream.Write(String.Format("f {0} {1} {2}\n",
                                    ((ushort)indexStart + p.index[i]),
                                    ((ushort)indexStart + p.index[i + 1]),
                                    ((ushort)indexStart + p.index[i + 2])));
                            }
                            indexStart += p.vertex.Count;
                        }
                    }
                }

                stream.Flush();
            }
        }
        public override void WriteMap(string outputFile, BrushMap map)
        {
            using (StreamWriter stream = new StreamWriter(System.IO.File.Create(outputFile), UTF8Encoding.UTF8))
            {
                List<Map.Face> AllFaces = new List<Map.Face>();
                foreach (Map.Entity e in map.Entities)
                {
                    foreach (Map.Brush b in e.Brushes)
                        AllFaces.AddRange(b.Faces);
                }

                Console.WriteLine("Sorting faces...");
                IEnumerable<List<Map.Face>> SortedFaces = AllFaces.GroupBy(p => p.TexName).Select(g => g.ToList());
                int GroupCt = 0;
                foreach (List<Map.Face> faces in SortedFaces)
                    ++GroupCt;

                // Write "objects" to OBJ
                int CurrentIdx = 0;
                List<Brush> brushes = new List<Brush>();
                foreach (Entity e in map.Entities)
                    brushes.AddRange(e.Brushes);
                using (ConsoleProgress modelProgress = new ConsoleProgress(String.Format("Writing Meshes", CurrentIdx), SortedFaces.Count()))
                {
                    int indexStart = 1;

                    foreach (Brush b in brushes)
                    //foreach (List<Map.Face> faces in SortedFaces)
                    {
                        List<Face> faces = b.Faces;
                        ++CurrentIdx;
                        modelProgress.Increment();
                        modelProgress.Write();

                        stream.Write(String.Format("o Mesh{0}\n", CurrentIdx));

                        int FaceCount = Map.Face.CountFaces(faces);

                        // Vertex Positions
                        foreach (Map.Face face in faces)
                        {
                            foreach (Vector3 vert in face.Vertices)
                            {
                                WriteVec3(stream, "v", vert);
                            }
                        }

                        // Texture Coordinates
                        foreach (Map.Face face in faces)
                        {
                            foreach (Vector3 vert in face.Vertices)
                            {
                                WriteVec2(stream, "vt", face.GetTexCoord(vert));
                            }
                        }

                        // Vertex Normals
                        foreach (Map.Face face in faces)
                        {
                            Vector3 norm = face.GetNormal().Multiply(-1);
                            foreach (Vector3 vert in face.Vertices)
                            {
                                WriteVec3(stream, "vn", norm);
                            }
                        }

                        foreach (Map.Face face in faces)
                        {
                            for (int i = 0; i < face.Indices.Count; i += 3)
                            {
                                stream.Write("f {0} {1} {2}\n",
                                    indexStart + face.Indices[i],
                                    indexStart + face.Indices[i + 1],
                                    indexStart + face.Indices[i + 2]);
                            }
                            indexStart += face.Vertices.Count;
                        }
                    }

                    List<Patch> patches = new List<Patch>();
                    foreach (Entity e in map.Entities)
                    {
                        foreach (Patch patch in e.Patches)
                            patches.Add(patch);
                    }

                    int currentPatch = 0;
                    //foreach (Patch p in patches)
                    //{
                    //    ++currentPatch;
                    //    stream.Write(String.Format("o Patch{0}\n", currentPatch));
                    //    if (p.LiteralMesh)
                    //    {
                    //        for (int x = 0; x < p.Columns; ++x)
                    //        {
                    //            for (int y = 0; y < p.Rows; ++y)
                    //            {
                    //                PatchVert vert = p.FlatVertices[x + y * p.Columns];
                    //                stream.Write(String.Format("v {0} {1} {2}\n", vert.Position.X, vert.Position.Y, vert.Position.Z));
                    //            }
                    //        }
                    //        for (int x = 0; x < p.Columns; ++x)
                    //        {
                    //            for (int y = 0; y < p.Rows; ++y)
                    //            {
                    //                PatchVert vert = p.FlatVertices[x + y * p.Columns];
                    //                stream.Write(String.Format("vt {0} {1}\n", vert.UV.X, vert.UV.Y));
                    //            }
                    //        }
                    //        p.BuildIndices();
                    //        for (int i = 0; i < p.index.Count; i += 3)
                    //        {
                    //            stream.Write(String.Format("f {0} {1} {2}\n",
                    //                ((ushort)indexStart + p.index[i]),
                    //                ((ushort)indexStart + p.index[i + 1]),
                    //                ((ushort)indexStart + p.index[i + 2])));
                    //        }
                    //        indexStart += p.index.Count;
                    //    } else {
                    //        p.Generate(1);
                    //        for (int i = 0; i < p.vertex.Count; ++i)
                    //        {
                    //            stream.Write(String.Format("v {0} {1} {2}\n", p.vertex[i].X, p.vertex[i].Y, p.vertex[i].Z));
                    //        }
                    //        for (int i = 0; i < p.uvs.Count; ++i)
                    //        {
                    //            stream.Write(String.Format("vt {0} {1}\n", p.uvs[i].X, p.uvs[i].Y));
                    //        }
                    //        for (int i = 0; i < p.index.Count; i += 3)
                    //        {
                    //            stream.Write(String.Format("f {0} {1} {2}\n",
                    //                ((ushort)indexStart + p.index[i]),
                    //                ((ushort)indexStart + p.index[i + 1]),
                    //                ((ushort)indexStart + p.index[i + 2])));
                    //        }
                    //    }
                    //}
                }

                stream.Flush();
            }
        }
 public override void WriteMap(string outputFile, BrushMap map)
 {
     throw new NotImplementedException();
 }
 public override void WriteMap(string outputFile, BrushMap map)
 {
     SceneBuilder sb = new SceneBuilder(map, QMapConverter.Settings.CellSize);
     sb.WriteModel(outputFile, QMapConverter.Settings.MaterialSourceDir);
 }