private PolyTreeEdgesRetained PrepairPolyTree(Collider2D[] floorColliders, Collider2D[] wallColliders) { if(floorColliders.Length == 0) { throw new System.Exception("No colliders in the scene on the floor layer."); } PolyTreeEdgesRetained TreeAndEdges = new PolyTreeEdgesRetained(); TreeAndEdges.Edges = new List<List<IntPoint>>(); TreeAndEdges.Tree = new PolyTree(); Clipper finalClipper = new Clipper(); if (floorColliders.Length > 0) { Clipper tempC = new Clipper(); ClipperOffset tempCo = new ClipperOffset(); foreach (Collider2D d in floorColliders) { List<IntPoint> p = PolygonFromCollider2D(d, false); if (p != null && p.Count != 0) { if (ClipperLib.Clipper.Orientation(p)) p.Reverse(); tempC.AddPath(p, PolyType.ptSubject, true); } } List<List<IntPoint>> solution = new List<List<IntPoint>>(); tempC.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); tempC.Clear(); foreach (List<IntPoint> intPoints in solution) { tempCo.AddPath(intPoints, (JoinType)GenerationInformation.JoinType, EndType.etClosedPolygon); TreeAndEdges.Edges.Add(intPoints); } solution.Clear(); tempCo.Execute(ref solution, -GenerationInformation.ColliderPadding * GenerationInformation.CalculationScaleFactor); finalClipper.AddPaths(solution, PolyType.ptSubject, true); } if(wallColliders.Length > 0) { Clipper tempC = new Clipper(); ClipperOffset tempCo = new ClipperOffset(); foreach (Collider2D d in wallColliders) { List<IntPoint> p = PolygonFromCollider2D(d, false); if (p != null && p.Count != 0) { if (ClipperLib.Clipper.Orientation(p)) p.Reverse(); tempC.AddPath(p, PolyType.ptSubject, true); } } List<List<IntPoint>> solution = new List<List<IntPoint>>(); tempC.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); tempC.Clear(); foreach (List<IntPoint> intPoints in solution) { tempCo.AddPath(intPoints, (JoinType)GenerationInformation.JoinType, EndType.etClosedPolygon); TreeAndEdges.Edges.Add(intPoints); } solution.Clear(); tempCo.Execute(ref solution, GenerationInformation.ColliderPadding * GenerationInformation.CalculationScaleFactor); finalClipper.AddPaths(solution, PolyType.ptClip, true); } finalClipper.Execute(ClipType.ctDifference, TreeAndEdges.Tree, PolyFillType.pftPositive, PolyFillType.pftEvenOdd); return TreeAndEdges; }
private NavMesh2DBehaviour.MeshContour[] ExtractMeshContour(PolyTreeEdgesRetained ptcr) { List<NavMesh2DBehaviour.MeshContour> result = new List<NavMesh2DBehaviour.MeshContour>(); foreach (PolyNode meshContour in ptcr.Tree.Childs) { List<Vector2> extractedPoints = new List<Vector2>(); foreach (var point in meshContour.Contour) { extractedPoints.Add(new Vector2(point.X / GenerationInformation.CalculationScaleFactor, point.Y / GenerationInformation.CalculationScaleFactor)); } result.Add(new NavMesh2DBehaviour.MeshContour { Points = extractedPoints.ToArray() }); foreach (PolyNode holes in meshContour.Childs) { extractedPoints.Clear(); foreach (var point in holes.Contour) { extractedPoints.Add(new Vector2(point.X / GenerationInformation.CalculationScaleFactor, point.Y / GenerationInformation.CalculationScaleFactor)); } result.Add(new NavMesh2DBehaviour.MeshContour { Points = extractedPoints.ToArray() }); } } return result.ToArray(); }