public Merge.Merge2D ComplexMerge(List <Vector2D> slice, bool perform = true) { Merge.Merge2D merge2D = Merge.Merge2D.Create(slice); if (isActiveAndEnabled == false) { return(merge2D); } Polygon2D colliderPolygon = shape.GetWorld(); if (colliderPolygon != null) { Merge.Merge2D mergeResult = API.ComplexMerge(colliderPolygon, slice); if (mergeResult.polygons.Count > 0) { if (perform) { PerformMergeResult(mergeResult.polygons, mergeResult); } } return(mergeResult); } return(merge2D); }
public static Merge2D Create(List <Vector2D> slice) { Merge2D merge2D = new Merge2D(); //merge2D.slice = new List<Vector2D>(slice); return(merge2D); }
static private Merge2D SingleMerge(Polygon2D polygon, List <Vector2D> slice) { Merge2D result = Merge2D.Create(slice); if (polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false) { //Debug.Log("incorrect"); return(result); } slice = new List <Vector2D> (slice); Merge.Collision collisionMerge = new Merge.Collision(polygon, slice); if (collisionMerge.error) { // When this happens? Debug.LogWarning("Merger2D: Unexpected Error 2"); return(result); } List <Polygon2D> intersectHoles = polygon.GetListSliceIntersectHoles(slice); switch (intersectHoles.Count) { case 0: if (collisionMerge.collisionCount == 2) { return(SliceWithoutHoles(polygon, slice, collisionMerge)); } break; case 1: break; case 2: break; default: break; } return(result); }
///// Merger2D Perform public void PerformMergeResult(List <Polygon2D> polygons, Merge.Merge2D mergeResult) { if (mergeResult.polygons.Count > 0) { Polygon2D merged = mergeResult.polygons[0]; if (merged != null) { merged.ToLocalSpace(transform).CreatePolygonCollider(gameObject); shape = new Shape(); shape.SetSlicer2D(this); Initialize(); GetComponent <ColliderLineRenderer2D>().Initialize(); } } }
static public List <Merge2D> ComplexMergeAll(List <Vector2D> slice, Layer layer = null) { List <Merge2D> result = new List <Merge2D> (); if (layer == null) { layer = Layer.Create(); } foreach (Sliceable2D id in Sliceable2D.GetListLayer(layer)) { Merge2D sliceResult = id.ComplexMerge(slice); if (sliceResult.polygons.Count > 0) { result.Add(sliceResult); } } return(result); }
static public Merge2D MergePolygon(Polygon2D polygon, Polygon2D mergePolygon) { Merge2D result = Merge2D.Create(mergePolygon.pointsList); Vector2D startPoint = null; foreach (Vector2D id in mergePolygon.pointsList) { if (polygon.PointInPoly(id) == true) { startPoint = id; break; } } if (startPoint == null) { Debug.LogWarning("Starting Point Error In Polygon Merge"); return(result); } mergePolygon.pointsList = Vector2DList.GetListStartingPoint(mergePolygon.pointsList, startPoint); mergePolygon.AddPoint(startPoint); // Not Necessary if (polygon.SliceIntersectPoly(mergePolygon.pointsList) == false) { return(result); } result = Merger.Merge(polygon, new List <Vector2D> (mergePolygon.pointsList)); if (result.polygons.Count < 1) { Debug.LogWarning("Merger2D: Returns Empty Polygon Slice"); } return(result); }
static private Merge2D SliceWithoutHoles(Polygon2D polygon, List <Vector2D> slice, Merge.Collision mergeCollision) { Merge2D result = Merge2D.Create(slice); // Simple non-hole slice Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(); Polygon2D currentPoly = polyA; List <Vector2D> slices = new List <Vector2D>(mergeCollision.GetPoints()); foreach (Pair2D p in Pair2D.GetList(polygon.pointsList)) { List <Vector2D> intersections = Math2D.GetListLineIntersectSlice(p, slice); if (intersections.Count() > 0) { if (intersections.Count == 2) { Vector2D first = intersections.First(); Vector2D last = intersections.Last(); if (Vector2D.Distance(last, p.A) < Vector2D.Distance(first, p.A)) { first = intersections.Last(); last = intersections.First(); } // Add Inside Points if (mergeCollision.GetPoints().Count > 0) // InsidePlus { if (Vector2D.Distance(first, mergeCollision.Last()) < Vector2D.Distance(first, mergeCollision.First())) { mergeCollision.Reverse(); } currentPoly.AddPoints(mergeCollision.GetPoints()); // InsidePlus } ///// currentPoly = polyB; if (mergeCollision.GetPoints().Count > 0) // InsidePlus( { currentPoly.AddPoints(mergeCollision.GetPoints()); // InsidePlus } currentPoly = polyA; } if (intersections.Count == 1) { Vector2D intersection = intersections.First(); ///// Add Inside Points if (mergeCollision.GetPoints().Count > 0) //InsidePlus { if (Vector2D.Distance(intersection, mergeCollision.Last()) < Vector2D.Distance(intersection, mergeCollision.First())) { mergeCollision.Reverse(); } currentPoly.AddPoints(mergeCollision.GetPoints()); // InsidePlus } ///// currentPoly = (currentPoly == polyA) ? polyB : polyA; } } currentPoly.AddPoint(p.B); } Polygon2D mainPoly = polyA; if (polyB != null && polyB.GetArea() > polyA.GetArea()) { mainPoly = polyB; } result.AddPolygon(mainPoly); foreach (Polygon2D hole in polygon.holesList) { mainPoly.AddHole(hole); } result.AddSlice(slices); return(result); }
// Complex Merge static public Merge2D Merge(Polygon2D polygon, List <Vector2D> slice) { Merge2D result = Merge2D.Create(slice); if (slice.Count < 2) { return(result); } // Normalize into clockwise polygon.Normalize(); Rect sliceRect = Math2D.GetBounds(slice); Rect polygonRect = polygon.GetBounds(); if (sliceRect.Overlaps(polygonRect) == false) { return(result); } List <List <Vector2D> > slices = GetSplitSlices(polygon, slice); // Adjusting split lines before performing convex split result.AddPolygon(polygon); foreach (List <Vector2D> id in slices) { if (id.Count < 1) { continue; } foreach (Vector2D p in id) { result.AddCollision(p); } // Sclice line points generated from intersections list Vector2D vec0 = id.First(); vec0.Push(Vector2D.Atan2(vec0, id[1]), precision); // ERROR Vector2D vec1 = id.Last(); vec1.Push(Vector2D.Atan2(vec1, id[id.Count - 2]), precision); // For each in polygons list attempt convex split List <Polygon2D> temp = new List <Polygon2D>(result.polygons); // necessary? foreach (Polygon2D poly in temp) { Merge2D resultList = SingleMerge(poly, id); if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } if (resultList.polygons.Count > 0) { foreach (Polygon2D i in resultList.polygons) { result.AddPolygon(i); } // If it's possible to perform convex split, remove parent polygon from result list result.polygons.Remove(poly); } } } return(result); }