protected void ScanAllTiles(OnScanStatus statusCallback) { #if ASTARDEBUG System.Console.WriteLine("Recast Graph -- Collecting Meshes"); #endif #if BNICKSON_UPDATED editorTileSize = (int)(EditorVars.GridSize / cellSize); #endif //---- //Voxel grid size int gw = (int)(forcedBounds.size.x / cellSize + 0.5f); int gd = (int)(forcedBounds.size.z / cellSize + 0.5f); if (!useTiles) { tileSizeX = gw; tileSizeZ = gd; } else { tileSizeX = editorTileSize; tileSizeZ = editorTileSize; } //Number of tiles int tw = (gw + tileSizeX - 1) / tileSizeX; int td = (gd + tileSizeZ - 1) / tileSizeZ; tileXCount = tw; tileZCount = td; if (tileXCount * tileZCount > TileIndexMask + 1) { throw new System.Exception("Too many tiles (" + (tileXCount * tileZCount) + ") maximum is " + (TileIndexMask + 1) + "\nTry disabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* inspector."); } tiles = new NavmeshTile[tileXCount * tileZCount]; #if ASTARDEBUG System.Console.WriteLine("Recast Graph -- Creating Voxel Base"); #endif // If this is true, just fill the graph with empty tiles if (scanEmptyGraph) { for (int z = 0; z < td; z++) { for (int x = 0; x < tw; x++) { tiles[z * tileXCount + x] = NewEmptyTile(x, z); } } return; } AstarProfiler.StartProfile("Finding Meshes"); List <ExtraMesh> extraMeshes; #if !NETFX_CORE || UNITY_EDITOR System.Console.WriteLine("Collecting Meshes"); #endif CollectMeshes(out extraMeshes, forcedBounds); AstarProfiler.EndProfile("Finding Meshes"); // A walkableClimb higher than walkableHeight can cause issues when generating the navmesh since then it can in some cases // Both be valid for a character to walk under an obstacle and climb up on top of it (and that cannot be handled with navmesh without links) // The editor scripts also enforce this but we enforce it here too just to be sure walkableClimb = Mathf.Min(walkableClimb, walkableHeight); //Create the voxelizer and set all settings var vox = new Voxelize(cellHeight, cellSize, walkableClimb, walkableHeight, maxSlope); vox.inputExtraMeshes = extraMeshes; vox.maxEdgeLength = maxEdgeLength; int lastInfoCallback = -1; var watch = System.Diagnostics.Stopwatch.StartNew(); //Generate all tiles for (int z = 0; z < td; z++) { for (int x = 0; x < tw; x++) { int tileNum = z * tileXCount + x; #if !NETFX_CORE || UNITY_EDITOR System.Console.WriteLine("Generating Tile #" + (tileNum) + " of " + td * tw); #endif //Call statusCallback only 10 times since it is very slow in the editor if (statusCallback != null && (tileNum * 10 / tiles.Length > lastInfoCallback || watch.ElapsedMilliseconds > 2000)) { lastInfoCallback = tileNum * 10 / tiles.Length; watch.Reset(); watch.Start(); statusCallback(new Progress(Mathf.Lerp(0.1f, 0.9f, tileNum / (float)tiles.Length), "Building Tile " + tileNum + "/" + tiles.Length)); } BuildTileMesh(vox, x, z); } } #if !NETFX_CORE System.Console.WriteLine("Assigning Graph Indices"); #endif if (statusCallback != null) { statusCallback(new Progress(0.9f, "Connecting tiles")); } //Assign graph index to nodes uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this); GraphNodeDelegateCancelable del = delegate(GraphNode n) { n.GraphIndex = graphIndex; return(true); }; GetNodes(del); #if BNICKSON_UPDATED #if DEBUG if (useCenterTileOnly && (3 != tileXCount || 3 != tileZCount)) { EB.Debug.LogError("RecastGenerator.ScanAllTiles() : Incorrect amount of tiles generated if ceneter tile is all that is required"); } #endif int centerXTile = (tileXCount / 2); int centerZTile = (tileZCount / 2); #endif for (int z = 0; z < td; z++) { for (int x = 0; x < tw; x++) { #if BNICKSON_UPDATED // if we're only using the center tile, and this is not the center tile if (useCenterTileOnly && !(centerZTile == z && centerXTile == x)) { continue; } #endif #if !NETFX_CORE System.Console.WriteLine("Connecing Tile #" + (z * tileXCount + x) + " of " + td * tw); #endif if (x < tw - 1) { ConnectTiles(tiles[x + z * tileXCount], tiles[x + 1 + z * tileXCount]); } if (z < td - 1) { ConnectTiles(tiles[x + z * tileXCount], tiles[x + (z + 1) * tileXCount]); } } } AstarProfiler.PrintResults(); }
public override void Scan() { AstarProfiler.Reset(); //AstarProfiler.StartProfile ("Base Scan"); //base.Scan (); //AstarProfiler.EndProfile ("Base Scan"); if (useCRecast) { ScanCRecast(); } else { MeshFilter[] filters; ExtraMesh[] extraMeshes; if (!CollectMeshes(out filters, out extraMeshes)) { nodes = new Node[0]; return; } Voxelize vox = new Voxelize(cellHeight, cellSize, walkableClimb, walkableHeight, maxSlope); vox.maxEdgeLength = maxEdgeLength; vox.forcedBounds = forcedBounds; vox.includeOutOfBounds = includeOutOfBounds; //g.GetComponent<Voxelize>(); vox.VoxelizeMesh(filters, extraMeshes); /*bool[,] open = new bool[width,depth]; * int[,] visited = new int[width+1,depth+1]; * * for (int z=0;z<depth;z++) { * for (int x = 0;x < width;x++) { * open[x,z] = graphNodes[z*width+x].walkable; * } * }*/ /*for (int i=0;i<depth*width;i++) { * open[i] = graphNodes[i].walkable; * } * * * int wd = width*depth; * * List<int> boundary = new List<int>(); * * int p = 0; * * for (int i=0;i<wd;i++) { * if (!open[i]) { * boundary.Add (i); * * p = i; * * int backtrack = i-1; * * * }*/ vox.ErodeWalkableArea(Mathf.CeilToInt(2 * characterRadius / cellSize)); vox.BuildDistanceField(); vox.BuildRegions(); VoxelContourSet cset = new VoxelContourSet(); vox.BuildContours(contourMaxError, 1, cset, Voxelize.RC_CONTOUR_TESS_WALL_EDGES); VoxelMesh mesh; vox.BuildPolyMesh(cset, 3, out mesh); Vector3[] vertices = new Vector3[mesh.verts.Length]; AstarProfiler.StartProfile("Build Nodes"); for (int i = 0; i < vertices.Length; i++) { vertices[i] = (Vector3)mesh.verts[i]; } matrix = Matrix4x4.TRS(vox.voxelOffset, Quaternion.identity, Int3.Precision * Voxelize.CellScale); //Int3.Precision*Voxelize.CellScale+(Int3)vox.voxelOffset //GenerateNodes (this,vectorVertices,triangles, out originalVertices, out _vertices); NavMeshGraph.GenerateNodes(this, vertices, mesh.tris, out _vectorVertices, out _vertices); AstarProfiler.EndProfile("Build Nodes"); AstarProfiler.PrintResults(); } }