package com.exh.bevel.algo; import java.util.LinkedList; import java.util.List; import com.exh.bevel.render.Spotlight; import com.exh.math.poly.Bool; import com.exh.math.poly.Triangulizer; import com.exh.math.primitive.Point3; import com.exh.math.primitive.Polygon; import com.exh.math.primitive.Tri; // Store a list of polygons. Clients provide input of a single // tri, and every poly in my list is subtracted from that tri. The // result will be either nothing if the input was completely masked, // the original input tri if there were no intersections, or n number // of new tris. public final class Mask { public Spotlight mSpotlight; private final Triangulizer mTriangulizer = new Triangulizer(); private final List mClip = new LinkedList(); private List mResult0 = new LinkedList(), mResult1 = new LinkedList(); private final Bool mBool = new Bool(); // Not how we want to clip the triangles, but for now... private final Polygon mPolyA = new Polygon(), mPolyC = new Polygon(); private final Point3.Order mOrder = new Point3.Order(); // For debugging, number each tri added to the output. private int mCount = 0; public void start() { mClip.clear(); mCount = 0; } public void addClipPoly(final Polygon p) { if (p == null) return; mClip.add(p.copy()); } // Clip input tri dst against every tri in mClipSrc. // Intersections stores a list of the intersection points between // the dst and all my clipping polygons. I use this to chop off // any polygons that got generated but technically should have // been masked (i.e. the clip polys only subtract from their area, // but what they should be doing is eliminating everything at their // z level and above). public void clip(final Polygon dst, final List output) { mResult0.clear(); mPolyA.setTo(dst); mResult0.add(mPolyA.copy()); //System.out.println("PERFORM MASK.CLIP size=" + mClip.size()); int k = 0; for (Polygon s : mClip) { //System.out.println("MASK.CLIP " + k + " against size " + mResult0.size()); mResult1.clear(); for (Polygon d : mResult0) clip(d, s, mResult1); swapResults(); k++; } for (Polygon p : mResult0) makeOutput(p, output); } public void clip(final Tri dst, final List output) { mResult0.clear(); mPolyA.setTo(dst); mResult0.add(mPolyA.copy()); for (Polygon s : mClip) { mResult1.clear(); for (Polygon d : mResult0) clip(d, s, mResult1); swapResults(); } for (Polygon p : mResult0) makeOutput(p, output); } // Clip dst against src s, placing the results, in any, in the output. private void clip(final Polygon dst, final Polygon src, final List output) { mPolyA.setTo(dst); final int err = mBool.subtract(mPolyA, src, null, null); if (err <= Bool.ERROR) { output.add(dst.copy()); return; } for (int k=0; mBool.takeResult(k, mPolyC); k++) { Polygon p = new Polygon(); p.swap(mPolyC); output.add(p); } } private void makeOutput(final Polygon poly, final List output) { final int ans = mTriangulizer.on(poly); for (int j=0; j s = mResult0; mResult0 = mResult1; mResult1 = s; } }