public void updateIndexes(IndexOffset.IndexOffsetContainer ioc) { interdataStart.targetLineSegmentID = ioc.getNewIndex(origVeinStart); interdataEnd.targetLineSegmentID = ioc.getNewIndex(origVeinEnd); }
public void cutShape(Shape stencil, bool splitFurther = true) { if (stencil.Direction != this.Direction) { throw new UnityException("Trying to cut shape with stencil of different thread type! shape: " + Direction + ", stencil: " + stencil.Direction); } //Show paths (for debugging) //showPath(points); //showPath(stencilPoints); //Gather overlap info List <IntersectionData> intersectionData = new List <IntersectionData>(); for (int i = 0; i < GlobalPoints.Count; i++) { int i2 = (i + 1) % GlobalPoints.Count; //Line Checking LineSegment targetLine = new LineSegment(GlobalPoints, i); //Check to see if the bounds overlap if (stencil.bounds.Intersects(targetLine.Bounds)) { bool startInStencil = stencil.OverlapPoint(targetLine.startPos); bool endInStencil = stencil.OverlapPoint(targetLine.endPos); //Check which stencil edges intersect the line segment bool intersectsSegment = false; for (int j = 0; j < stencil.GlobalPoints.Count; j++) { LineSegment stencilLine = new LineSegment(stencil.GlobalPoints, j); Vector2 intersection = Vector2.zero; bool intersects = targetLine.Intersects(stencilLine, ref intersection); //If it intersects, if (intersects) { //Record a data point intersectsSegment = true; float distanceToPoint = (intersection - targetLine.startPos).magnitude; IntersectionData interdata = new IntersectionData(intersection, i, j, intersects, startInStencil, endInStencil, distanceToPoint); intersectionData.Add(interdata); } } //If no line segment intersections were found, if (!intersectsSegment) { //but one or more end points are in the stencil, if (startInStencil || endInStencil) { //Make an intersection data point anyway, with slightly different arguments IntersectionData interdata = new IntersectionData(Vector2.zero, i, -1, IntersectionData.IntersectionType.INSIDE); intersectionData.Add(interdata); } } //else, else { //do nothing because the bounds lied about the line segment and stencil colliding //don't worry, it's a known thing that can happen: //bounds checking is quick but liable to give false positives } } } // // Refine intersection data entries // //Sort the data entries intersectionData.Sort(new IntersectionData.IntersectionDataComparer()); //Set the intersection type of the data int side = 0;//0 =not set, 1 =inside, -1 =outside foreach (IntersectionData interdata in intersectionData) { if (side == 0) { side = (interdata.startsInStencil) ? 1 : -1; } if (interdata.segmentIntersection) { side *= -1; interdata.type = (side > 0) ? IntersectionData.IntersectionType.ENTER : IntersectionData.IntersectionType.EXIT; } else { interdata.type = (side > 0) ? IntersectionData.IntersectionType.INSIDE : IntersectionData.IntersectionType.OUTSIDE; } } IntersectionData.printDataList(intersectionData, GlobalPoints); // //Start cutting // //Replace line segments inside the stencil int dataCount = intersectionData.Count; //Search for start of vein of changes List <Vein> veins = new List <Vein>(); //only need to go through the loop once, //because the veins will find their own end points: //here we just need to find the start of each vein for (int iData = 0; iData < dataCount; iData++) { IntersectionData interdata = intersectionData[iData]; //if this segment enters the stencil at this data point, if (interdata.type == IntersectionData.IntersectionType.ENTER) { //then it's a vein start Vein vein = new Vein(iData, interdata, intersectionData); veins.Add(vein); } } //Process found veins if (veins.Count == 1) { Vector2[] newPath = veins[0].getStencilPath(stencil.GlobalPoints); //Replace vein with stencil path int removeCount = veins[0].getRemoveCount(GlobalPoints.Count); replacePoints(newPath, veins[0].VeinStart + 1, removeCount); } else { //Process all the veins IndexOffset.IndexOffsetContainer offsets = new IndexOffset.IndexOffsetContainer(GlobalPoints.Count); for (int i = 0; i < veins.Count; i++) { Vein vein = veins[i]; //Update vein with new offsets vein.updateIndexes(offsets); //Check next vein bool slices = false; if (i < veins.Count - 1) { Vein vein2 = veins[i + 1]; vein.updateIndexes(offsets); slices = vein.formsSlice(vein2, stencil.GlobalPoints.Count); Debug.Log("slices: " + slices); if (slices) { vein.slice(vein2); if (splitFurther) { if (this.pc2d) { //make a new collider to make the new piece PolygonCollider2D pc2dNew = GameObject.Instantiate(pc2d.gameObject) .GetComponent <PolygonCollider2D>(); Shape newShape = new Shape(pc2dNew); newShape.rotatePoints(vein2.VeinStart); newShape.finalize(); childrenShapes.Add(newShape); pc2dNew.transform.parent = pc2d.transform.parent; pc2dNew.transform.position = pc2d.transform.position; newShape.cutShape(stencil, false); } } //skip the next vein i++; } } if (true || !slices) { //Replace vein with stencil path Vector2[] newPath = vein.getStencilPath(stencil.GlobalPoints); int removeCount = vein.getRemoveCount(GlobalPoints.Count); replacePoints(newPath, vein.VeinStart + 1, removeCount); //Add offset to the collection IndexOffset offset = new IndexOffset(vein.VeinStart, newPath.Length - removeCount); offsets.Add(offset); } } } // // Finish up // finalize(); }