示例#1
0
        protected override void LoadContent()
        {
            _mesh = new NavMesh();
            if (File.Exists(@"S:\meshReader\meshes\" + _continent + "\\" + _continent + ".dmesh"))
            {
                _mesh.Initialize(File.ReadAllBytes(@"S:\meshReader\meshes\" + _continent + "\\" + _continent + ".dmesh"));
            }
            else
            {
                _mesh.Initialize(32768, 128, World.Origin, Constant.TileSize, Constant.TileSize);
                MeshTile discard;
                _mesh.AddTile(
                    File.ReadAllBytes(@"S:\meshReader\meshes\" + _continent + "\\" + _continent + "_" + _tileX + "_" +
                                      _tileY + ".tile"), out discard);
            }
            float[] vertices;
            int[]   tris;
            _mesh.BuildRenderGeometry(_tileX, _tileY, out vertices, out tris);
            _drawer = new GeometryDrawer();
            _drawer.Initialize(Game, new Color(0.1f, 0.1f, 0.9f, 0.5f), vertices, tris);

            _effect     = new BasicEffect(GraphicsDevice);
            _depthState = new DepthStencilState {
                DepthBufferEnable = true
            };
        }
示例#2
0
        public static bool LoadNavMeshByJsonFile(string filePath, ref NavMesh navMesh)
        {
            navMesh = null;
            if (string.IsNullOrEmpty(filePath))
            {
                return(false);
            }

            if (File.Exists(filePath) == false)
            {
                Console.WriteLine("LoadNavMeshByJsonFile:{0} is not exist", filePath);
                return(false);
            }

            using (FileStream fsRead = new FileStream(filePath, FileMode.Open))
            {
                int    fsLen  = (int)fsRead.Length;
                byte[] heByte = new byte[fsLen];
                fsRead.Read(heByte, 0, heByte.Length);

                string jsonString = System.Text.Encoding.UTF8.GetString(heByte);
                //var ms = new MemoryStream(heByte);
                //JsonMap jsonMap = (JsonMap)new DataContractJsonSerializer(typeof(JsonMap)).ReadObject(ms);

                JsonMap jsonMap = MathUtils.ParseJson <JsonMap>(jsonString);//JsonConvert.DeserializeObject(jsonString, typeof(JsonMap));
                if (jsonMap == null)
                {
                    Console.WriteLine("JsonConvert.DeserializeObject ==> {0} failed", filePath);
                    return(false);
                }

                navMesh = new NavMesh();

                Status status = navMesh.Init(jsonMap.Param);
                if (status != Status.Success)
                {
                    Console.WriteLine("NavMesh init failed");
                    return(false);
                }

                for (int i = 0; i < jsonMap.NavMeshBuilders.Count; i++)
                {
                    NavMeshBuilder builder = jsonMap.NavMeshBuilders[i];
                    if (builder == null)
                    {
                        continue;
                    }
                    long   result = 0;
                    Status ss     = navMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
                    if (ss != Status.Success)
                    {
                        Console.WriteLine("NavMesh AddTile failed! result = {0}", result);
                    }
                }
            }

            return(true);
        }
示例#3
0
        protected override void LoadContent()
        {
            string Folder = @"G:\Meshes\6.0\";

            _mesh = new NavMesh();
            if (File.Exists(Folder + _continent + "\\" + _continent + ".dmesh"))
            {
                _mesh.Initialize(File.ReadAllBytes(Folder + _continent + "\\" + _continent + ".dmesh"));
            }
            else
            {
                MeshTile discard;
                if (Constant.Division == 1)
                {
                    _mesh.Initialize(150000, 4096, World.Origin, Constant.BaseTileSize, Constant.BaseTileSize);
                    _mesh.AddTile(File.ReadAllBytes(Folder + _continent + "\\" + _continent + "_" + _tileX + "_" + _tileY + ".tile"), out discard);
                }
                else
                {
                    _mesh.Initialize(150000, 4096, World.Origin, Constant.TileSize, Constant.TileSize);
                    string name = _continent + "\\" + _continent + "_" + _tileX + "_" + _tileY + "_" + _i + _j + ".tile";
                    _mesh.AddTile(File.ReadAllBytes(Folder + name), out discard);
                    System.Console.WriteLine(name);
                }
            }
            float[] vertices;
            int[]   tris;
            if (Constant.Division == 1)
            {
                _mesh.BuildRenderGeometry(_tileX, _tileY, out vertices, out tris);
            }
            else
            {
                _mesh.BuildRenderGeometry(_tileX * Constant.Division + _i, _tileY * Constant.Division + _j, out vertices, out tris);
            }
            _drawer = new GeometryDrawer();
            _drawer.Initialize(Game, new Color(0.1f, 0.1f, 0.9f, 0.5f), vertices, tris);
            _effect     = new BasicEffect(GraphicsDevice);
            _depthState = new DepthStencilState {
                DepthBufferEnable = true
            };
        }
示例#4
0
    public NavMesh Reconstitute()
    {
        NavMesh navMesh = new NavMesh();

        navMesh.Init(Param);

        long tempRef = 0;
        long temp    = 0;

        for (int i = 0; i < NavMeshBuilders.Length; i++)
        {
            if (NavMeshBuilders[i] != null)
            {
                navMesh.AddTile(NavMeshBuilders[i], NavMesh.TileFreeData, tempRef, ref temp);
                //tempRef = temp;
            }
        }
        return(navMesh);
    }
示例#5
0
            /// <summary>
            /// Creates a navigation mesh from a navigation mesh file
            /// </summary>
            /// <param name="file">Navigation mesh file</param>
            /// <returns>Returns the navigation mesh</returns>
            public static NavMesh FromNavmeshFile(NavMeshFile file)
            {
                NavMesh navmesh = new NavMesh();

                navmesh.Init(file.NavMeshParams);

                for (int i = 0; i < file.NavMeshData.Count; i++)
                {
                    var tile = file.NavMeshData[i];
                    if (tile == null || tile.Header.Magic != Detour.DT_NAVMESH_MAGIC)
                    {
                        continue;
                    }

                    navmesh.AddTile(tile, TileFlagTypes.DT_TILE_FREE_DATA, 0, out int res);
                }

                if (file.HasTileCache)
                {
                    var tmproc = new TileCacheMeshProcess(null);

                    navmesh.TileCache = new TileCache();
                    navmesh.TileCache.Init(file.TileCacheParams, tmproc);

                    for (int i = 0; i < file.TileCacheData.Count; i++)
                    {
                        var tile = file.TileCacheData[i];
                        if (tile.Header.Magic != DetourTileCache.DT_TILECACHE_MAGIC)
                        {
                            continue;
                        }

                        navmesh.TileCache.AddTile(tile, CompressedTileFlagTypes.DT_COMPRESSEDTILE_FREE_DATA);
                    }
                }

                return(navmesh);
            }
示例#6
0
        protected override void LoadContent()
        {
            _mesh = new NavMesh();
            if (File.Exists(@"S:\meshReader\meshes\" + _continent + "\\" + _continent + ".dmesh"))
            {
                _mesh.Initialize(File.ReadAllBytes(@"S:\meshReader\meshes\" + _continent + "\\" + _continent + ".dmesh"));
            }
            else
            {
                _mesh.Initialize(32768, 128, World.Origin, Constant.TileSize, Constant.TileSize);
                MeshTile discard;
                _mesh.AddTile(
                    File.ReadAllBytes(@"S:\meshReader\meshes\" + _continent + "\\" + _continent + "_" + _tileX + "_" +
                                      _tileY + ".tile"), out discard);
            }
            float[] vertices;
            int[] tris;
            _mesh.BuildRenderGeometry(_tileX, _tileY, out vertices, out tris);
            _drawer = new GeometryDrawer();
            _drawer.Initialize(Game, new Color(0.1f, 0.1f, 0.9f, 0.5f), vertices, tris);

            _effect = new BasicEffect(GraphicsDevice);
            _depthState = new DepthStencilState { DepthBufferEnable = true };
        }
示例#7
0
        public bool BuildNavMeshTile(CompressedTile tile, NavMesh navmesh)
        {
            NavMeshTileBuildContext bc = new NavMeshTileBuildContext();
            int walkableClimbVx        = (int)(m_params.WalkableClimb / m_params.CellHeight);

            // Decompress tile layer data.
            if (!DetourTileCache.DecompressTileCacheLayer(tile.Header, tile.Data, 0, out var layer))
            {
                return(false);
            }
            bc.Layer = layer;

            // Rasterize obstacles.
            for (int i = 0; i < m_params.MaxObstacles; ++i)
            {
                var ob = m_obstacles[i];

                if (ob.State == ObstacleState.DT_OBSTACLE_EMPTY || ob.State == ObstacleState.DT_OBSTACLE_REMOVING)
                {
                    continue;
                }

                if (DetourTileCache.Contains(ob.Touched, ob.NTouched, tile))
                {
                    if (ob.Type == ObstacleType.DT_OBSTACLE_CYLINDER)
                    {
                        DetourTileCache.MarkCylinderArea(bc,
                                                         tile.Header.BBox.Minimum, m_params.CellSize, m_params.CellHeight,
                                                         ob.Cylinder.Pos, ob.Cylinder.Radius, ob.Cylinder.Height, 0);
                    }
                    else if (ob.Type == ObstacleType.DT_OBSTACLE_BOX)
                    {
                        DetourTileCache.MarkBoxArea(bc,
                                                    tile.Header.BBox.Minimum, m_params.CellSize, m_params.CellHeight,
                                                    ob.Box.BMin, ob.Box.BMax, 0);
                    }
                    else if (ob.Type == ObstacleType.DT_OBSTACLE_ORIENTED_BOX)
                    {
                        DetourTileCache.MarkBoxArea(bc,
                                                    tile.Header.BBox.Minimum, m_params.CellSize, m_params.CellHeight,
                                                    ob.OrientedBox.Center, ob.OrientedBox.HalfExtents, ob.OrientedBox.RotAux, 0);
                    }
                }
            }

            // Build navmesh
            if (!DetourTileCache.BuildTileCacheRegions(bc, walkableClimbVx))
            {
                return(false);
            }

            if (!DetourTileCache.BuildTileCacheContours(bc, walkableClimbVx, m_params.MaxSimplificationError))
            {
                return(false);
            }

            if (!DetourTileCache.BuildTileCachePolyMesh(bc))
            {
                return(false);
            }

            // Early out if the mesh tile is empty.
            if (bc.LMesh.NPolys == 0)
            {
                // Remove existing tile.
                navmesh.RemoveTile(navmesh.GetTileRefAt(tile.Header.TX, tile.Header.TY, tile.Header.TLayer), null, 0);
                return(true);
            }

            var param = new NavMeshCreateParams
            {
                Verts          = bc.LMesh.Verts,
                VertCount      = bc.LMesh.NVerts,
                Polys          = bc.LMesh.Polys,
                PolyAreas      = bc.LMesh.Areas,
                PolyFlags      = bc.LMesh.Flags,
                polyCount      = bc.LMesh.NPolys,
                nvp            = Detour.DT_VERTS_PER_POLYGON,
                walkableHeight = m_params.WalkableHeight,
                walkableRadius = m_params.WalkableRadius,
                walkableClimb  = m_params.WalkableClimb,
                tileX          = tile.Header.TX,
                tileY          = tile.Header.TY,
                tileLayer      = tile.Header.TLayer,
                cs             = m_params.CellSize,
                ch             = m_params.CellHeight,
                buildBvTree    = false,
                bmin           = tile.Header.BBox.Minimum,
                bmax           = tile.Header.BBox.Maximum,
            };

            if (m_tmproc != null)
            {
                m_tmproc.Process(ref param, bc);
            }

            if (!Detour.CreateNavMeshData(param, out MeshData navData))
            {
                return(false);
            }

            // Remove existing tile.
            navmesh.RemoveTile(navmesh.GetTileRefAt(tile.Header.TX, tile.Header.TY, tile.Header.TLayer), null, 0);

            // Add new tile, or leave the location empty.
            if (navData != null && !navmesh.AddTile(navData, TileFlagTypes.DT_TILE_FREE_DATA, 0, out int result))
            {
                // Let the navmesh own the data.
                navData = null;

                return(false);
            }

            return(true);
        }
示例#8
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Please supply continent name");
                return;
            }

            var continent = args[0];
            var path = "S:\\meshReader\\Meshes\\" + continent;
            if (!Directory.Exists(path))
            {
                Console.WriteLine("Can't find mesh directory: " + path);
                return;
            }

            Console.Write("Setting up data storage.. ");
            string floodDir = "S:\\meshReader\\Meshes\\Floodfill\\";
            if (!Directory.Exists(floodDir))
                Directory.CreateDirectory(floodDir);
            floodDir += continent;
            if (Directory.Exists(floodDir))
                Directory.Delete(floodDir, true);
            Directory.CreateDirectory(floodDir);
            floodDir += "\\";
            Console.WriteLine("done");

            var files = Directory.GetFiles(path).Where(f => f.EndsWith(".tile"));
            Console.WriteLine("Total amount of tiles: " + files.Count());
            if (files.Count() > 4096)
            {
                Console.WriteLine("Too many tiles. Increase maxTiles.");
                return;
            }

            Console.WriteLine("Initializing mesh..");
            var mesh = new NavMesh();
            if ((mesh.Initialize(32768, 4096, Utility.Origin, Utility.TileSize, Utility.TileSize) & DetourStatus.Failure) != 0)
            {
                Console.WriteLine("Failed to initialize mesh.");
                return;
            }

            Console.WriteLine("Loading all tiles..");
            var tiles = new List<MeshTile>(files.Count());
            foreach (var file in files)
            {
                var data = File.ReadAllBytes(file);
                MeshTile tile;
                if ((mesh.AddTile(data, out tile) & DetourStatus.Failure) != 0)
                {
                    Console.WriteLine("Failed to load tile: " + file);
                    return;
                }
                tiles.Add(tile);
            }

            Console.WriteLine("Initializing DBC backend...");
            MpqManager.InitializeDBC("S:\\WoW");

            Console.Write("Identifiying map id.. ");
            int mapId = PhaseHelper.GetMapIdByName(continent);
            if (mapId < 0)
            {
                Console.WriteLine("failed");
                return;
            }
            Console.WriteLine(mapId);
            Console.Write("Identifying source points.. ");
            var sourcePoints = new List<Vector3>(100);
            sourcePoints.AddRange(from record in TaxiHelper.TaxiNodesDBC.Records
                                  select new TaxiNode(record)
                                  into node where node.IsValid && node.MapId == mapId select node.Location.ToRecast());
            Console.WriteLine(sourcePoints.Count);

            Console.WriteLine("Initializing flood fill..");
            var floodFill = new FloodFill(mesh);
            Console.WriteLine("Flooding.. ");
            foreach (var source in sourcePoints)
                floodFill.ExecuteFrom(source);
            Console.WriteLine("Finished, visited " + floodFill.Marked + " polygons");

            Console.WriteLine("Rebuilding tiles...");
            var config = RecastConfig.Default;
            long sizeBefore = 0;
            long sizeAfter = 0;
            foreach (var tile in tiles)
            {
                sizeBefore += tile.DataSize;
                byte[] rebuiltData;

                if (!tile.Rebuild(floodFill.Visited, floodFill.VisitedMask, config.CellHeight, config.MaxVertsPerPoly, out rebuiltData))
                {
                    Console.WriteLine("Failed to rebuild tile " + tile.Header.X + " " + tile.Header.Y);
                    continue;
                }

                if (rebuiltData == null)
                {
                    Console.WriteLine("Tile " + tile.Header.X + " " + tile.Header.Y + " ceases to exist.");
                    continue;
                }

                sizeAfter += rebuiltData.Length;
                File.WriteAllBytes(floodDir + continent + "_" + tile.Header.X + "_" + tile.Header.Y + ".tile", rebuiltData);
            }

            Console.WriteLine("All done, size before: " + (sizeBefore / 1024 / 1024) + "MiB after: " + (sizeAfter / 1024 / 1024) + "MiB");
            Console.ReadKey(true);
        }
示例#9
0
        public void TestNavMesh(byte[] data)
        {

            var extents = new Vector3(2.5f, 2.5f, 2.5f).ToFloatArray();


            // var startVec = new Vector3(-9467.8f, 64.2f, 55.9f);
            //var endVec = new Vector3(-9248.9f, -93.35f, 70.3f);


            //Vector3 startVec = new Vector3(1672.2f, 1662.9f, 139.2f);
            //Vector3 startVec = new Vector3(1665.2f, 1678.2f, 120.5f);

            Vector3 startVec = new Vector3 ( -8949.95f, -132.493f, 83.5312f );
            Vector3 endVec = new Vector3 ( -9046.507f, -45.71962f, 88.33186f );

            var start = startVec.ToRecast().ToFloatArray();
            var end = endVec.ToRecast().ToFloatArray();

            NavMesh _mesh = new NavMesh();
            _mesh.Initialize(32768, 4096, Helpers.Origin, Helpers.TileSize, Helpers.TileSize);
            var meshData = data;
            MeshTile tile;
            _mesh.AddTile(data, out tile);
            NavMeshQuery _query = new NavMeshQuery();
            _query.Initialize(_mesh, 65536);
            QueryFilter Filter = new QueryFilter { IncludeFlags = 0xFFFF, ExcludeFlags = 0x0 };

            var startRef = _query.FindNearestPolygon(start, extents, Filter);
           

            var endRef = _query.FindNearestPolygon(end, extents, Filter);


            uint[] pathCorridor;
            var status = _query.FindPath(startRef, endRef, start, end, Filter, out pathCorridor);
            if (status.Equals(DetourStatus.Failure) || pathCorridor == null)
                throw new Exception("FindPath failed, start: " + startRef + " end: " + endRef);

            if (status.HasFlag(DetourStatus.PartialResult))
                Console.WriteLine("Warning, partial result: " + status);

            float[] finalPath;
            StraightPathFlag[] pathFlags;
            uint[] pathRefs;
            status = _query.FindStraightPath(start, end, pathCorridor, out finalPath, out pathFlags, out pathRefs);
            if (status.Equals(DetourStatus.Failure) || (finalPath == null || pathFlags == null || pathRefs == null))
                throw new Exception("FindStraightPath failed, refs in corridor: " + pathCorridor.Length);

            

        }
示例#10
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Please supply continent name");
                return;
            }

            var continent = args[0];
            var path      = @"C:\\Users\\Sebastian\\CactusWOW\\MeshReader\\meshReader\\meshBuilderGui\\bin\\Debug\\" + continent;

            if (!Directory.Exists(path))
            {
                Console.WriteLine("Can't find mesh directory: " + path);
                return;
            }

            Console.Write("Setting up data storage.. ");
            string floodDir = "C:\\Users\\Sebastian\\CactusWOW\\MeshReader\\meshReader\\meshBuilderGui\\bin\\Debug\\FloodFill\\";

            if (!Directory.Exists(floodDir))
            {
                Directory.CreateDirectory(floodDir);
            }
            floodDir += continent;
            if (Directory.Exists(floodDir))
            {
                Directory.Delete(floodDir, true);
            }
            Directory.CreateDirectory(floodDir);
            floodDir += "\\";
            Console.WriteLine("done");

            var files = Directory.GetFiles(path).Where(f => f.EndsWith(".tile"));

            Console.WriteLine("Total amount of tiles: " + files.Count());
            if (files.Count() > 4096)
            {
                Console.WriteLine("Too many tiles. Increase maxTiles.");
                return;
            }

            Console.WriteLine("Initializing mesh..");
            var mesh = new NavMesh();

            if ((mesh.Initialize(32768, 4096, Utility.Origin, Utility.TileSize, Utility.TileSize) & DetourStatus.Failure) != 0)
            {
                Console.WriteLine("Failed to initialize mesh.");
                return;
            }

            Console.WriteLine("Loading all tiles..");
            var tiles = new List <MeshTile>(files.Count());

            foreach (var file in files)
            {
                var      data = File.ReadAllBytes(file);
                MeshTile tile;
                if ((mesh.AddTile(data, out tile) & DetourStatus.Failure) != 0)
                {
                    Console.WriteLine("Failed to load tile: " + file);
                    return;
                }
                tiles.Add(tile);
            }

            Console.WriteLine("Initializing DBC backend...");
            MpqManager.InitializeDBC(@"L:\World of Warcraft 3.3.5a");

            Console.Write("Identifiying map id.. ");
            int mapId = PhaseHelper.GetMapIdByName(continent);

            if (mapId < 0)
            {
                Console.WriteLine("failed");
                return;
            }
            Console.WriteLine(mapId);
            Console.Write("Identifying source points.. ");
            var sourcePoints = new List <Vector3>(100);

            sourcePoints.AddRange(from record in TaxiHelper.TaxiNodesDBC.Records
                                  select new TaxiNode(record)
                                  into node where node.IsValid && node.MapId == mapId select node.Location.ToRecast());
            Console.WriteLine(sourcePoints.Count);

            Console.WriteLine("Initializing flood fill..");
            var floodFill = new FloodFill(mesh);

            Console.WriteLine("Flooding.. ");
            foreach (var source in sourcePoints)
            {
                floodFill.ExecuteFrom(source);
            }
            Console.WriteLine("Finished, visited " + floodFill.Marked + " polygons");

            Console.WriteLine("Rebuilding tiles...");
            var  config     = RecastConfig.Default;
            long sizeBefore = 0;
            long sizeAfter  = 0;

            foreach (var tile in tiles)
            {
                sizeBefore += tile.DataSize;
                byte[] rebuiltData;

                if (!tile.Rebuild(floodFill.Visited, floodFill.VisitedMask, config.CellHeight, config.MaxVertsPerPoly, out rebuiltData))
                {
                    Console.WriteLine("Failed to rebuild tile " + tile.Header.X + " " + tile.Header.Y);
                    continue;
                }

                if (rebuiltData == null)
                {
                    Console.WriteLine("Tile " + tile.Header.X + " " + tile.Header.Y + " ceases to exist.");
                    continue;
                }

                sizeAfter += rebuiltData.Length;
                File.WriteAllBytes(floodDir + continent + "_" + tile.Header.X + "_" + tile.Header.Y + ".tile", rebuiltData);
            }

            Console.WriteLine("All done, size before: " + (sizeBefore / 1024 / 1024) + "MiB after: " + (sizeAfter / 1024 / 1024) + "MiB");
            Console.ReadKey(true);
        }