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 }; }
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); }
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 }; }
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); }
/// <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); }
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); }
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); }
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); }
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); }