Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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;
        }