// Token: 0x060005EB RID: 1515 RVA: 0x00037D0C File Offset: 0x0003610C public void LoadTile(TileHandler.TileType tile, int x, int z, int rotation, int yoffset) { if (tile == null) { throw new ArgumentNullException("tile"); } if (AstarPath.active == null) { return; } int index = x + z * this.graph.tileXCount; rotation %= 4; if (this.isBatching && this.reloadedInBatch[index] && this.activeTileOffsets[index] == yoffset && this.activeTileRotations[index] == rotation && this.activeTileTypes[index] == tile) { return; } if (this.isBatching) { this.reloadedInBatch[index] = true; } this.activeTileOffsets[index] = yoffset; this.activeTileRotations[index] = rotation; this.activeTileTypes[index] = tile; AstarPath.active.AddWorkItem(new AstarPath.AstarWorkItem(delegate(bool force) { if (this.activeTileOffsets[index] != yoffset || this.activeTileRotations[index] != rotation || this.activeTileTypes[index] != tile) { return(true); } GraphModifier.TriggerEvent(GraphModifier.EventType.PreUpdate); Int3[] verts; int[] tris; tile.Load(out verts, out tris, rotation, yoffset); Bounds tileBounds = this.graph.GetTileBounds(x, z, tile.Width, tile.Depth); Int3 @int = (Int3)tileBounds.min; @int = -@int; Int3[] array = null; int[] array2 = null; int num; int num2; this.CutPoly(verts, tris, ref array, ref array2, out num, out num2, null, @int, tileBounds, (TileHandler.CutMode) 3, 0); this.DelaunayRefinement(array, array2, ref num, ref num2, true, false, -@int); if (num2 != array2.Length) { array2 = TileHandler.ShrinkArray <int>(array2, num2); } if (num != array.Length) { array = TileHandler.ShrinkArray <Int3>(array, num); } int w = (rotation % 2 != 0) ? tile.Depth : tile.Width; int d = (rotation % 2 != 0) ? tile.Width : tile.Depth; this.graph.ReplaceTile(x, z, w, d, array, array2, false); GraphModifier.TriggerEvent(GraphModifier.EventType.PostUpdate); AstarPath.active.QueueWorkItemFloodFill(); return(true); })); }
private TileHandler.CuttingResult CutPoly(Int3[] verts, int[] tris, Int3[] extraShape, GraphTransform graphTransform, IntRect tiles, TileHandler.CutMode mode = TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual, int perturbate = -1) { if (verts.Length == 0 || tris.Length == 0) { return(new TileHandler.CuttingResult { verts = ArrayPool <Int3> .Claim(0), tris = ArrayPool <int> .Claim(0) }); } if (perturbate > 10) { Debug.LogError("Too many perturbations aborting.\nThis may cause a tile in the navmesh to become empty. Try to see see if any of your NavmeshCut or NavmeshAdd components use invalid custom meshes."); return(new TileHandler.CuttingResult { verts = verts, tris = tris }); } List <IntPoint> list = null; if (extraShape == null && (mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0) { throw new Exception("extraShape is null and the CutMode specifies that it should be used. Cannot use null shape."); } Bounds tileBoundsInGraphSpace = this.graph.GetTileBoundsInGraphSpace(tiles); Vector3 min = tileBoundsInGraphSpace.min; GraphTransform graphTransform2 = graphTransform * Matrix4x4.TRS(min, Quaternion.identity, Vector3.one); Vector2 v = new Vector2(tileBoundsInGraphSpace.size.x, tileBoundsInGraphSpace.size.z); if ((mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0) { list = ListPool <IntPoint> .Claim(extraShape.Length); for (int i = 0; i < extraShape.Length; i++) { Int3 @int = graphTransform2.InverseTransform(extraShape[i]); list.Add(new IntPoint((long)@int.x, (long)@int.z)); } } IntRect cutSpaceBounds = new IntRect(verts[0].x, verts[0].z, verts[0].x, verts[0].z); for (int j = 0; j < verts.Length; j++) { cutSpaceBounds = cutSpaceBounds.ExpandToContain(verts[j].x, verts[j].z); } List <NavmeshCut> list2; if (mode == TileHandler.CutMode.CutExtra) { list2 = ListPool <NavmeshCut> .Claim(); } else { list2 = this.cuts.QueryRect <NavmeshCut>(tiles); } List <NavmeshAdd> list3 = this.cuts.QueryRect <NavmeshAdd>(tiles); List <int> list4 = ListPool <int> .Claim(); List <TileHandler.Cut> list5 = TileHandler.PrepareNavmeshCutsForCutting(list2, graphTransform2, cutSpaceBounds, perturbate, list3.Count > 0); List <Int3> list6 = ListPool <Int3> .Claim(verts.Length * 2); List <int> list7 = ListPool <int> .Claim(tris.Length); if (list2.Count == 0 && list3.Count == 0 && (mode & ~(TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual)) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0) { TileHandler.CopyMesh(verts, tris, list6, list7); } else { List <IntPoint> list8 = ListPool <IntPoint> .Claim(); Dictionary <TriangulationPoint, int> dictionary = new Dictionary <TriangulationPoint, int>(); List <PolygonPoint> list9 = ListPool <PolygonPoint> .Claim(); PolyTree polyTree = new PolyTree(); List <List <IntPoint> > list10 = ListPool <List <IntPoint> > .Claim(); Stack <Polygon> stack = StackPool <Polygon> .Claim(); this.clipper.StrictlySimple = (perturbate > -1); this.clipper.ReverseSolution = true; Int3[] array = null; Int3[] clipOut = null; Int2 size = default(Int2); if (list3.Count > 0) { array = new Int3[7]; clipOut = new Int3[7]; size = new Int2(((Int3)v).x, ((Int3)v).y); } Int3[] array2 = null; for (int k = -1; k < list3.Count; k++) { Int3[] array3; int[] array4; if (k == -1) { array3 = verts; array4 = tris; } else { list3[k].GetMesh(ref array2, out array4, graphTransform2); array3 = array2; } for (int l = 0; l < array4.Length; l += 3) { Int3 int2 = array3[array4[l]]; Int3 int3 = array3[array4[l + 1]]; Int3 int4 = array3[array4[l + 2]]; if (VectorMath.IsColinearXZ(int2, int3, int4)) { Debug.LogWarning("Skipping degenerate triangle."); } else { IntRect a = new IntRect(int2.x, int2.z, int2.x, int2.z); a = a.ExpandToContain(int3.x, int3.z); a = a.ExpandToContain(int4.x, int4.z); int num = Math.Min(int2.y, Math.Min(int3.y, int4.y)); int num2 = Math.Max(int2.y, Math.Max(int3.y, int4.y)); list4.Clear(); bool flag = false; for (int m = 0; m < list5.Count; m++) { int x = list5[m].boundsY.x; int y = list5[m].boundsY.y; if (IntRect.Intersects(a, list5[m].bounds) && y >= num && x <= num2 && (list5[m].cutsAddedGeom || k == -1)) { Int3 int5 = int2; int5.y = x; Int3 int6 = int2; int6.y = y; list4.Add(m); flag |= list5[m].isDual; } } if (list4.Count == 0 && (mode & TileHandler.CutMode.CutExtra) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0 && k == -1) { list7.Add(list6.Count); list7.Add(list6.Count + 1); list7.Add(list6.Count + 2); list6.Add(int2); list6.Add(int3); list6.Add(int4); } else { list8.Clear(); if (k == -1) { list8.Add(new IntPoint((long)int2.x, (long)int2.z)); list8.Add(new IntPoint((long)int3.x, (long)int3.z)); list8.Add(new IntPoint((long)int4.x, (long)int4.z)); } else { array[0] = int2; array[1] = int3; array[2] = int4; int num3 = this.ClipAgainstRectangle(array, clipOut, size); if (num3 == 0) { goto IL_9D3; } for (int n = 0; n < num3; n++) { list8.Add(new IntPoint((long)array[n].x, (long)array[n].z)); } } dictionary.Clear(); for (int num4 = 0; num4 < 16; num4++) { if ((mode >> (num4 & 31) & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0) { if (1 << num4 == 1) { this.CutAll(list8, list4, list5, polyTree); } else if (1 << num4 == 2) { if (!flag) { goto IL_9C4; } this.CutDual(list8, list4, list5, flag, list10, polyTree); } else if (1 << num4 == 4) { this.CutExtra(list8, list, polyTree); } for (int num5 = 0; num5 < polyTree.ChildCount; num5++) { PolyNode polyNode = polyTree.Childs[num5]; List <IntPoint> contour = polyNode.Contour; List <PolyNode> childs = polyNode.Childs; if (childs.Count == 0 && contour.Count == 3 && k == -1) { for (int num6 = 0; num6 < 3; num6++) { Int3 int7 = new Int3((int)contour[num6].X, 0, (int)contour[num6].Y); int7.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int7); list7.Add(list6.Count); list6.Add(int7); } } else { Polygon polygon = null; int num7 = -1; for (List <IntPoint> list11 = contour; list11 != null; list11 = ((num7 >= childs.Count) ? null : childs[num7].Contour)) { list9.Clear(); for (int num8 = 0; num8 < list11.Count; num8++) { PolygonPoint polygonPoint = new PolygonPoint((double)list11[num8].X, (double)list11[num8].Y); list9.Add(polygonPoint); Int3 int8 = new Int3((int)list11[num8].X, 0, (int)list11[num8].Y); int8.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int8); dictionary[polygonPoint] = list6.Count; list6.Add(int8); } Polygon polygon2; if (stack.Count > 0) { polygon2 = stack.Pop(); polygon2.AddPoints(list9); } else { polygon2 = new Polygon(list9); } if (num7 == -1) { polygon = polygon2; } else { polygon.AddHole(polygon2); } num7++; } try { P2T.Triangulate(polygon); } catch (PointOnEdgeException) { Debug.LogWarning("PointOnEdgeException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times."); return(this.CutPoly(verts, tris, extraShape, graphTransform, tiles, mode, perturbate + 1)); } try { for (int num9 = 0; num9 < polygon.Triangles.Count; num9++) { DelaunayTriangle delaunayTriangle = polygon.Triangles[num9]; list7.Add(dictionary[delaunayTriangle.Points._0]); list7.Add(dictionary[delaunayTriangle.Points._1]); list7.Add(dictionary[delaunayTriangle.Points._2]); } } catch (KeyNotFoundException) { Debug.LogWarning("KeyNotFoundException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times."); return(this.CutPoly(verts, tris, extraShape, graphTransform, tiles, mode, perturbate + 1)); } TileHandler.PoolPolygon(polygon, stack); } } } IL_9C4 :; } } } IL_9D3 :; } } if (array2 != null) { ArrayPool <Int3> .Release(ref array2, false); } StackPool <Polygon> .Release(stack); ListPool <List <IntPoint> > .Release(list10); ListPool <IntPoint> .Release(list8); ListPool <PolygonPoint> .Release(list9); } TileHandler.CuttingResult result = default(TileHandler.CuttingResult); Polygon.CompressMesh(list6, list7, out result.verts, out result.tris); for (int num10 = 0; num10 < list2.Count; num10++) { list2[num10].UsedForCut(); } ListPool <Int3> .Release(list6); ListPool <int> .Release(list7); ListPool <int> .Release(list4); for (int num11 = 0; num11 < list5.Count; num11++) { ListPool <IntPoint> .Release(list5[num11].contour); } ListPool <TileHandler.Cut> .Release(list5); ListPool <NavmeshCut> .Release(list2); return(result); }
private void CutPoly(Int3[] verts, int[] tris, ref Int3[] outVertsArr, ref int[] outTrisArr, out int outVCount, out int outTCount, Int3[] extraShape, Int3 cuttingOffset, Bounds realBounds, TileHandler.CutMode mode = TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual, int perturbate = -1) { if (verts.Length == 0 || tris.Length == 0) { outVCount = 0; outTCount = 0; outTrisArr = new int[0]; outVertsArr = new Int3[0]; return; } if (perturbate > 10) { Debug.LogError("Too many perturbations aborting.\nThis may cause a tile in the navmesh to become empty. Try to see see if any of your NavmeshCut or NavmeshAdd components use invalid custom meshes."); outVCount = verts.Length; outTCount = tris.Length; outTrisArr = tris; outVertsArr = verts; return; } List <IntPoint> list = null; if (extraShape == null && (mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0) { throw new Exception("extraShape is null and the CutMode specifies that it should be used. Cannot use null shape."); } if ((mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0) { list = ListPool <IntPoint> .Claim(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))); } } IntRect bounds = new IntRect(verts[0].x, verts[0].z, verts[0].x, verts[0].z); for (int j = 0; j < verts.Length; j++) { bounds = bounds.ExpandToContain(verts[j].x, verts[j].z); } List <NavmeshCut> list2; if (mode == TileHandler.CutMode.CutExtra) { list2 = ListPool <NavmeshCut> .Claim(); } else { list2 = NavmeshCut.GetAllInRange(realBounds); } List <NavmeshAdd> allInRange = NavmeshAdd.GetAllInRange(realBounds); List <int> list3 = ListPool <int> .Claim(); List <TileHandler.Cut> list4 = TileHandler.PrepareNavmeshCutsForCutting(list2, cuttingOffset, bounds, perturbate, allInRange.Count > 0); List <Int3> list5 = ListPool <Int3> .Claim(verts.Length * 2); List <int> list6 = ListPool <int> .Claim(tris.Length); Int3[] array = verts; int[] array2 = tris; if (list2.Count == 0 && allInRange.Count == 0 && (mode & ~(TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual)) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0) { this.CopyMesh(array, array2, list5, list6); } else { List <IntPoint> list7 = ListPool <IntPoint> .Claim(); Dictionary <TriangulationPoint, int> dictionary = new Dictionary <TriangulationPoint, int>(); List <PolygonPoint> list8 = ListPool <PolygonPoint> .Claim(); PolyTree polyTree = new PolyTree(); List <List <IntPoint> > intermediateResult = new List <List <IntPoint> >(); Stack <Polygon> stack = new Stack <Polygon>(); this.clipper.StrictlySimple = (perturbate > -1); this.clipper.ReverseSolution = true; Int3[] array3 = null; Int3[] clipOut = null; Int2 @int = default(Int2); if (allInRange.Count > 0) { array3 = new Int3[7]; clipOut = new Int3[7]; @int = new Int2(((Int3)realBounds.extents).x, ((Int3)realBounds.extents).z); } int num = -1; int k = -3; for (;;) { k += 3; while (k >= array2.Length) { num++; k = 0; if (num >= allInRange.Count) { array = null; break; } if (array == verts) { array = null; } allInRange[num].GetMesh(cuttingOffset, ref array, out array2); } if (array == null) { break; } Int3 int2 = array[array2[k]]; Int3 int3 = array[array2[k + 1]]; Int3 int4 = array[array2[k + 2]]; if (VectorMath.IsColinearXZ(int2, int3, int4)) { Debug.LogWarning("Skipping degenerate triangle."); } else { IntRect a = new IntRect(int2.x, int2.z, int2.x, int2.z); a = a.ExpandToContain(int3.x, int3.z); a = a.ExpandToContain(int4.x, int4.z); int num2 = Math.Min(int2.y, Math.Min(int3.y, int4.y)); int num3 = Math.Max(int2.y, Math.Max(int3.y, int4.y)); list3.Clear(); bool flag = false; for (int l = 0; l < list4.Count; l++) { int x = list4[l].boundsY.x; int y = list4[l].boundsY.y; if (IntRect.Intersects(a, list4[l].bounds) && y >= num2 && x <= num3 && (list4[l].cutsAddedGeom || num == -1)) { Int3 int5 = int2; int5.y = x; Int3 int6 = int2; int6.y = y; list3.Add(l); flag |= list4[l].isDual; } } if (list3.Count == 0 && (mode & TileHandler.CutMode.CutExtra) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0 && num == -1) { list6.Add(list5.Count); list6.Add(list5.Count + 1); list6.Add(list5.Count + 2); list5.Add(int2); list5.Add(int3); list5.Add(int4); } else { list7.Clear(); if (num == -1) { list7.Add(new IntPoint((long)int2.x, (long)int2.z)); list7.Add(new IntPoint((long)int3.x, (long)int3.z)); list7.Add(new IntPoint((long)int4.x, (long)int4.z)); } else { array3[0] = int2; array3[1] = int3; array3[2] = int4; int num4 = this.ClipAgainstRectangle(array3, clipOut, new Int2(@int.x * 2, @int.y * 2)); if (num4 == 0) { continue; } for (int m = 0; m < num4; m++) { list7.Add(new IntPoint((long)array3[m].x, (long)array3[m].z)); } } dictionary.Clear(); for (int n = 0; n < 16; n++) { if ((mode >> (n & 31) & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0) { if (1 << n == 1) { this.CutAll(list7, list3, list4, polyTree); } else if (1 << n == 2) { if (!flag) { goto IL_9A0; } this.CutDual(list7, list3, list4, flag, intermediateResult, polyTree); } else if (1 << n == 4) { this.CutExtra(list7, list, polyTree); } for (int num5 = 0; num5 < polyTree.ChildCount; num5++) { PolyNode polyNode = polyTree.Childs[num5]; List <IntPoint> contour = polyNode.Contour; List <PolyNode> childs = polyNode.Childs; if (childs.Count == 0 && contour.Count == 3 && num == -1) { for (int num6 = 0; num6 < 3; num6++) { Int3 int7 = new Int3((int)contour[num6].X, 0, (int)contour[num6].Y); int7.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int7); list6.Add(list5.Count); list5.Add(int7); } } else { Polygon polygon = null; int num7 = -1; for (List <IntPoint> list9 = contour; list9 != null; list9 = ((num7 >= childs.Count) ? null : childs[num7].Contour)) { list8.Clear(); for (int num8 = 0; num8 < list9.Count; num8++) { PolygonPoint polygonPoint = new PolygonPoint((double)list9[num8].X, (double)list9[num8].Y); list8.Add(polygonPoint); Int3 int8 = new Int3((int)list9[num8].X, 0, (int)list9[num8].Y); int8.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int8); dictionary[polygonPoint] = list5.Count; list5.Add(int8); } Polygon polygon2; if (stack.Count > 0) { polygon2 = stack.Pop(); polygon2.AddPoints(list8); } else { polygon2 = new Polygon(list8); } if (num7 == -1) { polygon = polygon2; } else { polygon.AddHole(polygon2); } num7++; } try { P2T.Triangulate(polygon); } catch (PointOnEdgeException) { Debug.LogWarning("PointOnEdgeException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times."); this.CutPoly(verts, tris, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount, extraShape, cuttingOffset, realBounds, mode, perturbate + 1); return; } try { for (int num9 = 0; num9 < polygon.Triangles.Count; num9++) { DelaunayTriangle delaunayTriangle = polygon.Triangles[num9]; list6.Add(dictionary[delaunayTriangle.Points._0]); list6.Add(dictionary[delaunayTriangle.Points._1]); list6.Add(dictionary[delaunayTriangle.Points._2]); } } catch (KeyNotFoundException) { Debug.LogWarning("KeyNotFoundException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times."); this.CutPoly(verts, tris, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount, extraShape, cuttingOffset, realBounds, mode, perturbate + 1); return; } TileHandler.PoolPolygon(polygon, stack); } } } IL_9A0 :; } } } } ListPool <IntPoint> .Release(list7); ListPool <PolygonPoint> .Release(list8); } this.CompressMesh(list5, list6, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount); for (int num10 = 0; num10 < list2.Count; num10++) { list2[num10].UsedForCut(); } ListPool <Int3> .Release(list5); ListPool <int> .Release(list6); ListPool <int> .Release(list3); for (int num11 = 0; num11 < list4.Count; num11++) { ListPool <IntPoint> .Release(list4[num11].contour); } ListPool <TileHandler.Cut> .Release(list4); ListPool <NavmeshCut> .Release(list2); }