private void CutPoly(ListView <NavmeshCut> InNavmeshCuts, VInt3[] verts, int[] tris, ref VInt3[] outVertsArr, ref int[] outTrisArr, out int outVCount, out int outTCount, VInt3[] extraShape, VInt3 cuttingOffset, Bounds realBounds, SGameTileHandler.CutMode mode = (SGameTileHandler.CutMode) 3, int perturbate = 0) { if (verts.Length == 0 || tris.Length == 0) { outVCount = 0; outTCount = 0; outTrisArr = new int[0]; outVertsArr = new VInt3[0]; return; } List <IntPoint> list = null; if (extraShape == null && (mode & SGameTileHandler.CutMode.CutExtra) != (SGameTileHandler.CutMode) 0) { throw new Exception("extraShape is null and the CutMode specifies that it should be used. Cannot use null shape."); } if ((mode & SGameTileHandler.CutMode.CutExtra) != (SGameTileHandler.CutMode) 0) { list = new List <IntPoint>(extraShape.Length); for (int i = 0; i < extraShape.Length; i++) { list.Add(new IntPoint((long)(extraShape[i].x + cuttingOffset.x), (long)(extraShape[i].z + cuttingOffset.z))); } } List <IntPoint> list2 = new List <IntPoint>(5); Dictionary <TriangulationPoint, int> dictionary = new Dictionary <TriangulationPoint, int>(); List <PolygonPoint> list3 = new List <PolygonPoint>(); IntRect b = new IntRect(verts[0].x, verts[0].z, verts[0].x, verts[0].z); for (int j = 0; j < verts.Length; j++) { b = b.ExpandToContain(verts[j].x, verts[j].z); } List <VInt3> list4 = ListPool <VInt3> .Claim(verts.Length * 2); List <int> list5 = ListPool <int> .Claim(tris.Length); PolyTree polyTree = new PolyTree(); List <List <IntPoint> > list6 = new List <List <IntPoint> >(); Stack <Polygon> stack = new Stack <Polygon>(); if (this.clipper == null) { this.clipper = new Clipper(0); } this.clipper.set_ReverseSolution(true); this.clipper.set_StrictlySimple(true); ListView <NavmeshCut> listView; if (mode == SGameTileHandler.CutMode.CutExtra) { listView = new ListView <NavmeshCut>(); } else { listView = new ListView <NavmeshCut>(InNavmeshCuts); } List <int> list7 = ListPool <int> .Claim(); List <IntRect> list8 = ListPool <IntRect> .Claim(); List <VInt2> list9 = ListPool <VInt2> .Claim(); List <List <IntPoint> > list10 = new List <List <IntPoint> >(); List <bool> list11 = ListPool <bool> .Claim(); List <bool> list12 = ListPool <bool> .Claim(); if (perturbate > 10) { Debug.LogError("Too many perturbations aborting : " + mode); Debug.Break(); outVCount = verts.Length; outTCount = tris.Length; outTrisArr = tris; outVertsArr = verts; return; } Random random = null; if (perturbate > 0) { random = new Random(); } for (int k = 0; k < listView.Count; k++) { Bounds bounds = listView[k].GetBounds(); VInt3 vInt = (VInt3)bounds.min + cuttingOffset; VInt3 vInt2 = (VInt3)bounds.max + cuttingOffset; IntRect a = new IntRect(vInt.x, vInt.z, vInt2.x, vInt2.z); if (IntRect.Intersects(a, b)) { VInt2 vInt3 = new VInt2(0, 0); if (perturbate > 0) { vInt3.x = random.Next() % 6 * perturbate - 3 * perturbate; if (vInt3.x >= 0) { vInt3.x++; } vInt3.y = random.Next() % 6 * perturbate - 3 * perturbate; if (vInt3.y >= 0) { vInt3.y++; } } int count = list10.get_Count(); listView[k].GetContour(list10); for (int l = count; l < list10.get_Count(); l++) { List <IntPoint> list13 = list10.get_Item(l); if (list13.get_Count() == 0) { Debug.LogError("Zero Length Contour"); list8.Add(default(IntRect)); list9.Add(new VInt2(0, 0)); } else { IntRect intRect = new IntRect((int)list13.get_Item(0).X + cuttingOffset.x, (int)list13.get_Item(0).Y + cuttingOffset.y, (int)list13.get_Item(0).X + cuttingOffset.x, (int)list13.get_Item(0).Y + cuttingOffset.y); for (int m = 0; m < list13.get_Count(); m++) { IntPoint intPoint = list13.get_Item(m); intPoint.X += (long)cuttingOffset.x; intPoint.Y += (long)cuttingOffset.z; if (perturbate > 0) { intPoint.X += (long)vInt3.x; intPoint.Y += (long)vInt3.y; } list13.set_Item(m, intPoint); intRect = intRect.ExpandToContain((int)intPoint.X, (int)intPoint.Y); } list9.Add(new VInt2(vInt.y, vInt2.y)); list8.Add(intRect); list11.Add(listView[k].isDual); list12.Add(listView[k].cutsAddedGeom); } } } } ListView <NavmeshAdd> listView2 = new ListView <NavmeshAdd>(); VInt3[] array = verts; int[] array2 = tris; int num = -1; int n = -3; VInt3[] array3 = null; VInt3[] array4 = null; VInt3 vInt4 = VInt3.zero; if (listView2.Count > 0) { array3 = new VInt3[7]; array4 = new VInt3[7]; vInt4 = (VInt3)realBounds.extents; } while (true) { n += 3; while (n >= array2.Length) { num++; n = 0; if (num >= listView2.Count) { array = null; break; } if (array == verts) { array = null; } listView2[num].GetMesh(cuttingOffset, ref array, out array2); } if (array == null) { break; } VInt3 vInt5 = array[array2[n]]; VInt3 vInt6 = array[array2[n + 1]]; VInt3 vInt7 = array[array2[n + 2]]; IntRect a2 = new IntRect(vInt5.x, vInt5.z, vInt5.x, vInt5.z); a2 = a2.ExpandToContain(vInt6.x, vInt6.z); a2 = a2.ExpandToContain(vInt7.x, vInt7.z); int num2 = Math.Min(vInt5.y, Math.Min(vInt6.y, vInt7.y)); int num3 = Math.Max(vInt5.y, Math.Max(vInt6.y, vInt7.y)); list7.Clear(); bool flag = false; for (int num4 = 0; num4 < list10.get_Count(); num4++) { int x = list9.get_Item(num4).x; int y = list9.get_Item(num4).y; if (IntRect.Intersects(a2, list8.get_Item(num4)) && y >= num2 && x <= num3 && (list12.get_Item(num4) || num == -1)) { VInt3 vInt8 = vInt5; vInt8.y = x; VInt3 vInt9 = vInt5; vInt9.y = y; list7.Add(num4); flag |= list11.get_Item(num4); } } if (list7.get_Count() == 0 && (mode & SGameTileHandler.CutMode.CutExtra) == (SGameTileHandler.CutMode) 0 && (mode & SGameTileHandler.CutMode.CutAll) != (SGameTileHandler.CutMode) 0 && num == -1) { list5.Add(list4.get_Count()); list5.Add(list4.get_Count() + 1); list5.Add(list4.get_Count() + 2); list4.Add(vInt5); list4.Add(vInt6); list4.Add(vInt7); } else { list2.Clear(); if (num == -1) { list2.Add(new IntPoint((long)vInt5.x, (long)vInt5.z)); list2.Add(new IntPoint((long)vInt6.x, (long)vInt6.z)); list2.Add(new IntPoint((long)vInt7.x, (long)vInt7.z)); } else { array3[0] = vInt5; array3[1] = vInt6; array3[2] = vInt7; int num5 = Utility.ClipPolygon(array3, 3, array4, 1, 0, 0); if (num5 == 0) { continue; } num5 = Utility.ClipPolygon(array4, num5, array3, -1, 2 * vInt4.x, 0); if (num5 == 0) { continue; } num5 = Utility.ClipPolygon(array3, num5, array4, 1, 0, 2); if (num5 == 0) { continue; } num5 = Utility.ClipPolygon(array4, num5, array3, -1, 2 * vInt4.z, 2); if (num5 == 0) { continue; } for (int num6 = 0; num6 < num5; num6++) { list2.Add(new IntPoint((long)array3[num6].x, (long)array3[num6].z)); } } dictionary.Clear(); VInt3 vInt10 = vInt6 - vInt5; VInt3 vInt11 = vInt7 - vInt5; VInt3 vInt12 = vInt10; VInt3 vInt13 = vInt11; vInt12.y = 0; vInt13.y = 0; for (int num7 = 0; num7 < 16; num7++) { if ((mode >> (num7 & 31) & SGameTileHandler.CutMode.CutAll) != (SGameTileHandler.CutMode) 0) { if (1 << num7 == 1) { this.clipper.Clear(); this.clipper.AddPolygon(list2, 0); for (int num8 = 0; num8 < list7.get_Count(); num8++) { this.clipper.AddPolygon(list10.get_Item(list7.get_Item(num8)), 1); } polyTree.Clear(); this.clipper.Execute(2, polyTree, 0, 1); } else if (1 << num7 == 2) { if (!flag) { goto IL_1173; } this.clipper.Clear(); this.clipper.AddPolygon(list2, 0); for (int num9 = 0; num9 < list7.get_Count(); num9++) { if (list11.get_Item(list7.get_Item(num9))) { this.clipper.AddPolygon(list10.get_Item(list7.get_Item(num9)), 1); } } list6.Clear(); this.clipper.Execute(0, list6, 0, 1); this.clipper.Clear(); for (int num10 = 0; num10 < list6.get_Count(); num10++) { this.clipper.AddPolygon(list6.get_Item(num10), (!Clipper.Orientation(list6.get_Item(num10))) ? 0 : 1); } for (int num11 = 0; num11 < list7.get_Count(); num11++) { if (!list11.get_Item(list7.get_Item(num11))) { this.clipper.AddPolygon(list10.get_Item(list7.get_Item(num11)), 1); } } polyTree.Clear(); this.clipper.Execute(2, polyTree, 0, 1); } else if (1 << num7 == 4) { this.clipper.Clear(); this.clipper.AddPolygon(list2, 0); this.clipper.AddPolygon(list, 1); polyTree.Clear(); this.clipper.Execute(0, polyTree, 0, 1); } for (int num12 = 0; num12 < polyTree.get_ChildCount(); num12++) { PolyNode polyNode = polyTree.get_Childs().get_Item(num12); List <IntPoint> contour = polyNode.get_Contour(); List <PolyNode> childs = polyNode.get_Childs(); if (childs.get_Count() == 0 && contour.get_Count() == 3 && num == -1) { for (int num13 = 0; num13 < contour.get_Count(); num13++) { VInt3 vInt14 = new VInt3((int)contour.get_Item(num13).X, 0, (int)contour.get_Item(num13).Y); double num14 = (double)(vInt6.z - vInt7.z) * (double)(vInt5.x - vInt7.x) + (double)(vInt7.x - vInt6.x) * (double)(vInt5.z - vInt7.z); if (num14 == 0.0) { Debug.LogWarning("Degenerate triangle"); } else { double num15 = ((double)(vInt6.z - vInt7.z) * (double)(vInt14.x - vInt7.x) + (double)(vInt7.x - vInt6.x) * (double)(vInt14.z - vInt7.z)) / num14; double num16 = ((double)(vInt7.z - vInt5.z) * (double)(vInt14.x - vInt7.x) + (double)(vInt5.x - vInt7.x) * (double)(vInt14.z - vInt7.z)) / num14; vInt14.y = (int)Math.Round(num15 * (double)vInt5.y + num16 * (double)vInt6.y + (1.0 - num15 - num16) * (double)vInt7.y); list5.Add(list4.get_Count()); list4.Add(vInt14); } } } else { Polygon polygon = null; int num17 = -1; for (List <IntPoint> list14 = contour; list14 != null; list14 = ((num17 >= childs.get_Count()) ? null : childs.get_Item(num17).get_Contour())) { list3.Clear(); for (int num18 = 0; num18 < list14.get_Count(); num18++) { PolygonPoint polygonPoint = new PolygonPoint((double)list14.get_Item(num18).X, (double)list14.get_Item(num18).Y); list3.Add(polygonPoint); VInt3 vInt15 = new VInt3((int)list14.get_Item(num18).X, 0, (int)list14.get_Item(num18).Y); double num19 = (double)(vInt6.z - vInt7.z) * (double)(vInt5.x - vInt7.x) + (double)(vInt7.x - vInt6.x) * (double)(vInt5.z - vInt7.z); if (num19 == 0.0) { Debug.LogWarning("Degenerate triangle"); } else { double num20 = ((double)(vInt6.z - vInt7.z) * (double)(vInt15.x - vInt7.x) + (double)(vInt7.x - vInt6.x) * (double)(vInt15.z - vInt7.z)) / num19; double num21 = ((double)(vInt7.z - vInt5.z) * (double)(vInt15.x - vInt7.x) + (double)(vInt5.x - vInt7.x) * (double)(vInt15.z - vInt7.z)) / num19; vInt15.y = (int)Math.Round(num20 * (double)vInt5.y + num21 * (double)vInt6.y + (1.0 - num20 - num21) * (double)vInt7.y); dictionary.set_Item(polygonPoint, list4.get_Count()); list4.Add(vInt15); } } Polygon polygon2; if (stack.get_Count() > 0) { polygon2 = stack.Pop(); polygon2.AddPoints(list3); } else { polygon2 = new Polygon(list3); } if (polygon == null) { polygon = polygon2; } else { polygon.AddHole(polygon2); } num17++; } try { P2T.Triangulate(polygon); } catch (PointOnEdgeException) { Debug.LogWarning(string.Concat(new object[] { "PointOnEdgeException, perturbating vertices slightly ( at ", num7, " in ", mode, ")" })); this.CutPoly(InNavmeshCuts, verts, tris, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount, extraShape, cuttingOffset, realBounds, mode, perturbate + 1); return; } for (int num22 = 0; num22 < polygon.get_Triangles().get_Count(); num22++) { DelaunayTriangle delaunayTriangle = polygon.get_Triangles().get_Item(num22); list5.Add(dictionary.get_Item(delaunayTriangle.Points._0)); list5.Add(dictionary.get_Item(delaunayTriangle.Points._1)); list5.Add(dictionary.get_Item(delaunayTriangle.Points._2)); } if (polygon.get_Holes() != null) { for (int num23 = 0; num23 < polygon.get_Holes().get_Count(); num23++) { polygon.get_Holes().get_Item(num23).get_Points().Clear(); polygon.get_Holes().get_Item(num23).ClearTriangles(); if (polygon.get_Holes().get_Item(num23).get_Holes() != null) { polygon.get_Holes().get_Item(num23).get_Holes().Clear(); } stack.Push(polygon.get_Holes().get_Item(num23)); } } polygon.ClearTriangles(); if (polygon.get_Holes() != null) { polygon.get_Holes().Clear(); } polygon.get_Points().Clear(); stack.Push(polygon); } } } IL_1173 :; } } } Dictionary <VInt3, int> dictionary2 = this.cached_Int3_int_dict; dictionary2.Clear(); if (this.cached_int_array.Length < list4.get_Count()) { this.cached_int_array = new int[Math.Max(this.cached_int_array.Length * 2, list4.get_Count())]; } int[] array5 = this.cached_int_array; int num24 = 0; for (int num25 = 0; num25 < list4.get_Count(); num25++) { int num26; if (!dictionary2.TryGetValue(list4.get_Item(num25), ref num26)) { dictionary2.Add(list4.get_Item(num25), num24); array5[num25] = num24; list4.set_Item(num24, list4.get_Item(num25)); num24++; } else { array5[num25] = num26; } } outTCount = list5.get_Count(); if (outTrisArr == null || outTrisArr.Length < outTCount) { outTrisArr = new int[outTCount]; } for (int num27 = 0; num27 < outTCount; num27++) { outTrisArr[num27] = array5[list5.get_Item(num27)]; } outVCount = num24; if (outVertsArr == null || outVertsArr.Length < outVCount) { outVertsArr = new VInt3[outVCount]; } for (int num28 = 0; num28 < outVCount; num28++) { outVertsArr[num28] = list4.get_Item(num28); } for (int num29 = 0; num29 < listView.Count; num29++) { listView[num29].UsedForCut(); } ListPool <VInt3> .Release(list4); ListPool <int> .Release(list5); ListPool <int> .Release(list7); ListPool <VInt2> .Release(list9); ListPool <bool> .Release(list11); ListPool <bool> .Release(list12); ListPool <IntRect> .Release(list8); }