public GetNearestForce ( Vector3 position, |
||
position | Vector3 |
/// A |
constraint |
/// A |
|
return |
/** 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; } }
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); } }