Esempio n. 1
0
        // NavMesh generator
        private List <VertexPositionColor> LoadNavMeshTestData(H32Loader h32)
        {
            // TODO - configure nav dir - determine filename using worldid xml

            DateTime TIMER;
            var      floorLineVertices = new List <VertexPositionColor>();

            bool generate     = true;  //false;
            bool loadFromFile = false; //true;//true;
            bool saveToFile   = false; //true;
            //NavMeshBuilder.OPTION_PARALLEL_THREADS = 1;
            //NavMeshBuilder.OPTION_REMOVE_SMALL_GRAPHS = false;

            CompiledNavMeshSet compiledMeshSet = null;

            if (generate)
            {
                TIMER = DateTime.Now;
                h32.LoadIntoGeoSpace(m_geoSpace);
                Debug.WriteLine("h32.LoadIntoGeoSpace TIME: " + (DateTime.Now - TIMER));

                TIMER = DateTime.Now;
                m_geoSpace.BuildTree();
                m_geoSpace.Validate();
                Debug.WriteLine("BuildTree TIME: " + (DateTime.Now - TIMER));

                float startX = 90;       //133-120; //340 - 20;
                float endX   = 200;      //133+20; //360 + 20;
                float startY = 103 - 20; //220 - 20;
                float endY   = 120;      // 103+20; //240 + 20;

                int top = 400;
                int bot = 0;

                float step           = 1f;
                var   navMeshBuilder = new NavMeshBuilder(startX, startY, bot, endX, endY, top, step);

                TIMER           = DateTime.Now;
                compiledMeshSet = navMeshBuilder.ScanFloor(m_geoSpace);
                Debug.WriteLine("ScanFloor TIME: " + (DateTime.Now - TIMER));

                if (saveToFile)
                {
                    // File roundtrip test
                    using (var fs = File.OpenWrite("c:\\temp2\\300200000.nav"))
                        compiledMeshSet.Save(fs);
                }
            }

            if (loadFromFile)
            {
                using (var fs = File.OpenRead(@"c:\temp2\out\210020000.nav"))  //"c:\\temp2\\300200000.nav"))
                    compiledMeshSet = CompiledNavMeshSet.Load(fs);
            }

            Debug.WriteLine("Total estimated compiled mesh size in bytes: " + compiledMeshSet.GetEstimatedFileSizeInBytes());

            var compiledMesh = //compiledMeshSet.FindSubgraphUnderPointWithSnap(126, 66, 145+2, maxFall: 10);
                               //compiledMeshSet.FindSubgraphUnderPointWithSnap(2484, 2614, 300, maxFall: 20);
                               compiledMeshSet.FindSubgraphUnderPointWithSnap(110, 110, 300, maxFall: 2220);

            if (compiledMesh == null)
            {
                throw new InvalidOperationException("point was not over a floor");
            }

            m_tempCompiledNavMeshSet = compiledMeshSet;

            // DEBUG MARKERS

            //    floorLineVertices.Add(new VertexPositionColor(new Vector3(126, 65, 144.3f + 3), Color.Lime));
            //    floorLineVertices.Add(new VertexPositionColor(new Vector3(126, 65, 144.3f), Color.Lime));

            //    floorLineVertices.Add(new VertexPositionColor(new Vector3(127, 64, 145.09f + 3), Color.Red));
            //    floorLineVertices.Add(new VertexPositionColor(new Vector3(127, 64, 145.09f), Color.Red));

            //=============================================
            // TESTING COMPILED MESH GETNEIGHBOR

            //start...
            //    floorLineVertices.Add(new VertexPositionColor(new Vector3(133, 103, 150), Color.White));
            //  floorLineVertices.Add(new VertexPositionColor(new Vector3(133, 103, 144), Color.White));

            /*
             * var curNode = compiledMesh.FindFloorUnderPoint(132.9f, 102.9f, 149, 20);
             * Vector3 v = compiledMesh.WorldFromBlockIndex(curNode.blockIndex, 144);
             *
             * floorLineVertices.Add(new VertexPositionColor(v + new Vector3(0,0,5), Color.Lime));
             * floorLineVertices.Add(new VertexPositionColor(v, Color.Lime));
             *
             * curNode = compiledMesh.GetNeighbor(curNode, 0, 1);
             * v = compiledMesh.WorldFromBlockIndex(curNode.blockIndex, 144);
             * floorLineVertices.Add(new VertexPositionColor(v + new Vector3(0, 0, 5), Color.Cyan));
             * floorLineVertices.Add(new VertexPositionColor(v, Color.Lime));
             *
             * curNode = compiledMesh.GetNeighbor(curNode, 0, 1);
             * v = compiledMesh.WorldFromBlockIndex(curNode.blockIndex, 144);
             * floorLineVertices.Add(new VertexPositionColor(v + new Vector3(0, 0, 5), Color.Yellow));
             * floorLineVertices.Add(new VertexPositionColor(v, Color.Lime));
             *
             * curNode = compiledMesh.GetNeighbor(curNode, 1, 1);
             * v = compiledMesh.WorldFromBlockIndex(curNode.blockIndex, 144);
             * floorLineVertices.Add(new VertexPositionColor(v + new Vector3(0, 0, 5), Color.White));
             * floorLineVertices.Add(new VertexPositionColor(v, Color.Lime));
             */
            // END TEST
            //=============================================



            //=============================================
            // TEST A*

            //TestAStar(compiledMesh, new Vector3(141, 21, 145), new Vector3(140, 28, 144), 10, floorLineVertices);

            //TestAStar(compiledMesh, new Vector3(155, 56, 144), new Vector3(169, 23, 144), 10, floorLineVertices);

            //    TestAStar(compiledMesh, new Vector3(130, 101, 145), new Vector3(125, 106, 147), 10, floorLineVertices);
            // END A*
            //=============================================



            TIMER = DateTime.Now;
            for (int bY = 0; bY < compiledMesh.BlockHeight; bY++)
            {
                for (int bX = 0; bX < compiledMesh.BlockWidth; bX++)
                {
                    float x = compiledMesh.X1 + bX * compiledMesh.Step;
                    float y = compiledMesh.Y1 + bY * compiledMesh.Step;

                    compiledMesh.ForeachHeightAtXY(bX, bY,
                                                   (directionFlags, z) =>
                    {
                        /*Color xcolor = Color.Lime;
                         *
                         * //if (bX == 28 && bY == 0) Debugger.Break();
                         *
                         * if (y > 221 && y < 223 && x > 346 && x < 348)
                         *  xcolor = Color.White;
                         * else if (y > 221 && y < 223 && x > 347 && x < 349)
                         *  xcolor = Color.Blue;
                         * else if (y >= 221 && y <= 223 && x >= 346 && x <= 348)
                         *  xcolor = Color.Red;*/


                        // DRAW ELEVATION MARKER

                        /*    floorLineVertices.Add(new VertexPositionColor(new Vector3(x - 0.1f, y, z), xcolor));
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y + 0.1f, z), xcolor));
                         *
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y + 0.1f, z), xcolor));
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x + 0.1f, y, z), xcolor));
                         *
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x + 0.1f, y, z), xcolor));
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y - 0.1f, z), xcolor));
                         *
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y - 0.1f, z), xcolor));
                         *  floorLineVertices.Add(new VertexPositionColor(new Vector3(x - 0.1f, y, z), xcolor));
                         */

                        // EDGE CONNECTIONS
                        // draw lines through the compass points...

                        float halfstep = compiledMesh.Step;
                        float n;

                        n = compiledMesh.GetEdge(bX, bY, z, directionFlags, NavMeshUtil.DIRECTION_LEFT);
                        if (n >= 0)
                        {
                            var test = Color.Orange;
                            if (Math.Abs(z - n) >= 0.9f)
                            {
                                test = Color.Red;
                            }

                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y, z), test));
                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x - halfstep, y, n), test));
                        }
                        n = compiledMesh.GetEdge(bX, bY, z, directionFlags, NavMeshUtil.DIRECTION_TL);
                        if (n >= 0)
                        {
                            var test = Color.Orange;
                            if (Math.Abs(z - n) / (new Vector2(x, y) - new Vector2(x - halfstep, y + halfstep)).Length() >= 1.4f)
                            {
                                test = Color.Magenta;
                            }

                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y, z), test));
                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x - halfstep, y + halfstep, n), test));
                        }
                        n = compiledMesh.GetEdge(bX, bY, z, directionFlags, NavMeshUtil.DIRECTION_TOP);
                        if (n >= 0)
                        {
                            var test = Color.Orange;
                            if (Math.Abs(z - n) >= 0.9f)
                            {
                                test = Color.Red;
                            }

                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y, z), test));
                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y + halfstep, n), test));
                        }
                        n = compiledMesh.GetEdge(bX, bY, z, directionFlags, NavMeshUtil.DIRECTION_TR);
                        if (n >= 0)
                        {
                            var test = Color.Orange;
                            if (Math.Abs(z - n) / (new Vector2(x, y) - new Vector2(x + halfstep, y + halfstep)).Length() >= 1.4f)
                            {
                                test = Color.Purple;
                            }

                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x, y, z), test));
                            floorLineVertices.Add(new VertexPositionColor(new Vector3(x + halfstep, y + halfstep, n), test));
                        }
                    });
                }
            }
            Debug.WriteLine("MESH ASSEMBLY TIME: " + (DateTime.Now - TIMER));
            return(floorLineVertices);
        }
Esempio n. 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}");
            }
        }
Esempio n. 3
0
        // NavMesh generator
        private List <VertexPositionColor> LoadNavMeshTestData(H32Loader h32)
        {
            // TODO - configure nav dir - determine filename using worldid xml

            DateTime TIMER;
            bool     generate     = false;
            bool     loadFromFile = true;
            bool     saveToFile   = false;//true;
            //NavMeshBuilder.OPTION_PARALLEL_THREADS = 1;
            //NavMeshBuilder.OPTION_REMOVE_SMALL_GRAPHS = false;

            CompiledNavMeshSet compiledMeshSet = null;

            if (generate)
            {
                TIMER = DateTime.Now;
                h32.LoadIntoGeoSpace(m_geoSpace);
                Debug.WriteLine("h32.LoadIntoGeoSpace TIME: " + (DateTime.Now - TIMER));

                TIMER = DateTime.Now;
                m_geoSpace.BuildTree();
                m_geoSpace.Validate();
                Debug.WriteLine("BuildTree TIME: " + (DateTime.Now - TIMER));

                float startX = 90;       //133-120; //340 - 20;
                float endX   = 200;      //133+20; //360 + 20;
                float startY = 103 - 20; //220 - 20;
                float endY   = 120;      // 103+20; //240 + 20;

                int top = 400;
                int bot = 0;

                float step           = 1f;
                var   navMeshBuilder = new NavMeshBuilder(startX, startY, bot, endX, endY, top, step);

                TIMER           = DateTime.Now;
                compiledMeshSet = navMeshBuilder.ScanFloor(m_geoSpace);
                Debug.WriteLine("ScanFloor TIME: " + (DateTime.Now - TIMER));

                if (saveToFile)
                {
                    // File roundtrip test
                    using (var fs = File.OpenWrite("c:\\temp2\\300200000.nav"))
                        compiledMeshSet.Save(fs);
                }
            }

            if (loadFromFile)
            {
                using (var fs = File.OpenRead(@"c:\temp2\out\210020000.nav"))  //"c:\\temp2\\300200000.nav"))
                    compiledMeshSet = CompiledNavMeshSet.Load(fs);
            }

            Debug.WriteLine("Total estimated compiled mesh size in bytes: " + compiledMeshSet.GetEstimatedFileSizeInBytes());

            var compiledMesh = //compiledMeshSet.FindSubgraphUnderPointWithSnap(126, 66, 145+2, maxFall: 10);
                               //compiledMeshSet.FindSubgraphUnderPointWithSnap(2484, 2614, 300, maxFall: 20);
                               compiledMeshSet.FindSubgraphUnderPointWithSnap(110, 110, 300, maxFall: 2220);

            if (compiledMesh == null)
            {
                throw new InvalidOperationException("point was not over a floor");
            }

            m_tempCompiledNavMeshSet = compiledMeshSet;

            TIMER = DateTime.Now;
            var floorLineVertices = RenderFloorLines(compiledMesh, Vector3.Zero, 0);

            Debug.WriteLine("MESH ASSEMBLY TIME: " + (DateTime.Now - TIMER));

            return(floorLineVertices);
        }