/**
         * 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));
        }
Exemple #2
0
    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));
    }