예제 #1
0
		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 ();
		}
예제 #2
0
		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;
			});
		}