GetNearestForce() public method

Returns the nearest node to a position using the specified constraint.
public GetNearestForce ( Vector3 position, NNConstraint constraint ) : NNInfo
position Vector3 /// A ///
constraint NNConstraint /// A ///
return NNInfo
        /** Will calculate a number of points around \a p which are on the graph and are separated by \a clearance from each other.
         * The maximum distance from \a p to any point will be \a radius.
         * Points will first be tried to be laid out as \a previousPoints and if that fails, random points will be selected.
         * This is great if you want to pick a number of target points for group movement. If you pass all current agent points from e.g the group's average position
         * this method will return target points so that the units move very little within the group, this is often aesthetically pleasing and reduces jitter if using
         * some kind of local avoidance.
         *
         * \param g The graph to use for linecasting. If you are only using one graph, you can get this by AstarPath.active.graphs[0] as IRaycastableGraph.
         * Note that not all graphs are raycastable, recast, navmesh and grid graphs are raycastable. On recast and navmesh it works the best.
         * \param previousPoints The points to use for reference. Note that these should not be in world space. They are treated as relative to \a p.
         */
        public static void GetPointsAroundPoint(Vector3 p, IRaycastableGraph g, List <Vector3> previousPoints, float radius, float clearanceRadius)
        {
            if (g == null)
            {
                throw new System.ArgumentNullException("g");
            }

            NavGraph graph = g as NavGraph;

            if (graph == null)
            {
                throw new System.ArgumentException("g is not a NavGraph");
            }

            NNInfo nn = graph.GetNearestForce(p, NNConstraint.Default);

            p = nn.clampedPosition;

            if (nn.node == null)
            {
                // No valid point to start from
                return;
            }


            // Make sure the enclosing circle has a radius which can pack circles with packing density 0.5
            radius           = Mathf.Max(radius, 1.4142f * clearanceRadius * Mathf.Sqrt(previousPoints.Count));//Mathf.Sqrt(previousPoints.Count*clearanceRadius*2));
            clearanceRadius *= clearanceRadius;

            for (int i = 0; i < previousPoints.Count; i++)
            {
                Vector3 dir  = previousPoints[i];
                float   magn = dir.magnitude;

                if (magn > 0)
                {
                    dir /= magn;
                }

                float newMagn = radius;                //magn > radius ? radius : magn;
                dir *= newMagn;

                bool worked = false;

                GraphHitInfo hit;

                int tests = 0;
                do
                {
                    Vector3 pt = p + dir;

                    if (g.Linecast(p, pt, nn.node, out hit))
                    {
                        pt = hit.point;
                    }

                    for (float q = 0.1f; q <= 1.0f; q += 0.05f)
                    {
                        Vector3 qt = (pt - p) * q + p;
                        worked = true;
                        for (int j = 0; j < i; j++)
                        {
                            if ((previousPoints[j] - qt).sqrMagnitude < clearanceRadius)
                            {
                                worked = false;
                                break;
                            }
                        }

                        if (worked)
                        {
                            previousPoints[i] = qt;
                            break;
                        }
                    }

                    if (!worked)
                    {
                        // Abort after 8 tries
                        if (tests > 8)
                        {
                            worked = true;
                        }
                        else
                        {
                            clearanceRadius *= 0.9f;
                            // This will pick points in 2D closer to the edge of the circle with a higher probability
                            dir   = Random.onUnitSphere * Mathf.Lerp(newMagn, radius, tests / 5);
                            dir.y = 0;
                            tests++;
                        }
                    }
                } while (!worked);
            }
        }
        // Token: 0x060027A4 RID: 10148 RVA: 0x001B33F8 File Offset: 0x001B15F8
        public static void GetPointsAroundPoint(Vector3 center, IRaycastableGraph g, List <Vector3> previousPoints, float radius, float clearanceRadius)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            NavGraph navGraph = g as NavGraph;

            if (navGraph == null)
            {
                throw new ArgumentException("g is not a NavGraph");
            }
            NNInfoInternal nearestForce = navGraph.GetNearestForce(center, NNConstraint.Default);

            center = nearestForce.clampedPosition;
            if (nearestForce.node == null)
            {
                return;
            }
            radius           = Mathf.Max(radius, 1.4142f * clearanceRadius * Mathf.Sqrt((float)previousPoints.Count));
            clearanceRadius *= clearanceRadius;
            int i = 0;

            while (i < previousPoints.Count)
            {
                Vector3 vector    = previousPoints[i];
                float   magnitude = vector.magnitude;
                if (magnitude > 0f)
                {
                    vector /= magnitude;
                }
                float num = radius;
                vector *= num;
                int     num2 = 0;
                Vector3 vector2;
                for (;;)
                {
                    vector2 = center + vector;
                    GraphHitInfo graphHitInfo;
                    if (g.Linecast(center, vector2, nearestForce.node, out graphHitInfo))
                    {
                        if (graphHitInfo.point == Vector3.zero)
                        {
                            num2++;
                            if (num2 > 8)
                            {
                                goto Block_7;
                            }
                        }
                        else
                        {
                            vector2 = graphHitInfo.point;
                        }
                    }
                    bool flag = false;
                    for (float num3 = 0.1f; num3 <= 1f; num3 += 0.05f)
                    {
                        Vector3 vector3 = Vector3.Lerp(center, vector2, num3);
                        flag = true;
                        for (int j = 0; j < i; j++)
                        {
                            if ((previousPoints[j] - vector3).sqrMagnitude < clearanceRadius)
                            {
                                flag = false;
                                break;
                            }
                        }
                        if (flag || num2 > 8)
                        {
                            flag = true;
                            previousPoints[i] = vector3;
                            break;
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                    clearanceRadius *= 0.9f;
                    vector           = UnityEngine.Random.onUnitSphere * Mathf.Lerp(num, radius, (float)(num2 / 5));
                    vector.y         = 0f;
                    num2++;
                }
IL_19D:
                i++;
                continue;
Block_7:
                previousPoints[i] = vector2;
                goto IL_19D;
            }
        }
Esempio n. 3
0
        public static void GetPointsAroundPoint(Vector3 p, IRaycastableGraph g, List <Vector3> previousPoints, float radius, float clearanceRadius)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            NavGraph navGraph = g as NavGraph;

            if (navGraph == null)
            {
                throw new ArgumentException("g is not a NavGraph");
            }
            NNInfoInternal nearestForce = navGraph.GetNearestForce(p, NNConstraint.Default);

            p = nearestForce.clampedPosition;
            if (nearestForce.node == null)
            {
                return;
            }
            radius           = Mathf.Max(radius, 1.4142f * clearanceRadius * Mathf.Sqrt((float)previousPoints.Count));
            clearanceRadius *= clearanceRadius;
            for (int i = 0; i < previousPoints.Count; i++)
            {
                Vector3 vector    = previousPoints[i];
                float   magnitude = vector.magnitude;
                if (magnitude > 0f)
                {
                    vector /= magnitude;
                }
                float num = radius;
                vector *= num;
                bool flag = false;
                int  num2 = 0;
                do
                {
                    Vector3      vector2 = p + vector;
                    GraphHitInfo graphHitInfo;
                    if (g.Linecast(p, vector2, nearestForce.node, out graphHitInfo))
                    {
                        vector2 = graphHitInfo.point;
                    }
                    for (float num3 = 0.1f; num3 <= 1f; num3 += 0.05f)
                    {
                        Vector3 vector3 = (vector2 - p) * num3 + p;
                        flag = true;
                        for (int j = 0; j < i; j++)
                        {
                            if ((previousPoints[j] - vector3).sqrMagnitude < clearanceRadius)
                            {
                                flag = false;
                                break;
                            }
                        }
                        if (flag)
                        {
                            previousPoints[i] = vector3;
                            break;
                        }
                    }
                    if (!flag)
                    {
                        if (num2 > 8)
                        {
                            flag = true;
                        }
                        else
                        {
                            clearanceRadius *= 0.9f;
                            vector           = UnityEngine.Random.onUnitSphere * Mathf.Lerp(num, radius, (float)(num2 / 5));
                            vector.y         = 0f;
                            num2++;
                        }
                    }
                }while (!flag);
            }
        }