void BakeTileCache() { UpdateProgress(0f); int nverts = 0; float[] verts = null; int ntris = 0; int[] tris = null; ProcessTerrain(ref verts, ref nverts, ref tris, ref ntris); UpdateProgress(0.25f); IntPtr vertsPtr = Marshal.AllocHGlobal(verts.Length * sizeof(float)); Marshal.Copy(verts, 0, vertsPtr, verts.Length); IntPtr trisPtr = Marshal.AllocHGlobal(tris.Length * sizeof(int)); Marshal.Copy(tris, 0, trisPtr, tris.Length); InputGeometry geom = new InputGeometry() { verts = vertsPtr, tris = trisPtr, nverts = nverts, ntris = ntris }; UpdateProgress(0.5f); RecastConfig recastConfig = FindObjectOfType <RecastConfig>(); Dictionary <string, ushort> areas = new Dictionary <string, ushort>(); ushort k = 1; foreach (var layer in recastConfig.Layers) { areas.Add(layer.LayerID, k); TileCache.addFlag(k, 1); k *= 2; } DetourConvexVolume[] volumes = FindObjectsOfType <Pathfinding.DetourConvexVolume>(); foreach (var volume in volumes) { TileCache.addConvexVolume(volume.floatNodes(), volume.nodes.Count, volume.maxY, volume.minY, areas[volume.AreaID]); } IntPtr tileCache = new IntPtr(0); IntPtr navMesh = new IntPtr(0); IntPtr navQuery = new IntPtr(0); TileCache.handleTileCacheBuild(ref config, ref ecfg, ref geom, ref tileCache, ref navMesh, ref navQuery); UpdateProgress(0.75f); // Create asset TileCacheAsset asset = CustomAssetUtility.CreateAssetWithoutSaving <TileCacheAsset>(); IntPtr tilesHeader = new IntPtr(0); TileCache.getTileCacheHeaders(ref asset.header, ref tilesHeader, tileCache, navMesh); // Copy to asset asset.config = config; // Copy sizes int structSize = Marshal.SizeOf(typeof(TileCacheAsset.TileCacheTileHeader)); asset.tilesHeader = new TileCacheAsset.TileCacheTileHeader[asset.header.numTiles]; for (uint i = 0; i < asset.header.numTiles; ++i) { asset.tilesHeader[i] = (TileCacheAsset.TileCacheTileHeader)Marshal.PtrToStructure(new IntPtr(tilesHeader.ToInt64() + (structSize * i)), typeof(TileCacheAsset.TileCacheTileHeader)); } // Copy data int dataSize = 0; int start = 0; for (uint i = 0; i < asset.header.numTiles; ++i) { dataSize += asset.tilesHeader[i].dataSize; } asset.tilesData = new byte[dataSize]; for (uint i = 0; i < asset.header.numTiles; ++i) { IntPtr tilePtr = TileCache.getTileCacheTile(tileCache, (int)i); CompressedTile tile = (CompressedTile)Marshal.PtrToStructure(tilePtr, typeof(CompressedTile)); asset.tilesHeader[i] = (TileCacheAsset.TileCacheTileHeader)Marshal.PtrToStructure(new IntPtr(tilesHeader.ToInt64() + (structSize * i)), typeof(TileCacheAsset.TileCacheTileHeader)); if (asset.tilesHeader[i].dataSize > 0) { Marshal.Copy(tile.data, asset.tilesData, start, asset.tilesHeader[i].dataSize); start += asset.tilesHeader[i].dataSize; } } // Save asset CustomAssetUtility.SaveAsset <TileCacheAsset>(asset); // Close window UpdateProgress(0f); EditorUtility.ClearProgressBar(); }
public void OnEnable() { _recastConfig = GameObject.FindObjectOfType <RecastConfig>(); _tileCache = new TileCache(navmeshData, _recastConfig); IntPtr h = createCrowd(MaxAgents, AgentMaxRadius, _tileCache.NavMeshHandle.Handle); _crowd = new HandleRef(this, h); ushort k = 0; var filters = _recastConfig.Filters.ToList(); filters.Reverse(); foreach (var filter in filters) { ushort include = 0; ushort exclude = 0; foreach (var incl in filter.Include) { include |= _recastConfig.Areas[incl.Name]; } foreach (var excl in filter.Exclude) { exclude |= _recastConfig.Areas[excl.Name]; } setFilter(_crowd.Handle, k, include, exclude); ++k; } randomSample = new float[3]; positions = new float[MaxAgents * 3]; velocities = new float[MaxAgents * 3]; targetStates = new byte[MaxAgents]; states = new byte[MaxAgents]; partial = new bool[MaxAgents]; Instance = this; if (RenderInGame) { mesh.Clear(); switch (Mode) { case RenderMode.POLYS: Assert.IsTrue(polymesh != null); RecastDebug.ShowRecastNavmesh(mesh, polymesh.PolyMesh, polymesh.config); break; case RenderMode.DETAIL_POLYS: Assert.IsTrue(polymesh != null); RecastDebug.ShowRecastDetailMesh(mesh, polymesh.PolyDetailMesh); break; case RenderMode.TILE_POLYS: for (int i = 0; i < navmeshData.header.numTiles; ++i) { RecastDebug.ShowTilePolyDetails(mesh, _tileCache.NavMeshHandle.Handle, i); } break; } //RecastDebug.RenderObstacles(_tileCache.TileCacheHandle.Handle); mesh.CreateGameObjects("RecastRenderer", material); mesh.Rebuild(); } }
public void OnEnable() { _recastConfig = GameObject.FindObjectOfType<RecastConfig>(); _tileCache = new TileCache(navmeshData, _recastConfig); IntPtr h = createCrowd(MaxAgents, AgentMaxRadius, _tileCache.NavMeshHandle.Handle); _crowd = new HandleRef(this, h); ushort k = 0; var filters = _recastConfig.Filters.ToList(); filters.Reverse(); foreach (var filter in filters) { ushort include = 0; ushort exclude = 0; foreach (var incl in filter.Include) { include |= _recastConfig.Areas[incl.Name]; } foreach (var excl in filter.Exclude) { exclude |= _recastConfig.Areas[excl.Name]; } setFilter(_crowd.Handle, k, include, exclude); ++k; } randomSample = new float[3]; positions = new float[MaxAgents * 3]; velocities = new float[MaxAgents * 3]; targetStates = new byte[MaxAgents]; states = new byte[MaxAgents]; partial = new bool[MaxAgents]; Instance = this; if (RenderInGame) { mesh.Clear(); switch (Mode) { case RenderMode.POLYS: Assert.IsTrue(polymesh != null); RecastDebug.ShowRecastNavmesh(mesh, polymesh.PolyMesh, polymesh.config); break; case RenderMode.DETAIL_POLYS: Assert.IsTrue(polymesh != null); RecastDebug.ShowRecastDetailMesh(mesh, polymesh.PolyDetailMesh); break; case RenderMode.TILE_POLYS: for (int i = 0; i < navmeshData.header.numTiles; ++i) RecastDebug.ShowTilePolyDetails(mesh, _tileCache.NavMeshHandle.Handle, i); break; } //RecastDebug.RenderObstacles(_tileCache.TileCacheHandle.Handle); mesh.CreateGameObjects("RecastRenderer", material); mesh.Rebuild(); } }