public bool Contains(GraphNode node) { Vector3 point = (Vector3)node.position; //Debug.DrawRay (node.position,-Vector3.up*2,Color.magenta); if (convex) { if (_convexPoints == null) { return(false); } for (int i = 0, j = _convexPoints.Length - 1; i < _convexPoints.Length; j = i, i++) { if (Polygon.Left(_convexPoints[i], _convexPoints[j], point)) { return(false); } } } else { if (_points == null) { return(false); } return(Polygon.ContainsPoint(_points, point)); } //Debug.DrawRay (node.position,Vector3.up*2,Color.blue); return(true); }
public bool Contains(Vector3 point) { if (this.convex) { if (this._convexPoints == null) { return(false); } int index = 0; int num2 = this._convexPoints.Length - 1; while (index < this._convexPoints.Length) { if (Polygon.Left(this._convexPoints[index], this._convexPoints[num2], point)) { return(false); } num2 = index; index++; } return(true); } if (this._points == null) { return(false); } return(Polygon.ContainsPoint(this._points, point)); }
public bool Contains(Vector3 point) { if (convex) { if (_convexPoints == null) { return(false); } for (int i = 0, j = _convexPoints.Length - 1; i < _convexPoints.Length; j = i, i++) { if (Polygon.Left(_convexPoints[i], _convexPoints[j], point)) { return(false); } } } else { if (_points == null) { return(false); } return(Polygon.ContainsPoint(_points, point)); } return(true); }
// Token: 0x06000142 RID: 322 RVA: 0x0000DFB4 File Offset: 0x0000C3B4 public bool Contains(GraphNode node) { Vector3 p = (Vector3)node.position; if (!this.convex) { return(this._points != null && Polygon.ContainsPoint(this._points, p)); } if (this._convexPoints == null) { return(false); } int i = 0; int num = this._convexPoints.Length - 1; while (i < this._convexPoints.Length) { if (Polygon.Left(this._convexPoints[i], this._convexPoints[num], p)) { return(false); } num = i; i++; } return(true); }
public static Vector3[] ConvexHull(Vector3[] points) { if (points.Length == 0) { return(new Vector3[0]); } object obj = Polygon.hullCache; Vector3[] result; lock (obj) { List <Vector3> list = Polygon.hullCache; list.Clear(); int num = 0; for (int i = 1; i < points.Length; i++) { if (points[i].x < points[num].x) { num = i; } } int num2 = num; int num3 = 0; for (;;) { list.Add(points[num]); int num4 = 0; for (int j = 0; j < points.Length; j++) { if (num4 == num || !Polygon.Left(points[num], points[num4], points[j])) { num4 = j; } } num = num4; num3++; if (num3 > 10000) { break; } if (num == num2) { goto IL_F7; } } Debug.LogWarning("Infinite Loop in Convex Hull Calculation"); IL_F7: result = list.ToArray(); } return(result); }
public override void TangentToTangent(List <AdvancedSmooth.Turn> turnList) { Vector3 dir = Vector3.Cross(AdvancedSmooth.TurnConstructor.t1, Vector3.up); Vector3 vector = AdvancedSmooth.TurnConstructor.current - AdvancedSmooth.TurnConstructor.prev; Vector3 start = vector * 0.5f + AdvancedSmooth.TurnConstructor.prev; vector = Vector3.Cross(vector, Vector3.up); bool flag; this.circleCenter = Polygon.IntersectionPointOptimized(AdvancedSmooth.TurnConstructor.prev, dir, start, vector, out flag); if (!flag) { return; } this.gamma1 = base.Atan2(AdvancedSmooth.TurnConstructor.prev - this.circleCenter); this.gamma2 = base.Atan2(AdvancedSmooth.TurnConstructor.current - this.circleCenter); this.clockwise = !Polygon.Left(this.circleCenter, AdvancedSmooth.TurnConstructor.prev, AdvancedSmooth.TurnConstructor.prev + AdvancedSmooth.TurnConstructor.t1); double num = (!this.clockwise) ? base.CounterClockwiseAngle(this.gamma1, this.gamma2) : base.ClockwiseAngle(this.gamma1, this.gamma2); num = base.GetLengthFromAngle(num, (double)(this.circleCenter - AdvancedSmooth.TurnConstructor.current).magnitude); turnList.Add(new AdvancedSmooth.Turn((float)num, this, 0)); }
public override void TangentToTangent(List <Turn> turnList) { Vector3 preNormal = Vector3.Cross(t1, Vector3.up); //Debug.DrawLine (prev,prev + preNormal*10,Color.cyan); Vector3 dir = (current - prev); Vector3 pos = dir * 0.5F + prev; dir = Vector3.Cross(dir, Vector3.up); //Debug.DrawLine (prev,pos,Color.red); //Debug.DrawLine (pos,pos+dir*2,Color.red); bool didIntersect; circleCenter = Polygon.IntersectionPointOptimized(prev, preNormal, pos, dir, out didIntersect); //Debug.DrawLine (prev,circleCenter); //Debug.DrawLine (circleCenter,current); if (!didIntersect) { return; } gamma1 = Atan2(prev - circleCenter); gamma2 = Atan2(current - circleCenter); clockwise = !Polygon.Left(circleCenter, prev, prev + t1); double beta = clockwise ? ClockwiseAngle(gamma1, gamma2) : CounterClockwiseAngle(gamma1, gamma2); beta = GetLengthFromAngle(beta, (circleCenter - current).magnitude); turnList.Add(new Turn((float)beta, this, 0)); }
public Vector3 ClampMovement(Vector3 direction) { Vector3 vector = direction * this.delta; Vector3 vector2 = base.transform.position + direction; Vector3 vector3 = vector2; float num = 0f; int num2 = 0; this.vos.Clear(); float magnitude = this.velocity.magnitude; LocalAvoidance[] array = this.agents; for (int i = 0; i < array.Length; i++) { LocalAvoidance localAvoidance = array[i]; if (!(localAvoidance == this) && !(localAvoidance == null)) { Vector3 vector4 = localAvoidance.transform.position - base.transform.position; float magnitude2 = vector4.magnitude; float num3 = this.radius + localAvoidance.radius; if (magnitude2 <= vector.magnitude * this.delta + num3 + magnitude + localAvoidance.GetVelocity().magnitude) { if (num2 <= 50) { num2++; LocalAvoidance.VO vO = new LocalAvoidance.VO(); vO.origin = base.transform.position + Vector3.Lerp(this.velocity * this.delta, localAvoidance.GetVelocity() * this.delta, this.responability); vO.direction = vector4.normalized; if (num3 > vector4.magnitude) { vO.angle = 1.57079637f; } else { vO.angle = (float)Math.Asin((double)(num3 / magnitude2)); } vO.limit = magnitude2 - num3; if (vO.limit < 0f) { vO.origin += vO.direction * vO.limit; vO.limit = 0f; } float num4 = Mathf.Atan2(vO.direction.z, vO.direction.x); vO.pRight = new Vector3(Mathf.Cos(num4 + vO.angle), 0f, Mathf.Sin(num4 + vO.angle)); vO.pLeft = new Vector3(Mathf.Cos(num4 - vO.angle), 0f, Mathf.Sin(num4 - vO.angle)); vO.nLeft = new Vector3(Mathf.Cos(num4 + vO.angle - 1.57079637f), 0f, Mathf.Sin(num4 + vO.angle - 1.57079637f)); vO.nRight = new Vector3(Mathf.Cos(num4 - vO.angle + 1.57079637f), 0f, Mathf.Sin(num4 - vO.angle + 1.57079637f)); this.vos.Add(vO); } } } } if (this.resType == LocalAvoidance.ResolutionType.Geometric) { for (int j = 0; j < this.vos.Count; j++) { if (this.vos[j].Contains(vector3)) { num = float.PositiveInfinity; if (this.drawGizmos) { Debug.DrawRay(vector3, Vector3.down, Color.red); } vector3 = base.transform.position; break; } } if (this.drawGizmos) { for (int k = 0; k < this.vos.Count; k++) { this.vos[k].Draw(Color.black); } } if (num == 0f) { return(vector); } List <LocalAvoidance.VOLine> list = new List <LocalAvoidance.VOLine>(); for (int l = 0; l < this.vos.Count; l++) { LocalAvoidance.VO vO2 = this.vos[l]; float num5 = (float)Math.Atan2((double)vO2.direction.z, (double)vO2.direction.x); Vector3 vector5 = vO2.origin + new Vector3((float)Math.Cos((double)(num5 + vO2.angle)), 0f, (float)Math.Sin((double)(num5 + vO2.angle))) * vO2.limit; Vector3 vector6 = vO2.origin + new Vector3((float)Math.Cos((double)(num5 - vO2.angle)), 0f, (float)Math.Sin((double)(num5 - vO2.angle))) * vO2.limit; Vector3 end = vector5 + new Vector3((float)Math.Cos((double)(num5 + vO2.angle)), 0f, (float)Math.Sin((double)(num5 + vO2.angle))) * 100f; Vector3 end2 = vector6 + new Vector3((float)Math.Cos((double)(num5 - vO2.angle)), 0f, (float)Math.Sin((double)(num5 - vO2.angle))) * 100f; int num6 = (!Polygon.Left(vO2.origin, vO2.origin + vO2.direction, base.transform.position + this.velocity)) ? 2 : 1; list.Add(new LocalAvoidance.VOLine(vO2, vector5, end, true, 1, num6 == 1)); list.Add(new LocalAvoidance.VOLine(vO2, vector6, end2, true, 2, num6 == 2)); list.Add(new LocalAvoidance.VOLine(vO2, vector5, vector6, false, 3, false)); bool flag = false; bool flag2 = false; if (!flag) { for (int m = 0; m < this.vos.Count; m++) { if (m != l && this.vos[m].Contains(vector5)) { flag = true; break; } } } if (!flag2) { for (int n = 0; n < this.vos.Count; n++) { if (n != l && this.vos[n].Contains(vector6)) { flag2 = true; break; } } } vO2.AddInt(0f, flag, 1); vO2.AddInt(0f, flag2, 2); vO2.AddInt(0f, flag, 3); vO2.AddInt(1f, flag2, 3); } for (int num7 = 0; num7 < list.Count; num7++) { for (int num8 = num7 + 1; num8 < list.Count; num8++) { LocalAvoidance.VOLine vOLine = list[num7]; LocalAvoidance.VOLine vOLine2 = list[num8]; if (vOLine.vo != vOLine2.vo) { float num9; float num10; if (Polygon.IntersectionFactor(vOLine.start, vOLine.end, vOLine2.start, vOLine2.end, out num9, out num10)) { if (num9 >= 0f && num10 >= 0f && (vOLine.inf || num9 <= 1f) && (vOLine2.inf || num10 <= 1f)) { Vector3 p = vOLine.start + (vOLine.end - vOLine.start) * num9; bool flag3 = vOLine.wrongSide || vOLine2.wrongSide; if (!flag3) { for (int num11 = 0; num11 < this.vos.Count; num11++) { if (this.vos[num11] != vOLine.vo && this.vos[num11] != vOLine2.vo && this.vos[num11].Contains(p)) { flag3 = true; break; } } } vOLine.vo.AddInt(num9, flag3, vOLine.id); vOLine2.vo.AddInt(num10, flag3, vOLine2.id); if (this.drawGizmos) { Debug.DrawRay(vOLine.start + (vOLine.end - vOLine.start) * num9, Vector3.up, (!flag3) ? Color.green : Color.magenta); } } } } } } for (int num12 = 0; num12 < this.vos.Count; num12++) { Vector3 vector7; if (this.vos[num12].FinalInts(vector2, base.transform.position + this.velocity, this.drawGizmos, out vector7)) { float sqrMagnitude = (vector7 - vector2).sqrMagnitude; if (sqrMagnitude < num) { vector3 = vector7; num = sqrMagnitude; if (this.drawGizmos) { Debug.DrawLine(vector2 + Vector3.up, vector3 + Vector3.up, Color.red); } } } } if (this.drawGizmos) { Debug.DrawLine(vector2 + Vector3.up, vector3 + Vector3.up, Color.red); } return(Vector3.ClampMagnitude(vector3 - base.transform.position, vector.magnitude * this.maxSpeedScale)); } else { if (this.resType == LocalAvoidance.ResolutionType.Sampled) { Vector3 a = vector; Vector3 normalized = a.normalized; Vector3 a2 = Vector3.Cross(normalized, Vector3.up); int num13 = 10; int num14 = 0; while (num14 < 10) { float num15 = (float)(3.1415926535897931 * (double)this.circlePoint / (double)num13); float num16 = (float)(3.1415926535897931 - (double)this.circlePoint * 3.1415926535897931) * 0.5f; for (int num17 = 0; num17 < num13; num17++) { float num18 = num15 * (float)num17; Vector3 vector8 = base.transform.position + vector - (a * (float)Math.Sin((double)(num18 + num16)) * (float)num14 * this.circleScale + a2 * (float)Math.Cos((double)(num18 + num16)) * (float)num14 * this.circleScale); if (this.CheckSample(vector8, this.vos)) { return(vector8 - base.transform.position); } } num14++; num13 += 2; } for (int num19 = 0; num19 < this.samples.Length; num19++) { Vector3 vector9 = base.transform.position + this.samples[num19].x * a2 + this.samples[num19].z * normalized + this.samples[num19].y * a; if (this.CheckSample(vector9, this.vos)) { return(vector9 - base.transform.position); } } return(Vector3.zero); } return(Vector3.zero); } }
// 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); }
public Vector3 ClampMovement(Vector3 direction) { Vector3 targetDir = direction * delta; Vector3 targetPoint = transform.position + direction; Vector3 bestPoint = targetPoint; float bestPointDist = 0; //float lowestVO = float.PositiveInfinity; int lowestVOCounter = 0; //List<VO> vos = new List<VO> (); vos.Clear(); float velocityMagn = velocity.magnitude; foreach (LocalAvoidance agent in agents) { if (agent == this || agent == null) { continue; } Vector3 rCenter = agent.transform.position - transform.position; float dist = rCenter.magnitude; float doubleRad = (radius + agent.radius); if (dist > targetDir.magnitude * delta + doubleRad + velocityMagn + agent.GetVelocity().magnitude) { continue; } if (lowestVOCounter > maxVOCounter) { continue; } else { lowestVOCounter++; } VO vo = new VO(); vo.origin = transform.position + Vector3.Lerp(velocity * delta, agent.GetVelocity() * delta, responability); vo.direction = rCenter.normalized; if (doubleRad > rCenter.magnitude) { vo.angle = Mathf.PI * 0.5F; /*vo.limit = dist-doubleRad; * if (vo.limit < 0) { * vo.limit = 0.001F; * } * * vos.Add (vo); * continue;*/ //doubleRad = rCenter.magnitude*0.99F; //continue; } else { vo.angle = (float)Math.Asin(doubleRad / dist); } //float n = (float)Math.Tan (Math.Asin ((doubleRad)/rCenter.magnitude))*(rCenter.magnitude-doubleRad); //Vector3 m = (rCenter.magnitude - doubleRad)*rCenter.normalized;//+(agent.velocity+velocity)/2F; /*if (drawGizmos) { * Debug.DrawLine (transform.position,m,Color.red); * Debug.Log (n); * }*/ vo.limit = dist - doubleRad; //m.magnitude; if (vo.limit < 0) { vo.origin += vo.direction * (vo.limit); vo.limit = 0.000F; } float ax = Mathf.Atan2(vo.direction.z, vo.direction.x); vo.pRight = new Vector3(Mathf.Cos(ax + vo.angle), 0, Mathf.Sin(ax + vo.angle)); vo.pLeft = new Vector3(Mathf.Cos(ax - vo.angle), 0, Mathf.Sin(ax - vo.angle)); vo.nLeft = new Vector3(Mathf.Cos(ax + vo.angle - Mathf.PI * 0.5F), 0, Mathf.Sin(ax + vo.angle - Mathf.PI * 0.5F)); vo.nRight = new Vector3(Mathf.Cos(ax - vo.angle + Mathf.PI * 0.5F), 0, Mathf.Sin(ax - vo.angle + Mathf.PI * 0.5F)); //Debug.DrawRay (vo.origin,vo.nLeft,Color.red); //Debug.DrawRay (vo.origin,vo.nRight,Color.magenta); //vo.limit = Mathf.Min (rCenter.magnitude - doubleRad, rCenter.magnitude/2F); //doubleRad /= delta; //doubleRad /= 2; //vo.limit = doubleRad/Mathf.Tan (vo.angle); vos.Add(vo); } if (resType == ResolutionType.Geometric) { //Is there any need to run more calculations for (int i = 0; i < vos.Count; i++) { if (vos[i].Contains(bestPoint)) { bestPointDist = float.PositiveInfinity; if (drawGizmos) { Debug.DrawRay(bestPoint, Vector3.down, Color.red); } bestPoint = transform.position; break; } } if (drawGizmos) { for (int i = 0; i < vos.Count; i++) { vos[i].Draw(Color.black); /*if (vos[i].Contains (testPoint)) { * Debug.DrawLine (vos[i].origin,testPoint,Color.green); * } else { * Debug.DrawLine (vos[i].origin,testPoint,Color.red); * }*/ } } if (bestPointDist == 0) { return(targetDir); } List <VOLine> lines = new List <VOLine> (); //List<VOIntersection> ints = new List<VOIntersection>(); for (int i = 0; i < vos.Count; i++) { VO vo = vos[i]; float a = (float)Math.Atan2(vo.direction.z, vo.direction.x); //Vector3 cross = Vector3.Cross (vo.direction,Vector3.up); //Vector3 p1 = cross*(float)Math.Tan (vo.angle)*vo.limit; Vector3 pLeft = vo.origin + new Vector3((float)Math.Cos(a + vo.angle), 0, (float)Math.Sin(a + vo.angle)) * vo.limit; Vector3 pRight = vo.origin + new Vector3((float)Math.Cos(a - vo.angle), 0, (float)Math.Sin(a - vo.angle)) * vo.limit; //Vector3 pLeft = vo.origin+vo.direction*vo.limit+p1; //Vector3 pRight = vo.origin+vo.direction*vo.limit-p1; Vector3 pLeft2 = pLeft + new Vector3((float)Math.Cos(a + vo.angle), 0, (float)Math.Sin(a + vo.angle)) * 100; Vector3 pRight2 = pRight + new Vector3((float)Math.Cos(a - vo.angle), 0, (float)Math.Sin(a - vo.angle)) * 100; int IgnoreDirection = Polygon.Left(vo.origin, vo.origin + vo.direction, transform.position + velocity) ? 1 : 2; //Vector3.Dot (transform.position+velocity-vo.origin,cross) > 0 ? 2 : 1;//(pRight-(transform.position+velocity)).sqrMagnitude < (pLeft-(transform.position+velocity)).sqrMagnitude ? 2 : 1;//Vector3.Dot (pRight-pLeft,transform.position+velocity-pLeft) > 0 ? 1 : 2; lines.Add(new VOLine(vo, pLeft, pLeft2, true, 1, IgnoreDirection == 1)); lines.Add(new VOLine(vo, pRight, pRight2, true, 2, IgnoreDirection == 2)); lines.Add(new VOLine(vo, pLeft, pRight, false, 3, false)); bool pLeftInside = false; // || IgnoreDirection == 1; bool pRightInside = false; // || IgnoreDirection == 2; if (!pLeftInside) { for (int q = 0; q < vos.Count; q++) { if (q != i) { if (vos[q].Contains(pLeft)) { pLeftInside = true; break; } } } } if (!pRightInside) { for (int q = 0; q < vos.Count; q++) { if (q != i) { if (vos[q].Contains(pRight)) { pRightInside = true; break; } } } } vo.AddInt(0, pLeftInside, 1); //pLeftInside || IgnoreDirection == 1,1); vo.AddInt(0, pRightInside, 2); //pRightInside || IgnoreDirection == 2,2); vo.AddInt(0, pLeftInside, 3); //pLeftInside ,3);//@ Ignore shouldn't really be there, but it works better with it of some reason vo.AddInt(1, pRightInside, 3); //pRightInside ,3);//@ Ignore shouldn't really be there, but it works better with it of some reason } for (int i = 0; i < lines.Count; i++) { for (int j = i + 1; j < lines.Count; j++) { //if (i==j) continue; VOLine line = lines[i]; VOLine line2 = lines[j]; if (line.vo == line2.vo) { continue; } float factor1; float factor2; if (Polygon.IntersectionFactor(line.start, line.end, line2.start, line2.end, out factor1, out factor2)) { if (factor1 < 0 || factor2 < 0 || (!line.inf && factor1 > 1) || (!line2.inf && factor2 > 1)) { continue; } Vector3 p = line.start + (line.end - line.start) * factor1; bool inside = line.wrongSide || line2.wrongSide; if (!inside) { for (int q = 0; q < vos.Count; q++) { if (vos[q] != line.vo && vos[q] != line2.vo) { if (vos[q].Contains(p)) { inside = true; break; } } } } line.vo.AddInt(factor1, inside, line.id); line2.vo.AddInt(factor2, inside, line2.id); //ints.Add (new VOIntersection (line.vo,line2.vo, factor1, factor2,inside)); if (drawGizmos) { Debug.DrawRay(line.start + (line.end - line.start) * factor1, Vector3.up, inside ? Color.magenta : Color.green); } } } } for (int i = 0; i < vos.Count; i++) { Vector3 segmClosest; if (vos[i].FinalInts(targetPoint, transform.position + velocity, drawGizmos, out segmClosest)) { float dist = (segmClosest - targetPoint).sqrMagnitude; if (dist < bestPointDist) { bestPoint = segmClosest; bestPointDist = dist; if (drawGizmos) { Debug.DrawLine(targetPoint + Vector3.up, bestPoint + Vector3.up, Color.red); } } } } //} if (drawGizmos) { Debug.DrawLine(targetPoint + Vector3.up, bestPoint + Vector3.up, Color.red); } return(Vector3.ClampMagnitude(bestPoint - transform.position, targetDir.magnitude * maxSpeedScale)); } else if (resType == ResolutionType.Sampled) { /*Sampling Solution * ================= */ Vector3 forward = targetDir; Vector3 normForward = forward.normalized; Vector3 right = Vector3.Cross(normForward, Vector3.up); int circleSamples = 10; for (int i = 0; i < 10; i++, circleSamples += 2) { float radPerSamples = (float)(Math.PI * circlePoint / circleSamples); float offset = (float)(Math.PI - circlePoint * Math.PI) * 0.5F; for (int j = 0; j < circleSamples; j++) { float a = radPerSamples * j; Vector3 sample = transform.position + targetDir - (forward * (float)Math.Sin(a + offset) * i * circleScale + right * (float)Math.Cos(a + offset) * i * circleScale); if (CheckSample(sample, vos)) { return(sample - transform.position); } } } for (int i = 0; i < samples.Length; i++) { Vector3 sample = transform.position + samples[i].x * right + samples[i].z * normForward + samples[i].y * forward; if (CheckSample(sample, vos)) { return(sample - transform.position); } } return(Vector3.zero); /* End of Sampling Solution * ======================== */ } return(Vector3.zero); //if (drawGizmos) { /*HalfPlane[] hps = new HalfPlane[vos.Count]; * for (int i=0;i<vos.Count;i++) { * HalfPlane hp = (HalfPlane)vos[i]; * hps[i] = hp; * } * * /*HalfPlane hp_top = new HalfPlane (); * hp_top.point = transform.position+Vector3.forward*speed; * hp_top.normal = -new Vector3 (0.001F,0,1F).normalized; * hps[vos.Count+0] = hp_top; * * HalfPlane hp_bot = new HalfPlane (); * hp_bot.point = transform.position-Vector3.forward*speed; * hp_bot.normal = new Vector3 (0.001F,0,1F).normalized; * hps[vos.Count+1] = hp_bot; * * HalfPlane hp_left = new HalfPlane (); * hp_left.point = transform.position-Vector3.right*speed; * hp_left.normal = new Vector3 (1F,0,0.001F).normalized; * hps[vos.Count+2] = hp_left; * * HalfPlane hp_right = new HalfPlane (); * hp_right.point = transform.position+Vector3.right*speed; * hp_right.normal = -new Vector3 (1F,0,0.001F).normalized; * hps[vos.Count+3] = hp_right;* * * for (int i=0;i<hps.Length;i++) { * if (drawGizmos) { hps[i].Draw (); } * } * * for (int i=0;i<hps.Length;i++) { * HalfPlane hp = hps[i]; * if (hp.Contains (bestPoint)) { * if (drawGizmos) { * Debug.DrawLine (bestPoint,hp.point,Color.green); * } * continue; * } * * * Vector3 tangent = Vector3.Cross (hp.normal,Vector3.up); * * float leftBound = -100; * float rightBound = 100; * * if (tangent.x < 0) { * tangent = -tangent; * } * * for (int j=0;j<i;j++) { * HalfPlane hp2 = hps[j]; * Vector3 intersection = hp.Intersection (hp2); * * float dot = Vector3.Dot (tangent,hp2.normal); * if (dot > 0) { * leftBound = Mathf.Max (leftBound,intersection.x); * } else if (dot < 0) { * rightBound = Mathf.Min (rightBound,intersection.x); * } else { * //Parallel * if (Vector3.Dot (hp.normal,hp2.normal) < 0) { * if (drawGizmos) { * Debug.DrawLine (bestPoint,hp.point,Color.red); * } * return Vector3.zero; * } * } * /*if (hp.normal.x > hp2.normal.x) { * if (hp2.normal.x < 0) { * rightBound = Mathf.Min (intersection.x, rightBound); * } else { * leftBound = Mathf.Max (leftBound,intersection.x); * } * } else if (hp.normal.x < hp2.normal.x) { * if (hp2.normal.x < 0) { * leftBound = Mathf.Max (leftBound,intersection.x); * } else { * rightBound = Mathf.Min (rightBound,intersection.x); * } * }* * } * * if (drawGizmos) { * hp.DrawBounds (leftBound,rightBound); * } * if (leftBound > rightBound) { * if (drawGizmos) { * Debug.DrawRay (bestPoint,Vector3.up,Color.red); * Debug.DrawLine (bestPoint,hp.point,Color.red); * } * return Vector3.zero; * } * * Vector3 closest = hp.ClosestPoint (targetPoint,leftBound,rightBound); * if (drawGizmos) { * Debug.DrawLine (bestPoint,closest,Color.red); * } * bestPoint = closest; * } * * return bestPoint-transform.position;*/ }
public static bool Intersects(Int3 a, Int3 b, Int3 a2, Int3 b2) { return(Polygon.Left(a, b, a2) != Polygon.Left(a, b, b2) && Polygon.Left(a2, b2, a) != Polygon.Left(a2, b2, b)); }
public static bool Intersects(VInt2 a, VInt2 b, VInt2 a2, VInt2 b2) { return(Polygon.Left(a, b, a2) != Polygon.Left(a, b, b2) && Polygon.Left(a2, b2, a) != Polygon.Left(a2, b2, b)); }
/** 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 List <Vector3> SmoothOffsetSimple(List <Vector3> path) { if (path.Count <= 2 || this.iterations <= 0) { return(path); } if (this.iterations > 12) { Debug.LogWarning("A very high iteration count was passed, won't let this one through"); return(path); } int num = (path.Count - 2) * (int)Mathf.Pow(2f, (float)this.iterations) + 2; List <Vector3> list = ListPool <Vector3> .Claim(num); List <Vector3> list2 = ListPool <Vector3> .Claim(num); for (int i = 0; i < num; i++) { list.Add(Vector3.zero); list2.Add(Vector3.zero); } for (int j = 0; j < path.Count; j++) { list[j] = path[j]; } for (int k = 0; k < this.iterations; k++) { int num2 = (path.Count - 2) * (int)Mathf.Pow(2f, (float)k) + 2; List <Vector3> list3 = list; list = list2; list2 = list3; for (int l = 0; l < num2 - 1; l++) { Vector3 vector = list2[l]; Vector3 vector2 = list2[l + 1]; Vector3 normalized = Vector3.Cross(vector2 - vector, Vector3.up).normalized; bool flag = false; bool flag2 = false; bool flag3 = false; bool flag4 = false; if (l != 0 && !Polygon.IsColinear(vector, vector2, list2[l - 1])) { flag3 = true; flag = Polygon.Left(vector, vector2, list2[l - 1]); } if (l < num2 - 1 && !Polygon.IsColinear(vector, vector2, list2[l + 2])) { flag4 = true; flag2 = Polygon.Left(vector, vector2, list2[l + 2]); } if (flag3) { list[l * 2] = vector + ((!flag) ? (-normalized * this.offset * 1f) : (normalized * this.offset * 1f)); } else { list[l * 2] = vector; } if (flag4) { list[l * 2 + 1] = vector2 + ((!flag2) ? (-normalized * this.offset * 1f) : (normalized * this.offset * 1f)); } else { list[l * 2 + 1] = vector2; } } list[(path.Count - 2) * (int)Mathf.Pow(2f, (float)(k + 1)) + 2 - 1] = list2[num2 - 1]; } ListPool <Vector3> .Release(list2); return(list); }
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 static bool IsClockwiseMargin(Int2 a, Int2 b, Int2 c) { return(Polygon.Left(a, b, c)); }
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 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 static bool IntersectsUnclamped(Vector3 a, Vector3 b, Vector3 a2, Vector3 b2) { return(Polygon.Left(a, b, a2) != Polygon.Left(a, b, b2)); }
public List <Vector3> SmoothOffsetSimple(List <Vector3> path) { if (path.Count <= 2 || iterations <= 0) { return(path); } if (iterations > 12) { Debug.LogWarning("A very high iteration count was passed, won't let this one through"); return(path); } int maxLength = (path.Count - 2) * (int)Mathf.Pow(2, iterations) + 2; List <Vector3> subdivided = ListPool <Vector3> .Claim(maxLength); //new Vector3[(path.Length-2)*(int)Mathf.Pow(2,iterations)+2]; List <Vector3> subdivided2 = ListPool <Vector3> .Claim(maxLength); //new Vector3[(path.Length-2)*(int)Mathf.Pow(2,iterations)+2]; for (int i = 0; i < maxLength; i++) { subdivided.Add(Vector3.zero); subdivided2.Add(Vector3.zero); } for (int i = 0; i < path.Count; i++) { subdivided[i] = path[i]; } for (int iteration = 0; iteration < iterations; iteration++) { int currentPathLength = (path.Count - 2) * (int)Mathf.Pow(2, iteration) + 2; //Switch the arrays List <Vector3> tmp = subdivided; subdivided = subdivided2; subdivided2 = tmp; float nextMultiplier = 1F; for (int i = 0; i < currentPathLength - 1; i++) { Vector3 current = subdivided2[i]; Vector3 next = subdivided2[i + 1]; Vector3 normal = Vector3.Cross(next - current, Vector3.up); normal = normal.normalized; //This didn't work very well, made the path jaggy /*Vector3 dir = next-current; * dir *= strength*0.5F; * current += dir; * next -= dir;*/ bool firstRight = false; bool secondRight = false; bool setFirst = false; bool setSecond = false; if (i != 0 && !Polygon.IsColinear(current, next, subdivided2[i - 1])) { setFirst = true; firstRight = Polygon.Left(current, next, subdivided2[i - 1]); } if (i < currentPathLength - 1 && !Polygon.IsColinear(current, next, subdivided2[i + 2])) { setSecond = true; secondRight = Polygon.Left(current, next, subdivided2[i + 2]); } if (setFirst) { subdivided[i * 2] = current + (firstRight ? normal * offset * nextMultiplier : -normal * offset * nextMultiplier); } else { subdivided[i * 2] = current; } //Didn't work very well /*if (setFirst && setSecond) { * if (firstRight != secondRight) { * nextMultiplier = 0.5F; * } else { * nextMultiplier = 1F; * } * }*/ if (setSecond) { subdivided[i * 2 + 1] = next + (secondRight ? normal * offset * nextMultiplier : -normal * offset * nextMultiplier); } else { subdivided[i * 2 + 1] = next; } } subdivided[(path.Count - 2) * (int)Mathf.Pow(2, iteration + 1) + 2 - 1] = subdivided2[currentPathLength - 1]; } ListPool <Vector3> .Release(subdivided2); return(subdivided); }
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); }