Пример #1
0
        private void LoadBrushes(DirManager meshesDir, DirManager levelDir, List <VertexPositionColor> vertices,
                                 List <VertexPositionColor> collisionVertices, List <VertexPositionColor> lineVertices)
        {
            var brushlst = LevelLoadHelper.CreateBrushLstLoader(levelDir, "brush.lst");

            if (brushlst != null)
            {
                var cgfMap = LevelLoadHelper.CreateBrushLstCgfLoaderMap(meshesDir, brushlst);

                foreach (var brush in brushlst.brushEntries)
                {
                    CgfLoader cgf;
                    if (!cgfMap.TryGetValue(brush.meshIdx, out cgf))
                    {
                        continue;
                    }

                    //Debug.WriteLine("*Brush: " + cgf.m_path);
                    //Debug.WriteLine($"  entryIdx:{brush.entryIdx} meshIdx:{brush.meshIdx} pos:{brush.position} brRotMat:{brush.rotationMatrix}");

                    Matrix brushMatrix = LevelLoadHelper.GetBrushMatrix(brush);
                    DrawCgfInWorld(cgf, ref brushMatrix, brush.position, CgfDrawStyle.Brush, vertices, collisionVertices, lineVertices);
                }
            }
        }
Пример #2
0
        // generates navmesh data for the selected levels.
        public static void GenerateAllNav(WorldIdXmlLoader worldIdXmlLoader,
                                          DirManager meshesDir, DirManager levelsDir, string levelId,
                                          bool skipExistingNav, string outputPath)
        {
            int curFolderIndex = -1;

            foreach (var pairs in worldIdXmlLoader.FolderNamesById)
            {
                curFolderIndex++;

                string clientLevelId = pairs.Key;
                string levelFolder   = pairs.Value;

                if (!string.IsNullOrEmpty(levelId) && levelId != clientLevelId)
                {
                    // skip excluded
                    continue;
                }

                string outputNavFilename = Path.Combine(outputPath, clientLevelId + ".nav");

                if (skipExistingNav && File.Exists(outputNavFilename))
                {
                    Console.WriteLine($"    ** Skipping (already exists): {clientLevelId} - {levelFolder}");
                    continue;
                }


                Console.WriteLine($"    Loading meshes for {clientLevelId} - {levelFolder}");

                var LEVEL_TIME = DateTime.Now;
                var TIMER      = DateTime.Now;
                var geoSpace   = new GeoSpace();

                // brushes
                var brushlst = LevelLoadHelper.CreateBrushLstLoader(levelsDir,
                                                                    Path.Combine(levelFolder, "brush.lst"));
                if (brushlst != null)
                {
                    var cgfMap = LevelLoadHelper.CreateBrushLstCgfLoaderMap(meshesDir, brushlst);

                    foreach (var brush in brushlst.brushEntries)
                    {
                        CgfLoader cgf;
                        if (!cgfMap.TryGetValue(brush.meshIdx, out cgf))
                        {
                            continue;
                        }

                        Matrix brushMatrix = LevelLoadHelper.GetBrushMatrix(brush);
                        AddCgfToWorld(cgf, ref brushMatrix, brush.position, geoSpace);
                    }
                }

                // objects
                var ctx = LevelLoadHelper.LoadObjectsLst(meshesDir, levelsDir, levelFolder);
                if (ctx != null)
                {
                    foreach (var o in ctx.objects)
                    {
                        CgfLoader cgf;
                        if (!ctx.cgfMap.TryGetValue(o.ObjectId, out cgf))
                        {
                            continue;
                        }

                        var xform = LevelLoadHelper.GetObjectMatrix(o);
                        AddCgfToWorld(cgf, ref xform, o.Position, geoSpace);
                    }
                }

                // terrain
                bool   loadedH32 = false;
                string h32path   = Path.Combine(levelFolder, @"terrain\land_map.h32");
                if (levelsDir.Exists(h32path))
                {
                    using (var landMapStream = levelsDir.OpenFile(h32path))
                        new H32Loader(landMapStream).LoadIntoGeoSpace(geoSpace);
                    loadedH32 = true;
                }

                Console.WriteLine("      Data load time: " + (DateTime.Now - TIMER));

                if (brushlst == null && ctx == null && !loadedH32)
                {
                    Console.WriteLine("      ** Skipping (no level data found)");
                    continue;
                }

                // build geo
                TIMER = DateTime.Now;
                geoSpace.BuildTree();
                geoSpace.Validate();
                Console.WriteLine("      Geo build time: " + (DateTime.Now - TIMER));

                // get size of level for scanning
                var   bb     = geoSpace.GetBoundingBox();
                float startX = Math.Max(0, bb.Min.X);
                float endX   = bb.Max.X;
                float startY = Math.Max(0, bb.Min.Y);
                float endY   = bb.Max.Y;
                int   top    = (int)Math.Ceiling(bb.Max.Z);
                int   bot    = Math.Max(0, (int)bb.Min.Z);

                // TODO - print bounding box
                // TODO - save log file

                if (endX <= startX || endY <= startY || top < bot)
                {
                    throw new InvalidOperationException(
                              $"unexpected level size for {clientLevelId} {levelFolder} bb: {bb}");
                }

                // compile mesh
                TIMER = DateTime.Now;
                float step           = 1f;
                var   navMeshBuilder = new NavMeshBuilder(startX, startY, bot, endX, endY, top, step);
                CompiledNavMeshSet compiledMeshSet = navMeshBuilder.ScanFloor(geoSpace);
                Console.WriteLine("      Raycast time: " + (DateTime.Now - TIMER));

                // save to file
                using (var fs = File.OpenWrite(outputNavFilename))
                    compiledMeshSet.Save(fs);

                Console.WriteLine($"      Level {clientLevelId} finished in {DateTime.Now - LEVEL_TIME}");
            }
        }