/** * Returns the nearest node to a position using the specified NNConstraint. * Searches through all graphs for their nearest nodes to the specified position and picks the closest one. * The NNConstraint can be used to specify constraints on which nodes can be chosen such as only picking walkable nodes. * \see Pathfinding.NNConstraint */ public static NNInfo GetNearest(Vector3 position, NNConstraint constraint, GraphNode hint) { // Cache property lookup var localGraphs = GetConfig().graphs; float minDist = float.PositiveInfinity; NNInfoInternal nearestNode = new NNInfoInternal(); int nearestGraph = -1; if (localGraphs != null) { for (int i = 0; i < localGraphs.Length; i++) { NavGraph graph = localGraphs[i]; // Check if this graph should be searched if (graph == null || !constraint.SuitableGraph(i, graph)) { continue; } NNInfoInternal nnInfo; if (GetConfig().fullGetNearestSearch) { // Slower nearest node search // this will try to find a node which is suitable according to the constraint nnInfo = graph.GetNearestForce(position, constraint); } else { // Fast nearest node search // just find a node close to the position without using the constraint that much // (unless that comes essentially 'for free') nnInfo = graph.GetNearest(position, constraint); } GraphNode node = nnInfo.node; // No node found in this graph if (node == null) { continue; } // Distance to the closest point on the node from the requested position float dist = ((Vector3)nnInfo.clampedPosition - position).magnitude; if (GetConfig().prioritizeGraphs&& dist < GetConfig().prioritizeGraphsLimit) { // The node is close enough, choose this graph and discard all others minDist = dist; nearestNode = nnInfo; nearestGraph = i; break; } else { // Choose the best node found so far if (dist < minDist) { minDist = dist; nearestNode = nnInfo; nearestGraph = i; } } } } // No matches found if (nearestGraph == -1) { return(new NNInfo()); } // Check if a constrained node has already been set if (nearestNode.constrainedNode != null) { nearestNode.node = nearestNode.constrainedNode; nearestNode.clampedPosition = nearestNode.constClampedPosition; } if (!GetConfig().fullGetNearestSearch&& nearestNode.node != null && !constraint.Suitable(nearestNode.node)) { // Otherwise, perform a check to force the graphs to check for a suitable node NNInfoInternal nnInfo = localGraphs[nearestGraph].GetNearestForce(position, constraint); if (nnInfo.node != null) { nearestNode = nnInfo; } } if (!constraint.Suitable(nearestNode.node) || (constraint.constrainDistance && (nearestNode.clampedPosition - position).sqrMagnitude > GetConfig().maxNearestNodeDistanceSqr)) { return(new NNInfo()); } // Convert to NNInfo which doesn't have all the internal fields return(new NNInfo(nearestNode)); }
public NNInfo GetNearest(Vector3 position, NNConstraint constraint, GraphNode hint) { NavGraph[] graphs = this.graphs; float num = float.PositiveInfinity; NNInfoInternal nninfoInternal = default(NNInfoInternal); int num2 = -1; if (graphs != null) { for (int i = 0; i < graphs.Length; i++) { NavGraph navGraph = graphs[i]; if (navGraph != null && constraint.SuitableGraph(i, navGraph)) { NNInfoInternal nninfoInternal2; if (this.fullGetNearestSearch) { nninfoInternal2 = navGraph.GetNearestForce(position, constraint); } else { nninfoInternal2 = navGraph.GetNearest(position, constraint); } if (nninfoInternal2.node != null) { float magnitude = (nninfoInternal2.clampedPosition - position).magnitude; if (this.prioritizeGraphs && magnitude < this.prioritizeGraphsLimit) { nninfoInternal = nninfoInternal2; num2 = i; break; } if (magnitude < num) { num = magnitude; nninfoInternal = nninfoInternal2; num2 = i; } } } } } if (num2 == -1) { return(default(NNInfo)); } if (nninfoInternal.constrainedNode != null) { nninfoInternal.node = nninfoInternal.constrainedNode; nninfoInternal.clampedPosition = nninfoInternal.constClampedPosition; } if (!this.fullGetNearestSearch && nninfoInternal.node != null && !constraint.Suitable(nninfoInternal.node)) { NNInfoInternal nearestForce = graphs[num2].GetNearestForce(position, constraint); if (nearestForce.node != null) { nninfoInternal = nearestForce; } } if (!constraint.Suitable(nninfoInternal.node) || (constraint.constrainDistance && (nninfoInternal.clampedPosition - position).sqrMagnitude > this.maxNearestNodeDistanceSqr)) { return(default(NNInfo)); } return(new NNInfo(nninfoInternal)); }