GetNodes() public abstract method

public abstract GetNodes ( GraphNodeDelegateCancelable del ) : void
del GraphNodeDelegateCancelable
return void
        // Token: 0x060022EF RID: 8943 RVA: 0x001968C8 File Offset: 0x00194AC8
        public void FloodFill()
        {
            NavGraph[] graphs = this.astar.graphs;
            if (graphs == null)
            {
                return;
            }
            foreach (NavGraph navGraph in graphs)
            {
                if (navGraph != null)
                {
                    navGraph.GetNodes(delegate(GraphNode node)
                    {
                        node.Area = 0U;
                    });
                }
            }
            this.lastUniqueAreaIndex = 0U;
            uint area               = 0U;
            int  forcedSmallAreas   = 0;
            Stack <GraphNode> stack = StackPool <GraphNode> .Claim();

            Action <GraphNode> < > 9__1;
            foreach (NavGraph navGraph2 in graphs)
            {
                if (navGraph2 != null)
                {
                    NavGraph           navGraph3 = navGraph2;
                    Action <GraphNode> action;
                    if ((action = < > 9__1) == null)
                    {
                        action = (< > 9__1 = delegate(GraphNode node)
                        {
                            if (node.Walkable && node.Area == 0U)
                            {
                                uint area = area;
                                area += 1U;
                                uint area2 = area;
                                if (area > 131071U)
                                {
                                    area = area;
                                    area -= 1U;
                                    area2 = area;
                                    int forcedSmallAreas;
                                    if (forcedSmallAreas == 0)
                                    {
                                        forcedSmallAreas = 1;
                                    }
                                    forcedSmallAreas = forcedSmallAreas;
                                    forcedSmallAreas++;
                                }
                                stack.Clear();
                                stack.Push(node);
                                int num = 1;
                                node.Area = area2;
                                while (stack.Count > 0)
                                {
                                    num++;
                                    stack.Pop().FloodFill(stack, area2);
                                }
                            }
                        });
                    }
                    navGraph3.GetNodes(action);
                }
            }
            this.lastUniqueAreaIndex = area;
            if (forcedSmallAreas > 0)
            {
                Debug.LogError(string.Concat(new object[]
                {
                    forcedSmallAreas,
                    " areas had to share IDs. This usually doesn't affect pathfinding in any significant way (you might get 'Searched whole area but could not find target' as a reason for path failure) however some path requests may take longer to calculate (specifically those that fail with the 'Searched whole area' error).The maximum number of areas is ",
                    131071U,
                    "."
                }));
            }
            StackPool <GraphNode> .Release(stack);
        }
Ejemplo n.º 2
0
        public static NNInfo GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
        {
            Int3      pos                   = (Int3)position;
            float     minDist               = -1f;
            GraphNode minNode               = null;
            float     minConstDist          = -1f;
            GraphNode minConstNode          = null;
            float     maxDistSqr            = (!constraint.constrainDistance) ? float.PositiveInfinity : AstarPath.active.maxNearestNodeDistanceSqr;
            GraphNodeDelegateCancelable del = delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode3 = _node as TriangleMeshNode;
                if (accurateNearestNode)
                {
                    Vector3 b            = triangleMeshNode3.ClosestPointOnNode(position);
                    float   sqrMagnitude = ((Vector3)pos - b).sqrMagnitude;
                    if (minNode == null || sqrMagnitude < minDist)
                    {
                        minDist = sqrMagnitude;
                        minNode = triangleMeshNode3;
                    }
                    if (sqrMagnitude < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || sqrMagnitude < minConstDist))
                    {
                        minConstDist = sqrMagnitude;
                        minConstNode = triangleMeshNode3;
                    }
                }
                else if (!triangleMeshNode3.ContainsPoint((Int3)position))
                {
                    float sqrMagnitude2 = (triangleMeshNode3.position - pos).sqrMagnitude;
                    if (minNode == null || sqrMagnitude2 < minDist)
                    {
                        minDist = sqrMagnitude2;
                        minNode = triangleMeshNode3;
                    }
                    if (sqrMagnitude2 < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || sqrMagnitude2 < minConstDist))
                    {
                        minConstDist = sqrMagnitude2;
                        minConstNode = triangleMeshNode3;
                    }
                }
                else
                {
                    int num = AstarMath.Abs(triangleMeshNode3.position.y - pos.y);
                    if (minNode == null || (float)num < minDist)
                    {
                        minDist = (float)num;
                        minNode = triangleMeshNode3;
                    }
                    if ((float)num < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || (float)num < minConstDist))
                    {
                        minConstDist = (float)num;
                        minConstNode = triangleMeshNode3;
                    }
                }
                return(true);
            };

            graph.GetNodes(del);
            NNInfo result = new NNInfo(minNode);

            if (result.node != null)
            {
                TriangleMeshNode triangleMeshNode = result.node as TriangleMeshNode;
                Vector3          clampedPosition  = triangleMeshNode.ClosestPointOnNode(position);
                result.clampedPosition = clampedPosition;
            }
            result.constrainedNode = minConstNode;
            if (result.constrainedNode != null)
            {
                TriangleMeshNode triangleMeshNode2    = result.constrainedNode as TriangleMeshNode;
                Vector3          constClampedPosition = triangleMeshNode2.ClosestPointOnNode(position);
                result.constClampedPosition = constClampedPosition;
            }
            return(result);
        }
Ejemplo n.º 3
0
        /** This performs a linear search through all polygons returning the closest one.
         * This will fill the NNInfo with .node for the closest node not necessarily complying with the NNConstraint, and .constrainedNode with the closest node
         * complying with the NNConstraint.
         * \see GetNearestForce(Node[],Int3[],Vector3,NNConstraint,bool)
         */
        public static NNInfo GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
        {
            Int3 pos = (Int3)position;

            float     minDist = -1;
            GraphNode minNode = null;

            float     minConstDist = -1;
            GraphNode minConstNode = null;

            float maxDistSqr = constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;

            GraphNodeDelegateCancelable del = delegate(GraphNode _node) {
                TriangleMeshNode node = _node as TriangleMeshNode;

                if (accurateNearestNode)
                {
                    Vector3 closest = node.ClosestPointOnNode(position);
                    float   dist    = ((Vector3)pos - closest).sqrMagnitude;

                    if (minNode == null || dist < minDist)
                    {
                        minDist = dist;
                        minNode = node;
                    }

                    if (dist < maxDistSqr && constraint.Suitable(node))
                    {
                        if (minConstNode == null || dist < minConstDist)
                        {
                            minConstDist = dist;
                            minConstNode = node;
                        }
                    }
                }
                else
                {
                    if (!node.ContainsPoint((Int3)position))
                    {
                        float dist = (node.position - pos).sqrMagnitude;
                        if (minNode == null || dist < minDist)
                        {
                            minDist = dist;
                            minNode = node;
                        }

                        if (dist < maxDistSqr && constraint.Suitable(node))
                        {
                            if (minConstNode == null || dist < minConstDist)
                            {
                                minConstDist = dist;
                                minConstNode = node;
                            }
                        }
                    }
                    else
                    {
                        int dist = AstarMath.Abs(node.position.y - pos.y);

                        if (minNode == null || dist < minDist)
                        {
                            minDist = dist;
                            minNode = node;
                        }

                        if (dist < maxDistSqr && constraint.Suitable(node))
                        {
                            if (minConstNode == null || dist < minConstDist)
                            {
                                minConstDist = dist;
                                minConstNode = node;
                            }
                        }
                    }
                }
                return(true);
            };

            graph.GetNodes(del);

            NNInfo nninfo = new NNInfo(minNode);

            //Find the point closest to the nearest triangle

            if (nninfo.node != null)
            {
                TriangleMeshNode node = nninfo.node as TriangleMeshNode;                //minNode2 as MeshNode;

                Vector3 clP = node.ClosestPointOnNode(position);

                nninfo.clampedPosition = clP;
            }

            nninfo.constrainedNode = minConstNode;
            if (nninfo.constrainedNode != null)
            {
                TriangleMeshNode node = nninfo.constrainedNode as TriangleMeshNode;                //minNode2 as MeshNode;

                Vector3 clP = node.ClosestPointOnNode(position);

                nninfo.constClampedPosition = clP;
            }

            return(nninfo);
        }
        /** Floodfills all graphs and updates areas for every node.
         * The different colored areas that you see in the scene view when looking at graphs
         * are called just 'areas', this method calculates which nodes are in what areas.
         * \see Pathfinding.Node.area
         */
        public void FloodFill()
        {
            var graphs = astar.graphs;

            if (graphs == null)
            {
                return;
            }

            // Iterate through all nodes in all graphs
            // and reset their Area field
            for (int i = 0; i < graphs.Length; i++)
            {
                var graph = graphs[i];

                if (graph != null)
                {
                    graph.GetNodes(node => node.Area = 0);
                }
            }

            lastUniqueAreaIndex = 0;
            uint area             = 0;
            int  forcedSmallAreas = 0;

            // Get a temporary stack from a pool
            var stack = Pathfinding.Util.StackPool <GraphNode> .Claim();

            for (int i = 0; i < graphs.Length; i++)
            {
                NavGraph graph = graphs[i];

                if (graph == null)
                {
                    continue;
                }

                graph.GetNodes(node => {
                    if (node.Walkable && node.Area == 0)
                    {
                        area++;

                        uint thisArea = area;

                        if (area > GraphNode.MaxAreaIndex)
                        {
                            // Forced to consider this a small area
                            area--;
                            thisArea = area;

                            // Make sure the first small area is also counted
                            if (forcedSmallAreas == 0)
                            {
                                forcedSmallAreas = 1;
                            }

                            forcedSmallAreas++;
                        }

                        stack.Clear();
                        stack.Push(node);

                        int counter = 1;
                        node.Area   = thisArea;

                        while (stack.Count > 0)
                        {
                            counter++;
                            stack.Pop().FloodFill(stack, thisArea);
                        }
                    }
                });
            }

            lastUniqueAreaIndex = area;

            if (forcedSmallAreas > 0)
            {
                Debug.LogError(forcedSmallAreas + " areas had to share IDs. " +
                               "This usually doesn't affect pathfinding in any significant way (you might get 'Searched whole area but could not find target' as a reason for path failure) " +
                               "however some path requests may take longer to calculate (specifically those that fail with the 'Searched whole area' error)." +
                               "The maximum number of areas is " + GraphNode.MaxAreaIndex + ".");
            }

            // Put back into the pool
            Pathfinding.Util.StackPool <GraphNode> .Release(stack);
        }
Ejemplo n.º 5
0
		/** This performs a linear search through all polygons returning the closest one.
		  * This will fill the NNInfo with .node for the closest node not necessarily complying with the NNConstraint, and .constrainedNode with the closest node
		  * complying with the NNConstraint.
		  * \see GetNearestForce(Node[],Int3[],Vector3,NNConstraint,bool)
		  */
		public static NNInfo GetNearestForceBoth (NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode) {
			Int3 pos = (Int3)position;
			
			float minDist = -1;
			GraphNode minNode = null;
			
			float minConstDist = -1;
			GraphNode minConstNode = null;
			
			float maxDistSqr = constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;
			
			GraphNodeDelegateCancelable del = delegate (GraphNode _node) {
				TriangleMeshNode node = _node as TriangleMeshNode;
				
				if (accurateNearestNode) {
					
					Vector3 closest = node.ClosestPointOnNode (position);
					float dist = ((Vector3)pos-closest).sqrMagnitude;
					
					if (minNode == null || dist < minDist) {
						minDist = dist;
						minNode = node;
					}
					
					if (dist < maxDistSqr && constraint.Suitable (node)) {
						if (minConstNode == null || dist < minConstDist) {
							minConstDist = dist;
							minConstNode = node;
						}
					}
					
				} else {
					
					if (!node.ContainsPoint ((Int3)position)) {
						
						float dist = (node.position-pos).sqrMagnitude;
						if (minNode == null || dist < minDist) {
							minDist = dist;
							minNode = node;
						}
						
						if (dist < maxDistSqr && constraint.Suitable (node)) {
							if (minConstNode == null || dist < minConstDist) {
								minConstDist = dist;
								minConstNode = node;
							}
						}
						
					} else {
					
#if ASTARDEBUG
						Debug.DrawLine ((Vector3)vertices[node.v0],(Vector3)vertices[node.v1],Color.blue);
						Debug.DrawLine ((Vector3)vertices[node.v1],(Vector3)vertices[node.v2],Color.blue);
						Debug.DrawLine ((Vector3)vertices[node.v2],(Vector3)vertices[node.v0],Color.blue);
#endif
						
						int dist = AstarMath.Abs (node.position.y-pos.y);
						
						if (minNode == null || dist < minDist) {
							minDist = dist;
							minNode = node;
						}
						
						if (dist < maxDistSqr && constraint.Suitable (node)) {
							if (minConstNode == null || dist < minConstDist) {
								minConstDist = dist;
								minConstNode = node;
							}
						}
					}
				}
				return true;
			};
			
			graph.GetNodes (del);
			
			NNInfo nninfo = new NNInfo (minNode);
			
			//Find the point closest to the nearest triangle
				
			if (nninfo.node != null) {
				TriangleMeshNode node = nninfo.node as TriangleMeshNode;//minNode2 as MeshNode;
				
				Vector3 clP = node.ClosestPointOnNode (position);
				
				nninfo.clampedPosition = clP;
			}
			
			nninfo.constrainedNode = minConstNode;
			if (nninfo.constrainedNode != null) {
				TriangleMeshNode node = nninfo.constrainedNode as TriangleMeshNode;//minNode2 as MeshNode;
				
				Vector3 clP = node.ClosestPointOnNode (position);
				
				nninfo.constClampedPosition = clP;
			}
			
			return nninfo;
		}
		// Token: 0x0600265D RID: 9821 RVA: 0x001A9B00 File Offset: 0x001A7D00
		public void RecalculateCosts()
		{
			if (this.pivots == null)
			{
				this.RecalculatePivots();
			}
			if (this.mode == HeuristicOptimizationMode.None)
			{
				return;
			}
			this.pivotCount = 0;
			for (int i = 0; i < this.pivots.Length; i++)
			{
				if (this.pivots[i] != null && (this.pivots[i].Destroyed || !this.pivots[i].Walkable))
				{
					throw new Exception("Invalid pivot nodes (destroyed or unwalkable)");
				}
			}
			if (this.mode != HeuristicOptimizationMode.RandomSpreadOut)
			{
				for (int j = 0; j < this.pivots.Length; j++)
				{
					if (this.pivots[j] == null)
					{
						throw new Exception("Invalid pivot nodes (null)");
					}
				}
			}
			Debug.Log("Recalculating costs...");
			this.pivotCount = this.pivots.Length;
			Action<int> startCostCalculation = null;
			int numComplete = 0;
			OnPathDelegate onComplete = delegate(Path path)
			{
				int numComplete = numComplete;
				numComplete++;
				if (numComplete == this.pivotCount)
				{
					this.ApplyGridGraphEndpointSpecialCase();
				}
			};
			startCostCalculation = delegate(int pivotIndex)
			{
				GraphNode pivot = this.pivots[pivotIndex];
				FloodPath floodPath = null;
				floodPath = FloodPath.Construct(pivot, onComplete);
				floodPath.immediateCallback = delegate(Path _p)
				{
					_p.Claim(this);
					MeshNode meshNode = pivot as MeshNode;
					uint costOffset = 0U;
					if (meshNode != null && meshNode.connections != null)
					{
						for (int l = 0; l < meshNode.connections.Length; l++)
						{
							costOffset = Math.Max(costOffset, meshNode.connections[l].cost);
						}
					}
					NavGraph[] graphs = AstarPath.active.graphs;
					Action<GraphNode> <>9__3;
					for (int m = graphs.Length - 1; m >= 0; m--)
					{
						NavGraph navGraph = graphs[m];
						Action<GraphNode> action;
						if ((action = <>9__3) == null)
						{
							action = (<>9__3 = delegate(GraphNode node)
							{
								int num6 = node.NodeIndex * this.pivotCount + pivotIndex;
								this.EnsureCapacity(num6);
								PathNode pathNode = ((IPathInternals)floodPath).PathHandler.GetPathNode(node);
								if (costOffset > 0U)
								{
									this.costs[num6] = ((pathNode.pathID == floodPath.pathID && pathNode.parent != null) ? Math.Max(pathNode.parent.G - costOffset, 0U) : 0U);
									return;
								}
								this.costs[num6] = ((pathNode.pathID == floodPath.pathID) ? pathNode.G : 0U);
							});
						}
						navGraph.GetNodes(action);
					}
					if (this.mode == HeuristicOptimizationMode.RandomSpreadOut && pivotIndex < this.pivots.Length - 1)
					{
						if (this.pivots[pivotIndex + 1] == null)
						{
							int num = -1;
							uint num2 = 0U;
							int num3 = this.maxNodeIndex / this.pivotCount;
							for (int n = 1; n < num3; n++)
							{
								uint num4 = 1073741824U;
								for (int num5 = 0; num5 <= pivotIndex; num5++)
								{
									num4 = Math.Min(num4, this.costs[n * this.pivotCount + num5]);
								}
								GraphNode node2 = ((IPathInternals)floodPath).PathHandler.GetPathNode(n).node;
								if ((num4 > num2 || num == -1) && node2 != null && !node2.Destroyed && node2.Walkable)
								{
									num = n;
									num2 = num4;
								}
							}
							if (num == -1)
							{
								Debug.LogError("Failed generating random pivot points for heuristic optimizations");
								return;
							}
							this.pivots[pivotIndex + 1] = ((IPathInternals)floodPath).PathHandler.GetPathNode(num).node;
						}
						startCostCalculation(pivotIndex + 1);
					}
					_p.Release(this, false);
				};
				AstarPath.StartPath(floodPath, true);
			};
			if (this.mode != HeuristicOptimizationMode.RandomSpreadOut)
			{
				for (int k = 0; k < this.pivots.Length; k++)
				{
					startCostCalculation(k);
				}
			}
			else
			{
				startCostCalculation(0);
			}
			this.dirty = false;
		}
        public void FloodFill()
        {
            if (astar.astarData.graphs == null)
            {
                return;
            }

            uint area = 0;

            lastUniqueAreaIndex = 0;

            if (floodStack == null)
            {
                floodStack = new Stack <GraphNode> (1024);
            }

            Stack <GraphNode> stack = floodStack;

            var graphs = astar.graphs;

            // Iterate through all nodes in all graphs
            // and reset their Area field
            for (int i = 0; i < graphs.Length; i++)
            {
                NavGraph graph = graphs[i];

                if (graph != null)
                {
                    graph.GetNodes(node => {
                        node.Area = 0;
                        return(true);
                    });
                }
            }

            int smallAreasDetected = 0;

            bool warnAboutAreas = false;

            List <GraphNode> smallAreaList = Pathfinding.Util.ListPool <GraphNode> .Claim();

            for (int i = 0; i < graphs.Length; i++)
            {
                NavGraph graph = graphs[i];

                if (graph == null)
                {
                    continue;
                }

                GraphNodeDelegateCancelable del = delegate(GraphNode node) {
                    if (node.Walkable && node.Area == 0)
                    {
                        area++;

                        uint thisArea = area;

                        if (area > GraphNode.MaxAreaIndex)
                        {
                            if (smallAreaList.Count > 0)
                            {
                                GraphNode smallOne = smallAreaList[smallAreaList.Count - 1];
                                thisArea = smallOne.Area;
                                smallAreaList.RemoveAt(smallAreaList.Count - 1);

                                //Flood fill the area again with area ID GraphNode.MaxAreaIndex-1, this identifies a small area
                                stack.Clear();

                                stack.Push(smallOne);
                                smallOne.Area = GraphNode.MaxAreaIndex;

                                while (stack.Count > 0)
                                {
                                    stack.Pop().FloodFill(stack, GraphNode.MaxAreaIndex);
                                }

                                smallAreasDetected++;
                            }
                            else
                            {
                                // Forced to consider this a small area
                                area--;
                                thisArea       = area;
                                warnAboutAreas = true;
                            }
                        }

                        stack.Clear();

                        stack.Push(node);

                        int counter = 1;

                        node.Area = thisArea;

                        while (stack.Count > 0)
                        {
                            counter++;
                            stack.Pop().FloodFill(stack, thisArea);
                        }

                        if (counter < astar.minAreaSize)
                        {
                            smallAreaList.Add(node);
                        }
                    }
                    return(true);
                };

                graph.GetNodes(del);
            }

            lastUniqueAreaIndex = area;

            if (warnAboutAreas)
            {
                Debug.LogError("Too many areas - The maximum number of areas is " + GraphNode.MaxAreaIndex + ". Try raising the A* Inspector -> Settings -> Min Area Size value. Enable the optimization ASTAR_MORE_AREAS under the Optimizations tab.");
            }

            if (smallAreasDetected > 0)
            {
                astar.Log(smallAreasDetected + " small areas were detected (fewer than " + astar.minAreaSize + " nodes)," +
                          "these might have the same IDs as other areas, but it shouldn't affect pathfinding in any significant way (you might get All Nodes Searched as a reason for path failure)." +
                          "\nWhich areas are defined as 'small' is controlled by the 'Min Area Size' variable, it can be changed in the A* inspector-->Settings-->Min Area Size" +
                          "\nThe small areas will use the area id " + GraphNode.MaxAreaIndex);
            }

            Pathfinding.Util.ListPool <GraphNode> .Release(smallAreaList);
        }
Ejemplo n.º 8
0
		void DeserializeNodeReferences (NavGraph graph, GraphNode[] int2Node) {
			var zipIndex = graphIndexInZip[graph];
			var entry = zip["graph"+zipIndex+"_references"+binaryExt];

			if (entry == null) throw new Exception("Node references for graph " + zipIndex + " not found in the data. Was this loaded from an older version of the A* Pathfinding Project?");

			var reader = GetBinaryReader(entry);
			var ctx = new GraphSerializationContext(reader, int2Node, graph.graphIndex);

			graph.GetNodes(node => {
				node.DeserializeReferences(ctx);
				return true;
			});
		}
Ejemplo n.º 9
0
		/** Used to serialize references to other nodes e.g connections.
		 * Nodes use the GraphSerializationContext.GetNodeIdentifier and
		 * GraphSerializationContext.GetNodeFromIdentifier methods
		 * for serialization and deserialization respectively.
		 */
		static byte[] SerializeGraphNodeReferences (NavGraph graph) {
			var stream = new MemoryStream();
			var wr = new BinaryWriter(stream);
			var ctx = new GraphSerializationContext(wr);

			graph.GetNodes(node => {
				node.SerializeReferences(ctx);
				return true;
			});

#if NETFX_CORE
			wr.Dispose();
#else
			wr.Close();
#endif

			var bytes = stream.ToArray();
			return bytes;
		}
Ejemplo n.º 10
0
		public static void UpdateArea (GraphUpdateObject o, NavGraph graph) {
			
			INavmesh navgraph = graph as INavmesh;
			
			if (navgraph == null) { Debug.LogError ("Update Area on NavMesh must be called with a graph implementing INavmesh"); return; }
			
			//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;
			
			
			//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");
		
		}