public static TriangleArea2 ( Vector3 a, Vector3 b, Vector3 c ) : float | ||
a | Vector3 | |
b | Vector3 | |
c | Vector3 | |
return | float |
/** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */ void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices) { Profiler.BeginSample("Init"); if (vectorVertices.Length == 0 || triangles.Length == 0) { originalVertices = vectorVertices; vertices = new Int3[0]; //graph.CreateNodes (0); nodes = new TriangleMeshNode[0]; return; } vertices = new Int3[vectorVertices.Length]; int c = 0; for (int i = 0; i < vertices.Length; i++) { vertices[i] = (Int3)matrix.MultiplyPoint3x4(vectorVertices[i]); } var hashedVerts = new Dictionary <Int3, int> (); var newVertices = new int[vertices.Length]; Profiler.EndSample(); Profiler.BeginSample("Hashing"); for (int i = 0; i < vertices.Length; i++) { if (!hashedVerts.ContainsKey(vertices[i])) { newVertices[c] = i; hashedVerts.Add(vertices[i], c); c++; } } for (int x = 0; x < triangles.Length; x++) { Int3 vertex = vertices[triangles[x]]; triangles[x] = hashedVerts[vertex]; } Int3[] totalIntVertices = vertices; vertices = new Int3[c]; originalVertices = new Vector3[c]; for (int i = 0; i < c; i++) { vertices[i] = totalIntVertices[newVertices[i]]; originalVertices[i] = vectorVertices[newVertices[i]]; } Profiler.EndSample(); Profiler.BeginSample("Constructing Nodes"); nodes = new TriangleMeshNode[triangles.Length / 3]; int graphIndex = active.astarData.GetGraphIndex(this); // Does not have to set this, it is set in ScanInternal //TriangleMeshNode.SetNavmeshHolder ((int)graphIndex,this); for (int i = 0; i < nodes.Length; i++) { nodes[i] = new TriangleMeshNode(active); TriangleMeshNode node = nodes[i]; //new MeshNode (); node.GraphIndex = (uint)graphIndex; node.Penalty = initialPenalty; node.Walkable = true; node.v0 = triangles[i * 3]; node.v1 = triangles[i * 3 + 1]; node.v2 = triangles[i * 3 + 2]; if (!Polygon.IsClockwise(vertices[node.v0], vertices[node.v1], vertices[node.v2])) { //Debug.DrawLine (vertices[node.v0],vertices[node.v1],Color.red); //Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red); //Debug.DrawLine (vertices[node.v2],vertices[node.v0],Color.red); int tmp = node.v0; node.v0 = node.v2; node.v2 = tmp; } if (Polygon.IsColinear(vertices[node.v0], vertices[node.v1], vertices[node.v2])) { Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.red); Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.red); Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.red); } // Make sure position is correctly set node.UpdatePositionFromVertices(); } Profiler.EndSample(); var sides = new Dictionary <Int2, TriangleMeshNode>(); for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3) { sides[new Int2(triangles[i + 0], triangles[i + 1])] = nodes[j]; sides[new Int2(triangles[i + 1], triangles[i + 2])] = nodes[j]; sides[new Int2(triangles[i + 2], triangles[i + 0])] = nodes[j]; } Profiler.BeginSample("Connecting Nodes"); var connections = new List <MeshNode> (); var connectionCosts = new List <uint> (); for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3) { connections.Clear(); connectionCosts.Clear(); TriangleMeshNode node = nodes[j]; for (int q = 0; q < 3; q++) { TriangleMeshNode other; if (sides.TryGetValue(new Int2(triangles[i + ((q + 1) % 3)], triangles[i + q]), out other)) { connections.Add(other); connectionCosts.Add((uint)(node.position - other.position).costMagnitude); } } node.connections = connections.ToArray(); node.connectionCosts = connectionCosts.ToArray(); } Profiler.EndSample(); Profiler.BeginSample("Rebuilding BBTree"); RebuildBBTree(this); Profiler.EndSample(); #if ASTARDEBUG for (int i = 0; i < nodes.Length; i++) { TriangleMeshNode node = nodes[i] as TriangleMeshNode; float a1 = Polygon.TriangleArea2((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], (Vector3)vertices[node.v2]); long a2 = Polygon.TriangleArea2(vertices[node.v0], vertices[node.v1], vertices[node.v2]); if (a1 * a2 < 0) { Debug.LogError(a1 + " " + a2); } if (Polygon.IsClockwise(vertices[node.v0], vertices[node.v1], vertices[node.v2])) { Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.green); Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.green); Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.green); } else { Debug.DrawLine((Vector3)vertices[node.v0], (Vector3)vertices[node.v1], Color.red); Debug.DrawLine((Vector3)vertices[node.v1], (Vector3)vertices[node.v2], Color.red); Debug.DrawLine((Vector3)vertices[node.v2], (Vector3)vertices[node.v0], Color.red); } } #endif //Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms"); }
/** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other. * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph). * For other node types, only the positions of the nodes will be used. * * clearanceRadius will be reduced if no valid points can be found. */ public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0) { if (nodes == null) { throw new System.ArgumentNullException("nodes"); } if (nodes.Count == 0) { throw new System.ArgumentException("no nodes passed"); } var rnd = new System.Random(); List <Vector3> pts = ListPool <Vector3> .Claim(count); // Square clearanceRadius *= clearanceRadius; if (nodes[0] is TriangleMeshNode #if !ASTAR_NO_GRID_GRAPH || nodes[0] is GridNode #endif ) { //Assume all nodes are triangle nodes or grid nodes List <float> accs = ListPool <float> .Claim(nodes.Count); float tot = 0; for (int i = 0; i < nodes.Count; i++) { var tnode = nodes[i] as TriangleMeshNode; if (tnode != null) { /** \bug Doesn't this need to be divided by 2? */ float a = System.Math.Abs(Polygon.TriangleArea2(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2))); tot += a; accs.Add(tot); } #if !ASTAR_NO_GRID_GRAPH else { var gnode = nodes[i] as GridNode; if (gnode != null) { GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex); float a = gg.nodeSize * gg.nodeSize; tot += a; accs.Add(tot); } else { accs.Add(tot); } } #endif } for (int i = 0; i < count; i++) { //Pick point int testCount = 0; int testLimit = 10; bool worked = false; while (!worked) { worked = true; //If no valid points can be found, progressively lower the clearance radius until such a point is found if (testCount >= testLimit) { clearanceRadius *= 0.8f; testLimit += 10; if (testLimit > 100) { clearanceRadius = 0; } } float tg = (float)rnd.NextDouble() * tot; int v = accs.BinarySearch(tg); if (v < 0) { v = ~v; } if (v >= nodes.Count) { // This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic. worked = false; continue; } var node = nodes[v] as TriangleMeshNode; Vector3 p; if (node != null) { // Find a random point inside the triangle float v1; float v2; do { v1 = (float)rnd.NextDouble(); v2 = (float)rnd.NextDouble(); } while (v1 + v2 > 1); p = ((Vector3)(node.GetVertex(1) - node.GetVertex(0))) * v1 + ((Vector3)(node.GetVertex(2) - node.GetVertex(0))) * v2 + (Vector3)node.GetVertex(0); } else { #if !ASTAR_NO_GRID_GRAPH var gnode = nodes[v] as GridNode; if (gnode != null) { GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex); float v1 = (float)rnd.NextDouble(); float v2 = (float)rnd.NextDouble(); p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize; } else #endif { //Point nodes have no area, so we break directly instead pts.Add((Vector3)nodes[v].position); break; } } // Test if it is some distance away from the other points if (clearanceRadius > 0) { for (int j = 0; j < pts.Count; j++) { if ((pts[j] - p).sqrMagnitude < clearanceRadius) { worked = false; break; } } } if (worked) { pts.Add(p); break; } testCount++; } } ListPool <float> .Release(accs); } else { for (int i = 0; i < count; i++) { pts.Add((Vector3)nodes[rnd.Next(nodes.Count)].position); } } return(pts); }
// Token: 0x060006B1 RID: 1713 RVA: 0x000424C4 File Offset: 0x000408C4 public bool RunFunnel(List <Vector3> left, List <Vector3> right, List <Vector3> funnelPath) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } if (funnelPath == null) { throw new ArgumentNullException("funnelPath"); } if (left.Count != right.Count) { throw new ArgumentException("left and right lists must have equal length"); } if (left.Count <= 3) { return(false); } while (left[1] == left[2] && right[1] == right[2]) { left.RemoveAt(1); right.RemoveAt(1); if (left.Count <= 3) { return(false); } } Vector3 vector = left[2]; if (vector == left[1]) { vector = right[2]; } while (Polygon.IsColinear(left[0], left[1], right[1]) || Polygon.Left(left[1], right[1], vector) == Polygon.Left(left[1], right[1], left[0])) { left.RemoveAt(1); right.RemoveAt(1); if (left.Count <= 3) { return(false); } vector = left[2]; if (vector == left[1]) { vector = right[2]; } } if (!Polygon.IsClockwise(left[0], left[1], right[1]) && !Polygon.IsColinear(left[0], left[1], right[1])) { List <Vector3> list = left; left = right; right = list; } funnelPath.Add(left[0]); Vector3 vector2 = left[0]; Vector3 vector3 = left[1]; Vector3 vector4 = right[1]; int num = 1; int num2 = 1; int i = 2; while (i < left.Count) { if (funnelPath.Count > 2000) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } Vector3 vector5 = left[i]; Vector3 vector6 = right[i]; if (Polygon.TriangleArea2(vector2, vector4, vector6) < 0f) { goto IL_279; } if (vector2 == vector4 || Polygon.TriangleArea2(vector2, vector3, vector6) <= 0f) { vector4 = vector6; num = i; goto IL_279; } funnelPath.Add(vector3); vector2 = vector3; int num3 = num2; vector3 = vector2; vector4 = vector2; num2 = num3; num = num3; i = num3; IL_2DD: i++; continue; IL_279: if (Polygon.TriangleArea2(vector2, vector3, vector5) > 0f) { goto IL_2DD; } if (vector2 == vector3 || Polygon.TriangleArea2(vector2, vector4, vector5) >= 0f) { vector3 = vector5; num2 = i; goto IL_2DD; } funnelPath.Add(vector4); vector2 = vector4; num3 = num; vector3 = vector2; vector4 = vector2; num2 = num3; num = num3; i = num3; goto IL_2DD; } funnelPath.Add(left[left.Count - 1]); return(true); }
/** Calculate a funnel path from the \a left and \a right portal lists. * The result will be appended to \a funnelPath */ public static bool RunFunnel(List <Vector3> left, List <Vector3> right, List <Vector3> funnelPath) { if (left == null) { throw new System.ArgumentNullException("left"); } if (right == null) { throw new System.ArgumentNullException("right"); } if (funnelPath == null) { throw new System.ArgumentNullException("funnelPath"); } if (left.Count != right.Count) { throw new System.ArgumentException("left and right lists must have equal length"); } if (left.Count <= 3) { return(false); } //Remove identical vertices while (left[1] == left[2] && right[1] == right[2]) { //System.Console.WriteLine ("Removing identical left and right"); left.RemoveAt(1); right.RemoveAt(1); if (left.Count <= 3) { return(false); } } Vector3 swPoint = left[2]; if (swPoint == left[1]) { swPoint = right[2]; } //Test while (Polygon.IsColinear(left[0], left[1], right[1]) || Polygon.Left(left[1], right[1], swPoint) == Polygon.Left(left[1], right[1], left[0])) { left.RemoveAt(1); right.RemoveAt(1); if (left.Count <= 3) { return(false); } swPoint = left[2]; if (swPoint == left[1]) { swPoint = right[2]; } } //Switch left and right to really be on the "left" and "right" sides if (!Polygon.IsClockwise(left[0], left[1], right[1]) && !Polygon.IsColinear(left[0], left[1], right[1])) { //System.Console.WriteLine ("Wrong Side 2"); List <Vector3> tmp = left; left = right; right = tmp; } funnelPath.Add(left[0]); Vector3 portalApex = left[0]; Vector3 portalLeft = left[1]; Vector3 portalRight = right[1]; int apexIndex = 0; int rightIndex = 1; int leftIndex = 1; for (int i = 2; i < left.Count; i++) { if (funnelPath.Count > 2000) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } Vector3 pLeft = left[i]; Vector3 pRight = right[i]; /*Debug.DrawLine (portalApex,portalLeft,Color.red); * Debug.DrawLine (portalApex,portalRight,Color.yellow); * Debug.DrawLine (portalApex,left,Color.cyan); * Debug.DrawLine (portalApex,right,Color.cyan);*/ if (Polygon.TriangleArea2(portalApex, portalRight, pRight) >= 0) { if (portalApex == portalRight || Polygon.TriangleArea2(portalApex, portalLeft, pRight) <= 0) { portalRight = pRight; rightIndex = i; } else { funnelPath.Add(portalLeft); portalApex = portalLeft; apexIndex = leftIndex; portalLeft = portalApex; portalRight = portalApex; leftIndex = apexIndex; rightIndex = apexIndex; i = apexIndex; continue; } } if (Polygon.TriangleArea2(portalApex, portalLeft, pLeft) <= 0) { if (portalApex == portalLeft || Polygon.TriangleArea2(portalApex, portalRight, pLeft) >= 0) { portalLeft = pLeft; leftIndex = i; } else { funnelPath.Add(portalRight); portalApex = portalRight; apexIndex = rightIndex; portalLeft = portalApex; portalRight = portalApex; leftIndex = apexIndex; rightIndex = apexIndex; i = apexIndex; continue; } } } funnelPath.Add(left[left.Count - 1]); return(true); }
public static long TriangleArea(Int3 a, Int3 b, Int3 c) { return(Polygon.TriangleArea2(a, b, c)); }
public static float TriangleArea(Vector3 a, Vector3 b, Vector3 c) { return(Polygon.TriangleArea2(a, b, c)); }
public bool FindNextCorners(Vector3 origin, int startIndex, List <Vector3> funnelPath, int numCorners, out bool lastCorner) { lastCorner = false; if (this.left == null) { throw new Exception("left list is null"); } if (this.right == null) { throw new Exception("right list is null"); } if (funnelPath == null) { throw new ArgumentNullException("funnelPath"); } if (this.left.Count != this.right.Count) { throw new ArgumentException("left and right lists must have equal length"); } int count = this.left.Count; if (count == 0) { throw new ArgumentException("no diagonals"); } if (count - startIndex < 3) { funnelPath.Add(this.left[count - 1]); lastCorner = true; return(true); } while (this.left[startIndex + 1] == this.left[startIndex + 2] && this.right[startIndex + 1] == this.right[startIndex + 2]) { startIndex++; if (count - startIndex <= 3) { return(false); } } Vector3 vector = this.left[startIndex + 2]; if (vector == this.left[startIndex + 1]) { vector = this.right[startIndex + 2]; } while (Polygon.IsColinear(origin, this.left[startIndex + 1], this.right[startIndex + 1]) || Polygon.Left(this.left[startIndex + 1], this.right[startIndex + 1], vector) == Polygon.Left(this.left[startIndex + 1], this.right[startIndex + 1], origin)) { startIndex++; if (count - startIndex < 3) { funnelPath.Add(this.left[count - 1]); lastCorner = true; return(true); } vector = this.left[startIndex + 2]; if (vector == this.left[startIndex + 1]) { vector = this.right[startIndex + 2]; } } Vector3 vector2 = origin; Vector3 vector3 = this.left[startIndex + 1]; Vector3 vector4 = this.right[startIndex + 1]; int num = startIndex + 1; int num2 = startIndex + 1; int i = startIndex + 2; while (i < count) { if (funnelPath.Count >= numCorners) { return(true); } if (funnelPath.Count > 2000) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } Vector3 vector5 = this.left[i]; Vector3 vector6 = this.right[i]; if (Polygon.TriangleArea2(vector2, vector4, vector6) < 0f) { goto IL_2FB; } if (vector2 == vector4 || Polygon.TriangleArea2(vector2, vector3, vector6) <= 0f) { vector4 = vector6; num = i; goto IL_2FB; } funnelPath.Add(vector3); vector2 = vector3; int num3 = num2; vector3 = vector2; vector4 = vector2; num2 = num3; num = num3; i = num3; IL_35F: i++; continue; IL_2FB: if (Polygon.TriangleArea2(vector2, vector3, vector5) > 0f) { goto IL_35F; } if (vector2 == vector3 || Polygon.TriangleArea2(vector2, vector4, vector5) >= 0f) { vector3 = vector5; num2 = i; goto IL_35F; } funnelPath.Add(vector4); vector2 = vector4; num3 = num; vector3 = vector2; vector4 = vector2; num2 = num3; num = num3; i = num3; goto IL_35F; } lastCorner = true; funnelPath.Add(this.left[count - 1]); return(true); }
public bool FindNextCorners(Vector3 origin, int startIndex, List <Vector3> funnelPath, int numCorners, out bool lastCorner) { lastCorner = false; if (left == null) { throw new System.Exception("left list is null"); } if (right == null) { throw new System.Exception("right list is null"); } if (funnelPath == null) { throw new System.ArgumentNullException("funnelPath"); } if (left.Count != right.Count) { throw new System.ArgumentException("left and right lists must have equal length"); } int diagonalCount = left.Count; if (diagonalCount == 0) { throw new System.ArgumentException("no diagonals"); } if (diagonalCount - startIndex < 3) { //Direct path funnelPath.Add(left[diagonalCount - 1]); lastCorner = true; return(true); } #if ASTARDEBUG for (int i = startIndex; i < left.Count - 1; i++) { Debug.DrawLine(left[i], left[i + 1], Color.red); Debug.DrawLine(right[i], right[i + 1], Color.magenta); Debug.DrawRay(right[i], Vector3.up, Color.magenta); } for (int i = 0; i < left.Count; i++) { Debug.DrawLine(right[i], left[i], Color.cyan); } #endif //Remove identical vertices while (left[startIndex + 1] == left[startIndex + 2] && right[startIndex + 1] == right[startIndex + 2]) { //System.Console.WriteLine ("Removing identical left and right"); //left.RemoveAt (1); //right.RemoveAt (1); startIndex++; if (diagonalCount - startIndex <= 3) { return(false); } } Vector3 swPoint = left[startIndex + 2]; if (swPoint == left[startIndex + 1]) { swPoint = right[startIndex + 2]; } //Test while (Polygon.IsColinear(origin, left[startIndex + 1], right[startIndex + 1]) || Polygon.Left(left[startIndex + 1], right[startIndex + 1], swPoint) == Polygon.Left(left[startIndex + 1], right[startIndex + 1], origin)) { #if ASTARDEBUG Debug.DrawLine(left[startIndex + 1], right[startIndex + 1], new Color(0, 0, 0, 0.5F)); Debug.DrawLine(origin, swPoint, new Color(0, 0, 0, 0.5F)); #endif //left.RemoveAt (1); //right.RemoveAt (1); startIndex++; if (diagonalCount - startIndex < 3) { //Debug.Log ("#2 " + left.Count + " - " + startIndex + " = " + (left.Count-startIndex)); //Direct path funnelPath.Add(left[diagonalCount - 1]); lastCorner = true; return(true); } swPoint = left[startIndex + 2]; if (swPoint == left[startIndex + 1]) { swPoint = right[startIndex + 2]; } } //funnelPath.Add (origin); Vector3 portalApex = origin; Vector3 portalLeft = left[startIndex + 1]; Vector3 portalRight = right[startIndex + 1]; int apexIndex = startIndex + 0; int rightIndex = startIndex + 1; int leftIndex = startIndex + 1; for (int i = startIndex + 2; i < diagonalCount; i++) { if (funnelPath.Count >= numCorners) { return(true); } if (funnelPath.Count > 2000) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } Vector3 pLeft = left[i]; Vector3 pRight = right[i]; /*Debug.DrawLine (portalApex,portalLeft,Color.red); * Debug.DrawLine (portalApex,portalRight,Color.yellow); * Debug.DrawLine (portalApex,left,Color.cyan); * Debug.DrawLine (portalApex,right,Color.cyan);*/ if (Polygon.TriangleArea2(portalApex, portalRight, pRight) >= 0) { if (portalApex == portalRight || Polygon.TriangleArea2(portalApex, portalLeft, pRight) <= 0) { portalRight = pRight; rightIndex = i; } else { funnelPath.Add(portalLeft); portalApex = portalLeft; apexIndex = leftIndex; portalLeft = portalApex; portalRight = portalApex; leftIndex = apexIndex; rightIndex = apexIndex; i = apexIndex; continue; } } if (Polygon.TriangleArea2(portalApex, portalLeft, pLeft) <= 0) { if (portalApex == portalLeft || Polygon.TriangleArea2(portalApex, portalRight, pLeft) >= 0) { portalLeft = pLeft; leftIndex = i; } else { funnelPath.Add(portalRight); portalApex = portalRight; apexIndex = rightIndex; portalLeft = portalApex; portalRight = portalApex; leftIndex = apexIndex; rightIndex = apexIndex; i = apexIndex; continue; } } } lastCorner = true; funnelPath.Add(left[diagonalCount - 1]); return(true); }
public bool RunFunnel(List <VInt3> left, List <VInt3> right, List <VInt3> funnelPath) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } if (funnelPath == null) { throw new ArgumentNullException("funnelPath"); } if (left.get_Count() != right.get_Count()) { throw new ArgumentException("left and right lists must have equal length"); } if (left.get_Count() <= 3) { return(false); } while (left.get_Item(1) == left.get_Item(2) && right.get_Item(1) == right.get_Item(2)) { left.RemoveAt(1); right.RemoveAt(1); if (left.get_Count() <= 3) { return(false); } } VInt3 vInt = left.get_Item(2); if (vInt == left.get_Item(1)) { vInt = right.get_Item(2); } while (Polygon.IsColinear(left.get_Item(0), left.get_Item(1), right.get_Item(1)) || Polygon.Left(left.get_Item(1), right.get_Item(1), vInt) == Polygon.Left(left.get_Item(1), right.get_Item(1), left.get_Item(0))) { left.RemoveAt(1); right.RemoveAt(1); if (left.get_Count() <= 3) { return(false); } vInt = left.get_Item(2); if (vInt == left.get_Item(1)) { vInt = right.get_Item(2); } } if (!Polygon.IsClockwise(left.get_Item(0), left.get_Item(1), right.get_Item(1)) && !Polygon.IsColinear(left.get_Item(0), left.get_Item(1), right.get_Item(1))) { List <VInt3> list = left; left = right; right = list; } funnelPath.Add(left.get_Item(0)); VInt3 vInt2 = left.get_Item(0); VInt3 vInt3 = left.get_Item(1); VInt3 vInt4 = right.get_Item(1); int num = 1; int num2 = 1; int i = 2; while (i < left.get_Count()) { if (funnelPath.get_Count() > 2000) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } VInt3 vInt5 = left.get_Item(i); VInt3 vInt6 = right.get_Item(i); if (Polygon.TriangleArea2(vInt2, vInt4, vInt6) < 0L) { goto IL_27B; } if (vInt2 == vInt4 || Polygon.TriangleArea2(vInt2, vInt3, vInt6) <= 0L) { vInt4 = vInt6; num = i; goto IL_27B; } funnelPath.Add(vInt3); vInt2 = vInt3; int num3 = num2; vInt3 = vInt2; vInt4 = vInt2; num2 = num3; num = num3; i = num3; IL_270: i++; continue; IL_27B: if (Polygon.TriangleArea2(vInt2, vInt3, vInt5) > 0L) { goto IL_270; } if (vInt2 == vInt3 || Polygon.TriangleArea2(vInt2, vInt4, vInt5) >= 0L) { vInt3 = vInt5; num2 = i; goto IL_270; } funnelPath.Add(vInt4); vInt2 = vInt4; num3 = num; vInt3 = vInt2; vInt4 = vInt2; num2 = num3; num = num3; i = num3; goto IL_270; } funnelPath.Add(left.get_Item(left.get_Count() - 1)); return(true); }
public bool RunFunnel(List <VInt3> left, List <VInt3> right, List <VInt3> funnelPath) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } if (funnelPath == null) { throw new ArgumentNullException("funnelPath"); } if (left.Count != right.Count) { throw new ArgumentException("left and right lists must have equal length"); } if (left.Count <= 3) { return(false); } while ((left[1] == left[2]) && (right[1] == right[2])) { left.RemoveAt(1); right.RemoveAt(1); if (left.Count <= 3) { return(false); } } VInt3 c = left[2]; if (c == left[1]) { c = right[2]; } while (Polygon.IsColinear(left[0], left[1], right[1]) || (Polygon.Left(left[1], right[1], c) == Polygon.Left(left[1], right[1], left[0]))) { left.RemoveAt(1); right.RemoveAt(1); if (left.Count <= 3) { return(false); } c = left[2]; if (c == left[1]) { c = right[2]; } } if (!Polygon.IsClockwise(left[0], left[1], right[1]) && !Polygon.IsColinear(left[0], left[1], right[1])) { List <VInt3> list = left; left = right; right = list; } funnelPath.Add(left[0]); VInt3 a = left[0]; VInt3 b = left[1]; VInt3 num4 = right[1]; int num5 = 0; int num6 = 1; int num7 = 1; for (int i = 2; i < left.Count; i++) { if (funnelPath.Count > 0x7d0) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } VInt3 num9 = left[i]; VInt3 num10 = right[i]; if (Polygon.TriangleArea2(a, num4, num10) >= 0L) { if ((a == num4) || (Polygon.TriangleArea2(a, b, num10) <= 0L)) { num4 = num10; num6 = i; } else { funnelPath.Add(b); a = b; num5 = num7; b = a; num4 = a; num7 = num5; num6 = num5; i = num5; continue; } } if (Polygon.TriangleArea2(a, b, num9) <= 0L) { if ((a == b) || (Polygon.TriangleArea2(a, num4, num9) >= 0L)) { b = num9; num7 = i; } else { funnelPath.Add(num4); a = num4; num5 = num6; b = a; num4 = a; num7 = num5; num6 = num5; i = num5; } } } funnelPath.Add(left[left.Count - 1]); return(true); }
public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0f) { if (nodes == null) { throw new ArgumentNullException("nodes"); } if (nodes.Count == 0) { throw new ArgumentException("no nodes passed"); } System.Random random = new System.Random(); List <Vector3> list = ListPool <Vector3> .Claim(count); clearanceRadius *= clearanceRadius; if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode) { List <float> list2 = ListPool <float> .Claim(nodes.Count); float num = 0f; for (int i = 0; i < nodes.Count; i++) { TriangleMeshNode triangleMeshNode = nodes[i] as TriangleMeshNode; if (triangleMeshNode != null) { float num2 = (float)Math.Abs(Polygon.TriangleArea2(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2))); num += num2; list2.Add(num); } else { GridNode gridNode = nodes[i] as GridNode; if (gridNode != null) { GridGraph gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex); float num3 = gridGraph.nodeSize * gridGraph.nodeSize; num += num3; list2.Add(num); } else { list2.Add(num); } } } for (int j = 0; j < count; j++) { int num4 = 0; int num5 = 10; bool flag = false; while (!flag) { flag = true; if (num4 >= num5) { clearanceRadius *= 0.8f; num5 += 10; if (num5 > 100) { clearanceRadius = 0f; } } float item = (float)random.NextDouble() * num; int num6 = list2.BinarySearch(item); if (num6 < 0) { num6 = ~num6; } if (num6 >= nodes.Count) { flag = false; } else { TriangleMeshNode triangleMeshNode2 = nodes[num6] as TriangleMeshNode; Vector3 vector; if (triangleMeshNode2 != null) { float num7; float num8; do { num7 = (float)random.NextDouble(); num8 = (float)random.NextDouble(); }while (num7 + num8 > 1f); vector = (Vector3)(triangleMeshNode2.GetVertex(1) - triangleMeshNode2.GetVertex(0)) * num7 + (Vector3)(triangleMeshNode2.GetVertex(2) - triangleMeshNode2.GetVertex(0)) * num8 + (Vector3)triangleMeshNode2.GetVertex(0); } else { GridNode gridNode2 = nodes[num6] as GridNode; if (gridNode2 == null) { list.Add((Vector3)nodes[num6].position); break; } GridGraph gridGraph2 = GridNode.GetGridGraph(gridNode2.GraphIndex); float num9 = (float)random.NextDouble(); float num10 = (float)random.NextDouble(); vector = (Vector3)gridNode2.position + new Vector3(num9 - 0.5f, 0f, num10 - 0.5f) * gridGraph2.nodeSize; } if (clearanceRadius > 0f) { for (int k = 0; k < list.Count; k++) { if ((list[k] - vector).sqrMagnitude < clearanceRadius) { flag = false; break; } } } if (flag) { list.Add(vector); break; } num4++; } } } ListPool <float> .Release(list2); } else { for (int l = 0; l < count; l++) { list.Add((Vector3)nodes[random.Next(nodes.Count)].position); } } return(list); }