public void UpdateArea (GraphUpdateObject guo) { Bounds b = guo.bounds; b.center -= forcedBounds.min; //Figure out which tiles are affected var r = new IntRect (Mathf.FloorToInt (b.min.x / (tileSizeX*cellSize)), Mathf.FloorToInt (b.min.z / (tileSizeZ*cellSize)), Mathf.FloorToInt (b.max.x / (tileSizeX*cellSize)), Mathf.FloorToInt (b.max.z / (tileSizeZ*cellSize))); //Clamp to bounds r = IntRect.Intersection (r, new IntRect (0,0,tileXCount-1,tileZCount-1)); if (!guo.updatePhysics) { for ( int z=r.ymin;z<=r.ymax;z++) { for ( int x=r.xmin;x<=r.xmax;x++) { NavmeshTile tile = tiles[z*tileXCount + x]; tile.flag = true; } } for ( int z=r.ymin;z<=r.ymax;z++) { for ( int x=r.xmin;x<=r.xmax;x++) { NavmeshTile tile = tiles[z*tileXCount + x]; if ( tile.flag ) { tile.flag = false; NavMeshGraph.UpdateArea (guo, tile); } } } return; } if (!dynamic) { throw new System.Exception ("Recast graph must be marked as dynamic to enable graph updates with updatePhysics = true"); } Voxelize vox = globalVox; if (vox == null) { throw new System.InvalidOperationException ("No Voxelizer object. UpdateAreaInit should have been called before this function."); } AstarProfiler.StartProfile ("Init"); /** \bug No bounds checking */ //r.DebugDraw (Matrix4x4.TRS (forcedBounds.min, Quaternion.identity, new Vector3 (tileSize*cellSize, 1, tileSize*cellSize)), Color.red); //Debug.Break (); AstarProfiler.StartProfile ("RemoveConnections"); for (int x=r.xmin;x<=r.xmax;x++) { for (int z=r.ymin;z<=r.ymax;z++) { RemoveConnectionsFromTile (tiles[x + z*tileXCount]); } } AstarProfiler.EndProfile ("RemoveConnections"); AstarProfiler.StartProfile ("Build Tiles"); for (int x=r.xmin;x<=r.xmax;x++) { for (int z=r.ymin;z<=r.ymax;z++) { BuildTileMesh (vox, x,z); } } AstarProfiler.EndProfile ("Build Tiles"); AstarProfiler.StartProfile ("ConnectTiles"); uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex (this); for (int x=r.xmin;x<=r.xmax;x++) { for (int z=r.ymin;z<=r.ymax;z++) { NavmeshTile tile = tiles[x + z*tileXCount]; GraphNode[] nodes = tile.nodes; for (int i=0;i<nodes.Length;i++) nodes[i].GraphIndex = graphIndex; } } //Connect the newly create tiles with the old tiles and with each other r = r.Expand (1); //Clamp to bounds r = IntRect.Intersection (r, new IntRect (0,0,tileXCount-1,tileZCount-1)); for (int x=r.xmin;x<=r.xmax;x++) { for (int z=r.ymin;z<=r.ymax;z++) { if (x < tileXCount-1 && r.Contains (x+1, z)) { ConnectTiles (tiles[x + z*tileXCount], tiles[x+1 + z*tileXCount]); } if (z < tileZCount-1 && r.Contains (x, z+1)) { ConnectTiles (tiles[x + z*tileXCount], tiles[x + (z+1)*tileXCount]); } } } AstarProfiler.EndProfile ("ConnectTiles"); AstarProfiler.PrintResults (); }
public static void UpdateArea (GraphUpdateObject o, INavmesh graph) { //System.DateTime startTime = System.DateTime.UtcNow; Bounds bounds = o.bounds; Rect r = Rect.MinMaxRect (bounds.min.x,bounds.min.z,bounds.max.x,bounds.max.z); var r2 = new IntRect( Mathf.FloorToInt(bounds.min.x*Int3.Precision), Mathf.FloorToInt(bounds.min.z*Int3.Precision), Mathf.FloorToInt(bounds.max.x*Int3.Precision), Mathf.FloorToInt(bounds.max.z*Int3.Precision) ); var a = new Int3(r2.xmin,0,r2.ymin); var b = new Int3(r2.xmin,0,r2.ymax); var c = new Int3(r2.xmax,0,r2.ymin); var d = new Int3(r2.xmax,0,r2.ymax); graph.GetNodes (_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; for (int v=0;v<3;v++) { Int3 p = node.GetVertex(v); var vert = (Vector3)p; if (r2.Contains (p.x,p.z)) { inside = true; break; } if (vert.x < r.xMin) allLeft++; if (vert.x > r.xMax) allRight++; if (vert.z < r.yMin) allTop++; if (vert.z > r.yMax) allBottom++; } if (!inside) { if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) { return true; } } for (int v=0;v<3;v++) { int v2 = v > 1 ? 0 : v+1; Int3 vert1 = node.GetVertex(v); Int3 vert2 = node.GetVertex(v2); if (Polygon.Intersects (a,b,vert1,vert2)) { inside = true; break; } if (Polygon.Intersects (a,c,vert1,vert2)) { inside = true; break; } if (Polygon.Intersects (c,d,vert1,vert2)) { inside = true; break; } if (Polygon.Intersects (d,b,vert1,vert2)) { inside = true; break; } } if (node.ContainsPoint (a) || node.ContainsPoint (b) || node.ContainsPoint (c) || node.ContainsPoint (d)) { inside = true; } if (!inside) { return true; } o.WillUpdateNode(node); o.Apply (node); return true; }); }