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); IntRect 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) ); /*Vector3 a = new Vector3 (r.xMin,0,r.yMin);// -1 -1 Vector3 b = new Vector3 (r.xMin,0,r.yMax);// -1 1 Vector3 c = new Vector3 (r.xMax,0,r.yMin);// 1 -1 Vector3 d = new Vector3 (r.xMax,0,r.yMax);// 1 1 */ Int3 a = new Int3(r2.xmin,0,r2.ymin); Int3 b = new Int3(r2.xmin,0,r2.ymax); Int3 c = new Int3(r2.xmax,0,r2.ymin); Int3 d = new Int3(r2.xmax,0,r2.ymax); Int3 ia = (Int3)a; Int3 ib = (Int3)b; Int3 ic = (Int3)c; Int3 id = (Int3)d; #if ASTARDEBUG Debug.DrawLine (a,b,Color.white); Debug.DrawLine (a,c,Color.white); Debug.DrawLine (c,d,Color.white); Debug.DrawLine (d,b,Color.white); #endif //for (int i=0;i<nodes.Length;i++) { graph.GetNodes (delegate (GraphNode _node) { TriangleMeshNode 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); Vector3 vert = (Vector3)p; //Vector2 vert2D = new Vector2 (vert.x,vert.z); if (r2.Contains (p.x,p.z)) { //Debug.DrawRay (vert,Vector3.up*10,Color.yellow); 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 (!bounds.Contains (node[v]) { // inside = false; // break; //} } if (!inside) { if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) { return true; } } //Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.yellow); //Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.yellow); //Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.yellow); 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 (ia) || node.ContainsPoint (ib) || node.ContainsPoint (ic) || node.ContainsPoint (id)) { inside = true; } if (!inside) { return true; } o.WillUpdateNode(node); o.Apply (node); /*Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.blue); Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.blue); Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.blue); Debug.Break ();*/ return true; }); //System.DateTime endTime = System.DateTime.UtcNow; //float theTime = (endTime-startTime).Ticks*0.0001F; //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms"); }
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; }); }
public void UpdateArea (GraphUpdateObject guo) { Bounds b = guo.bounds; b.center -= forcedBounds.min; //Figure out which tiles are affected IntRect 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) { Bounds bounds = o.bounds; Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); IntRect r2 = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f)); Int3 a = new Int3(r2.xmin, 0, r2.ymin); Int3 b = new Int3(r2.xmin, 0, r2.ymax); Int3 c = new Int3(r2.xmax, 0, r2.ymin); Int3 d = new Int3(r2.xmax, 0, r2.ymax); int ymin = ((Int3)bounds.min).y; int ymax = ((Int3)bounds.max).y; graph.GetNodes(delegate(GraphNode _node) { TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode; bool flag = false; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < 3; i++) { Int3 vertex = triangleMeshNode.GetVertex(i); Vector3 vector = (Vector3)vertex; if (r2.Contains(vertex.x, vertex.z)) { flag = true; break; } if (vector.x < r.xMin) { num++; } if (vector.x > r.xMax) { num2++; } if (vector.z < r.yMin) { num3++; } if (vector.z > r.yMax) { num4++; } } if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3)) { return(true); } for (int j = 0; j < 3; j++) { int i2 = (j <= 1) ? (j + 1) : 0; Int3 vertex2 = triangleMeshNode.GetVertex(j); Int3 vertex3 = triangleMeshNode.GetVertex(i2); if (VectorMath.SegmentsIntersectXZ(a, b, vertex2, vertex3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vertex2, vertex3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vertex2, vertex3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vertex2, vertex3)) { flag = true; break; } } if (flag || triangleMeshNode.ContainsPoint(a) || triangleMeshNode.ContainsPoint(b) || triangleMeshNode.ContainsPoint(c) || triangleMeshNode.ContainsPoint(d)) { flag = true; } if (!flag) { return(true); } int num5 = 0; int num6 = 0; for (int k = 0; k < 3; k++) { Int3 vertex4 = triangleMeshNode.GetVertex(k); if (vertex4.y < ymin) { num6++; } if (vertex4.y > ymax) { num5++; } } if (num6 == 3 || num5 == 3) { return(true); } o.WillUpdateNode(triangleMeshNode); o.Apply(triangleMeshNode); return(true); }); }
public static void UpdateArea (GraphUpdateObject o, INavmesh graph) { Bounds bounds = o.bounds; // Bounding rectangle with floating point coordinates Rect r = Rect.MinMaxRect (bounds.min.x,bounds.min.z,bounds.max.x,bounds.max.z); // Bounding rectangle with int coordinates 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) ); // Corners of the bounding rectangle 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); var ymin = ((Int3)bounds.min).y; var ymax = ((Int3)bounds.max).y; // Loop through all nodes graph.GetNodes (_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; // Check bounding box rect in XZ plane 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; } } // Check if the polygon edges intersect the bounding rect 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; } } // Check if the node contains any corner of the bounding rect if (inside || node.ContainsPoint (a) || node.ContainsPoint (b) || node.ContainsPoint (c) || node.ContainsPoint (d)) { inside = true; } if (!inside) { return true; } int allAbove = 0; int allBelow = 0; // Check y coordinate for (int v = 0; v < 3; v++) { Int3 p = node.GetVertex(v); var vert = (Vector3)p; if (vert.y < ymin) allBelow++; if (vert.y > ymax) allAbove++; } // Polygon is either completely above the bounding box or completely below it if (allBelow == 3 || allAbove == 3) return true; // Triangle is inside the bounding box! // Update it! o.WillUpdateNode(node); o.Apply (node); return true; }); }
public bool Contains(Vector3 point) { var pi = (Int3)point; return(rect.Contains(pi.x, pi.z)); }
public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { Bounds bounds = o.bounds; Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); IntRect r2 = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f)); Int3 a = new Int3(r2.xmin, 0, r2.ymin); Int3 b = new Int3(r2.xmin, 0, r2.ymax); Int3 c = new Int3(r2.xmax, 0, r2.ymin); Int3 d = new Int3(r2.xmax, 0, r2.ymax); Int3 ia = a; Int3 ib = b; Int3 ic = c; Int3 id = d; graph.GetNodes(delegate(GraphNode _node) { TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode; bool flag = false; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < 3; i++) { Int3 vertex = triangleMeshNode.GetVertex(i); Vector3 vector = (Vector3)vertex; if (r2.Contains(vertex.x, vertex.z)) { flag = true; break; } if (vector.x < r.xMin) { num++; } if (vector.x > r.xMax) { num2++; } if (vector.z < r.yMin) { num3++; } if (vector.z > r.yMax) { num4++; } } if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3)) { return(true); } for (int j = 0; j < 3; j++) { int i2 = (j <= 1) ? (j + 1) : 0; Int3 vertex2 = triangleMeshNode.GetVertex(j); Int3 vertex3 = triangleMeshNode.GetVertex(i2); if (Polygon.Intersects(a, b, vertex2, vertex3)) { flag = true; break; } if (Polygon.Intersects(a, c, vertex2, vertex3)) { flag = true; break; } if (Polygon.Intersects(c, d, vertex2, vertex3)) { flag = true; break; } if (Polygon.Intersects(d, b, vertex2, vertex3)) { flag = true; break; } } if (triangleMeshNode.ContainsPoint(ia) || triangleMeshNode.ContainsPoint(ib) || triangleMeshNode.ContainsPoint(ic) || triangleMeshNode.ContainsPoint(id)) { flag = true; } if (!flag) { return(true); } o.WillUpdateNode(triangleMeshNode); o.Apply(triangleMeshNode); return(true); }); }
public static void UpdateArea(GraphUpdateObject o, INavmesh graph) { Bounds bounds = o.bounds; // Bounding rectangle with floating point coordinates Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z); // Bounding rectangle with int coordinates 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) ); // Corners of the bounding rectangle 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); var ymin = ((Int3)bounds.min).y; var ymax = ((Int3)bounds.max).y; // Loop through all nodes graph.GetNodes(_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; // Check bounding box rect in XZ plane 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); } } // Check if the polygon edges intersect the bounding rect 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 (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2)) { inside = true; break; } } // Check if the node contains any corner of the bounding rect if (inside || node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d)) { inside = true; } if (!inside) { return(true); } int allAbove = 0; int allBelow = 0; // Check y coordinate for (int v = 0; v < 3; v++) { Int3 p = node.GetVertex(v); if (p.y < ymin) { allBelow++; } if (p.y > ymax) { allAbove++; } } // Polygon is either completely above the bounding box or completely below it if (allBelow == 3 || allAbove == 3) { return(true); } // Triangle is inside the bounding box! // Update it! o.WillUpdateNode(node); o.Apply(node); return(true); }); }
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); }); }
// Token: 0x0600251A RID: 9498 RVA: 0x0019D24C File Offset: 0x0019B44C public static void UpdateArea(GraphUpdateObject o, INavmeshHolder graph) { Bounds bounds = graph.transform.InverseTransform(o.bounds); IntRect irect = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.CeilToInt(bounds.max.x * 1000f), Mathf.CeilToInt(bounds.max.z * 1000f)); Int3 a = new Int3(irect.xmin, 0, irect.ymin); Int3 b = new Int3(irect.xmin, 0, irect.ymax); Int3 c = new Int3(irect.xmax, 0, irect.ymin); Int3 d = new Int3(irect.xmax, 0, irect.ymax); int ymin = ((Int3)bounds.min).y; int ymax = ((Int3)bounds.max).y; graph.GetNodes(delegate(GraphNode _node) { TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode; bool flag = false; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < 3; i++) { Int3 vertexInGraphSpace = triangleMeshNode.GetVertexInGraphSpace(i); if (irect.Contains(vertexInGraphSpace.x, vertexInGraphSpace.z)) { flag = true; break; } if (vertexInGraphSpace.x < irect.xmin) { num++; } if (vertexInGraphSpace.x > irect.xmax) { num2++; } if (vertexInGraphSpace.z < irect.ymin) { num3++; } if (vertexInGraphSpace.z > irect.ymax) { num4++; } } if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3)) { return; } for (int j = 0; j < 3; j++) { int i2 = (j > 1) ? 0 : (j + 1); Int3 vertexInGraphSpace2 = triangleMeshNode.GetVertexInGraphSpace(j); Int3 vertexInGraphSpace3 = triangleMeshNode.GetVertexInGraphSpace(i2); if (VectorMath.SegmentsIntersectXZ(a, b, vertexInGraphSpace2, vertexInGraphSpace3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vertexInGraphSpace2, vertexInGraphSpace3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vertexInGraphSpace2, vertexInGraphSpace3)) { flag = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vertexInGraphSpace2, vertexInGraphSpace3)) { flag = true; break; } } if (flag || triangleMeshNode.ContainsPointInGraphSpace(a) || triangleMeshNode.ContainsPointInGraphSpace(b) || triangleMeshNode.ContainsPointInGraphSpace(c) || triangleMeshNode.ContainsPointInGraphSpace(d)) { flag = true; } if (!flag) { return; } int num5 = 0; int num6 = 0; for (int k = 0; k < 3; k++) { Int3 vertexInGraphSpace4 = triangleMeshNode.GetVertexInGraphSpace(k); if (vertexInGraphSpace4.y < ymin) { num6++; } if (vertexInGraphSpace4.y > ymax) { num5++; } } if (num6 == 3 || num5 == 3) { return; } o.WillUpdateNode(triangleMeshNode); o.Apply(triangleMeshNode); }); }
public static void UpdateArea(GraphUpdateObject o, INavmeshHolder graph) { Bounds bounds = graph.transform.InverseTransform(o.bounds); // Bounding rectangle with integer coordinates var irect = new IntRect( Mathf.FloorToInt(bounds.min.x * Int3.Precision), Mathf.FloorToInt(bounds.min.z * Int3.Precision), Mathf.CeilToInt(bounds.max.x * Int3.Precision), Mathf.CeilToInt(bounds.max.z * Int3.Precision) ); // Corners of the bounding rectangle var a = new Int3(irect.xmin, 0, irect.ymin); var b = new Int3(irect.xmin, 0, irect.ymax); var c = new Int3(irect.xmax, 0, irect.ymin); var d = new Int3(irect.xmax, 0, irect.ymax); var ymin = ((Int3)bounds.min).y; var ymax = ((Int3)bounds.max).y; // Loop through all nodes and check if they intersect the bounding box graph.GetNodes(_node => { var node = _node as TriangleMeshNode; bool inside = false; int allLeft = 0; int allRight = 0; int allTop = 0; int allBottom = 0; // Check bounding box rect in XZ plane for (int v = 0; v < 3; v++) { Int3 p = node.GetVertexInGraphSpace(v); if (irect.Contains(p.x, p.z)) { inside = true; break; } if (p.x < irect.xmin) { allLeft++; } if (p.x > irect.xmax) { allRight++; } if (p.z < irect.ymin) { allTop++; } if (p.z > irect.ymax) { allBottom++; } } if (!inside && (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)) { return; } // Check if the polygon edges intersect the bounding rect for (int v = 0; v < 3; v++) { int v2 = v > 1 ? 0 : v + 1; Int3 vert1 = node.GetVertexInGraphSpace(v); Int3 vert2 = node.GetVertexInGraphSpace(v2); if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2)) { inside = true; break; } if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2)) { inside = true; break; } } // Check if the node contains any corner of the bounding rect if (inside || node.ContainsPointInGraphSpace(a) || node.ContainsPointInGraphSpace(b) || node.ContainsPointInGraphSpace(c) || node.ContainsPointInGraphSpace(d)) { inside = true; } if (!inside) { return; } int allAbove = 0; int allBelow = 0; // Check y coordinate for (int v = 0; v < 3; v++) { Int3 p = node.GetVertexInGraphSpace(v); if (p.y < ymin) { allBelow++; } if (p.y > ymax) { allAbove++; } } // Polygon is either completely above the bounding box or completely below it if (allBelow == 3 || allAbove == 3) { return; } // Triangle is inside the bounding box! // Update it! o.WillUpdateNode(node); o.Apply(node); }); }
public void UpdateArea(GraphUpdateObject guo) { Bounds bounds = guo.bounds; bounds.center -= this.forcedBounds.min; IntRect a = new IntRect(Mathf.FloorToInt(bounds.min.x / ((float)this.tileSizeX * this.cellSize)), Mathf.FloorToInt(bounds.min.z / ((float)this.tileSizeZ * this.cellSize)), Mathf.FloorToInt(bounds.max.x / ((float)this.tileSizeX * this.cellSize)), Mathf.FloorToInt(bounds.max.z / ((float)this.tileSizeZ * this.cellSize))); a = IntRect.Intersection(a, new IntRect(0, 0, this.tileXCount - 1, this.tileZCount - 1)); if (!guo.updatePhysics) { for (int i = a.ymin; i <= a.ymax; i++) { for (int j = a.xmin; j <= a.xmax; j++) { RecastGraph.NavmeshTile navmeshTile = this.tiles[i * this.tileXCount + j]; navmeshTile.flag = true; } } for (int k = a.ymin; k <= a.ymax; k++) { for (int l = a.xmin; l <= a.xmax; l++) { RecastGraph.NavmeshTile navmeshTile2 = this.tiles[k * this.tileXCount + l]; if (navmeshTile2.flag) { navmeshTile2.flag = false; NavMeshGraph.UpdateArea(guo, navmeshTile2); } } } return; } if (!this.dynamic) { throw new Exception("Recast graph must be marked as dynamic to enable graph updates with updatePhysics = true"); } Voxelize voxelize = this.globalVox; if (voxelize == null) { throw new InvalidOperationException("No Voxelizer object. UpdateAreaInit should have been called before this function."); } for (int m = a.xmin; m <= a.xmax; m++) { for (int n = a.ymin; n <= a.ymax; n++) { this.RemoveConnectionsFromTile(this.tiles[m + n * this.tileXCount]); } } for (int num = a.xmin; num <= a.xmax; num++) { for (int num2 = a.ymin; num2 <= a.ymax; num2++) { this.BuildTileMesh(voxelize, num, num2); } } uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this); for (int num3 = a.xmin; num3 <= a.xmax; num3++) { for (int num4 = a.ymin; num4 <= a.ymax; num4++) { RecastGraph.NavmeshTile navmeshTile3 = this.tiles[num3 + num4 * this.tileXCount]; GraphNode[] nodes = navmeshTile3.nodes; for (int num5 = 0; num5 < nodes.Length; num5++) { nodes[num5].GraphIndex = graphIndex; } } } a = a.Expand(1); a = IntRect.Intersection(a, new IntRect(0, 0, this.tileXCount - 1, this.tileZCount - 1)); for (int num6 = a.xmin; num6 <= a.xmax; num6++) { for (int num7 = a.ymin; num7 <= a.ymax; num7++) { if (num6 < this.tileXCount - 1 && a.Contains(num6 + 1, num7)) { this.ConnectTiles(this.tiles[num6 + num7 * this.tileXCount], this.tiles[num6 + 1 + num7 * this.tileXCount]); } if (num7 < this.tileZCount - 1 && a.Contains(num6, num7 + 1)) { this.ConnectTiles(this.tiles[num6 + num7 * this.tileXCount], this.tiles[num6 + (num7 + 1) * this.tileXCount]); } } } }
// Token: 0x06000472 RID: 1138 RVA: 0x000259F8 File Offset: 0x00023DF8 public new void UpdateArea(GraphUpdateObject o) { if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount) { Debug.LogWarning("The Grid Graph is not scanned, cannot update area "); return; } Bounds bounds = o.bounds; Vector3 a; Vector3 a2; base.GetBoundsMinMax(bounds, this.inverseMatrix, out a, out a2); int xmin = Mathf.RoundToInt(a.x - 0.5f); int xmax = Mathf.RoundToInt(a2.x - 0.5f); int ymin = Mathf.RoundToInt(a.z - 0.5f); int ymax = Mathf.RoundToInt(a2.z - 0.5f); IntRect intRect = new IntRect(xmin, ymin, xmax, ymax); IntRect intRect2 = intRect; IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); IntRect intRect3 = intRect; bool flag = o.updatePhysics || o.modifyWalkability; bool flag2 = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes; bool preserveExistingNodes = !(o is LayerGridGraphUpdate) || ((LayerGridGraphUpdate)o).preserveExistingNodes; int num = (!o.updateErosion) ? 0 : this.erodeIterations; if (o.trackChangedNodes && flag2) { Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph"); return; } if (o.updatePhysics && !o.modifyWalkability && this.collision.collisionCheck) { Vector3 a3 = new Vector3(this.collision.diameter, 0f, this.collision.diameter) * 0.5f; a -= a3 * 1.02f; a2 += a3 * 1.02f; intRect3 = new IntRect(Mathf.RoundToInt(a.x - 0.5f), Mathf.RoundToInt(a.z - 0.5f), Mathf.RoundToInt(a2.x - 0.5f), Mathf.RoundToInt(a2.z - 0.5f)); intRect2 = IntRect.Union(intRect3, intRect2); } if (flag || num > 0) { intRect2 = intRect2.Expand(num + 1); } IntRect intRect4 = IntRect.Intersection(intRect2, b); if (!flag2) { for (int i = intRect4.xmin; i <= intRect4.xmax; i++) { for (int j = intRect4.ymin; j <= intRect4.ymax; j++) { for (int k = 0; k < this.layerCount; k++) { o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]); } } } } if (o.updatePhysics && !o.modifyWalkability) { this.collision.Initialize(this.matrix, this.nodeSize); intRect4 = IntRect.Intersection(intRect3, b); bool flag3 = false; for (int l = intRect4.xmin; l <= intRect4.xmax; l++) { for (int m = intRect4.ymin; m <= intRect4.ymax; m++) { flag3 |= this.RecalculateCell(l, m, preserveExistingNodes); } } for (int n = intRect4.xmin; n <= intRect4.xmax; n++) { for (int num2 = intRect4.ymin; num2 <= intRect4.ymax; num2++) { for (int num3 = 0; num3 < this.layerCount; num3++) { int num4 = num3 * this.width * this.depth + num2 * this.width + n; LevelGridNode levelGridNode = this.nodes[num4]; if (levelGridNode != null) { this.CalculateConnections(this.nodes, levelGridNode, n, num2, num3); } } } } } intRect4 = IntRect.Intersection(intRect, b); for (int num5 = intRect4.xmin; num5 <= intRect4.xmax; num5++) { for (int num6 = intRect4.ymin; num6 <= intRect4.ymax; num6++) { for (int num7 = 0; num7 < this.layerCount; num7++) { int num8 = num7 * this.width * this.depth + num6 * this.width + num5; LevelGridNode levelGridNode2 = this.nodes[num8]; if (levelGridNode2 != null) { if (flag) { levelGridNode2.Walkable = levelGridNode2.WalkableErosion; if (o.bounds.Contains((Vector3)levelGridNode2.position)) { o.Apply(levelGridNode2); } levelGridNode2.WalkableErosion = levelGridNode2.Walkable; } else if (o.bounds.Contains((Vector3)levelGridNode2.position)) { o.Apply(levelGridNode2); } } } } } if (flag && num == 0) { intRect4 = IntRect.Intersection(intRect2, b); for (int num9 = intRect4.xmin; num9 <= intRect4.xmax; num9++) { for (int num10 = intRect4.ymin; num10 <= intRect4.ymax; num10++) { for (int num11 = 0; num11 < this.layerCount; num11++) { int num12 = num11 * this.width * this.depth + num10 * this.width + num9; LevelGridNode levelGridNode3 = this.nodes[num12]; if (levelGridNode3 != null) { this.CalculateConnections(this.nodes, levelGridNode3, num9, num10, num11); } } } } } else if (flag && num > 0) { IntRect a4 = IntRect.Union(intRect, intRect3).Expand(num); IntRect a5 = a4.Expand(num); a4 = IntRect.Intersection(a4, b); a5 = IntRect.Intersection(a5, b); for (int num13 = a5.xmin; num13 <= a5.xmax; num13++) { for (int num14 = a5.ymin; num14 <= a5.ymax; num14++) { for (int num15 = 0; num15 < this.layerCount; num15++) { int num16 = num15 * this.width * this.depth + num14 * this.width + num13; LevelGridNode levelGridNode4 = this.nodes[num16]; if (levelGridNode4 != null) { bool walkable = levelGridNode4.Walkable; levelGridNode4.Walkable = levelGridNode4.WalkableErosion; if (!a4.Contains(num13, num14)) { levelGridNode4.TmpWalkable = walkable; } } } } } for (int num17 = a5.xmin; num17 <= a5.xmax; num17++) { for (int num18 = a5.ymin; num18 <= a5.ymax; num18++) { for (int num19 = 0; num19 < this.layerCount; num19++) { int num20 = num19 * this.width * this.depth + num18 * this.width + num17; LevelGridNode levelGridNode5 = this.nodes[num20]; if (levelGridNode5 != null) { this.CalculateConnections(this.nodes, levelGridNode5, num17, num18, num19); } } } } this.ErodeWalkableArea(a5.xmin, a5.ymin, a5.xmax + 1, a5.ymax + 1); for (int num21 = a5.xmin; num21 <= a5.xmax; num21++) { for (int num22 = a5.ymin; num22 <= a5.ymax; num22++) { if (!a4.Contains(num21, num22)) { for (int num23 = 0; num23 < this.layerCount; num23++) { int num24 = num23 * this.width * this.depth + num22 * this.width + num21; LevelGridNode levelGridNode6 = this.nodes[num24]; if (levelGridNode6 != null) { levelGridNode6.Walkable = levelGridNode6.TmpWalkable; } } } } } for (int num25 = a5.xmin; num25 <= a5.xmax; num25++) { for (int num26 = a5.ymin; num26 <= a5.ymax; num26++) { for (int num27 = 0; num27 < this.layerCount; num27++) { int num28 = num27 * this.width * this.depth + num26 * this.width + num25; LevelGridNode levelGridNode7 = this.nodes[num28]; if (levelGridNode7 != null) { this.CalculateConnections(this.nodes, levelGridNode7, num25, num26, num27); } } } } } }
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); IntRect 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) ); Int3 a = new Int3(r2.xmin, 0, r2.ymin); Int3 b = new Int3(r2.xmin, 0, r2.ymax); Int3 c = new Int3(r2.xmax, 0, r2.ymin); Int3 d = new Int3(r2.xmax, 0, r2.ymax); Int3 ia = (Int3)a; Int3 ib = (Int3)b; Int3 ic = (Int3)c; Int3 id = (Int3)d; //for (int i=0;i<nodes.Length;i++) { graph.GetNodes(delegate(GraphNode _node) { TriangleMeshNode 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); Vector3 vert = (Vector3)p; //Vector2 vert2D = new Vector2 (vert.x,vert.z); if (r2.Contains(p.x, p.z)) { //Debug.DrawRay (vert,Vector3.up*10,Color.yellow); 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); } } //Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.yellow); //Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.yellow); //Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.yellow); 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(ia) || node.ContainsPoint(ib) || node.ContainsPoint(ic) || node.ContainsPoint(id)) { inside = true; } if (!inside) { return(true); } o.WillUpdateNode(node); o.Apply(node); /*Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.blue); * Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.blue); * Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.blue); * Debug.Break ();*/ return(true); }); //System.DateTime endTime = System.DateTime.UtcNow; //float theTime = (endTime-startTime).Ticks*0.0001F; //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms"); }