public List <CSGPolygon> allPolygons() { /* * Create a shallow copy of the list */ CSGPolygon[] plist = new CSGPolygon[this.polygons.Count]; polygons.CopyTo(plist); polygons = plist.ToList <CSGPolygon>(); if (this.front != null) { foreach (CSGPolygon p in this.front.allPolygons()) { polygons.Add(p); } } if (this.back != null) { foreach (CSGPolygon p in this.back.allPolygons()) { polygons.Add(p); } } return(polygons); }
/* * Tesselate a convex multisided polygon */ private static void TesselatePolygon(List <CSGPolygon> TriangleList, CSGPolygon p) { if (p.vertices.Count == 3) { TriangleList.Add(p); return; } /* * Retrieve the sequences of vertices to delete in order to snip a triangle */ List <int[]> sequenceList = GetSequence(p.vertices.Count); /* * For each sequence, make a copy of the polygon and remove the vertex indices */ foreach (int[] sequence in sequenceList) { CSGPolygon c = p.clone(); foreach (int ndx in sequence) { c.vertices.RemoveAt(ndx); } TriangleList.Add(c); } }
public CSGPolygon clone() { CSGPolygon oClone = new CSGPolygon() { shared = this.shared, plane = this.plane.clone() }; foreach (CSGVertex v in this.vertices) { oClone.vertices.Add(v.clone()); } return(oClone); }
public List <CSGPolygon> clipPolygons(List <CSGPolygon> polygons) { if (this.plane == null) { /* * Create a shallow copy of the list */ CSGPolygon[] plist = new CSGPolygon[polygons.Count]; polygons.CopyTo(plist); return(plist.ToList <CSGPolygon>()); } List <CSGPolygon> front = new List <CSGPolygon>(); List <CSGPolygon> back = new List <CSGPolygon>(); for (int i = 0; i < polygons.Count; i++) { this.plane.splitPolygon(polygons[i], front, back, front, back); } if (this.front != null) { front = this.front.clipPolygons(front); } if (this.back != null) { back = this.back.clipPolygons(back); } else { back = new List <CSGPolygon>(); } foreach (CSGPolygon p in back) { front.Add(p); } return(front); }
public void splitPolygon(CSGPolygon polygon, List <CSGPolygon> coplanarFront, List <CSGPolygon> coPlanarBack, List <CSGPolygon> front, List <CSGPolygon> back) { const int COPLANAR = 0; const int FRONT = 1; const int BACK = 2; const int SPANNING = 3; int polygonType = 0; List <int> types = new List <int>(); for (int i = 0; i < polygon.vertices.Count; i++) { float t = this.normal.dot(polygon.vertices[i].pos) - this.w; int type = (t < -EPSILON) ? BACK : (t > EPSILON) ? FRONT : COPLANAR; polygonType |= type; types.Add(type); } switch (polygonType) { case COPLANAR: (this.normal.dot(polygon.plane.normal) > 0 ? coplanarFront : coPlanarBack).Add(polygon); break; case FRONT: front.Add(polygon); break; case BACK: back.Add(polygon); break; case SPANNING: List <CSGVertex> f = new List <CSGVertex>(); List <CSGVertex> b = new List <CSGVertex>(); for (int i = 0; i < polygon.vertices.Count; i++) { int j = (i + 1) % polygon.vertices.Count; int ti = types[i]; int tj = types[j]; CSGVertex vi = polygon.vertices[i]; CSGVertex vj = polygon.vertices[j]; if (ti != BACK) { f.Add(vi); } if (ti != FRONT) { b.Add(ti != BACK ? vi.clone() : vi); } if ((ti | tj) == SPANNING) { float t = (this.w - this.normal.dot(vi.pos)) / this.normal.dot(vj.pos.minus(vi.pos)); CSGVertex v = vi.interpolate(vj, t); f.Add(v); b.Add(v.clone()); } } if (f.Count >= 3) { front.Add(new CSGPolygon(f, polygon.shared)); } if (b.Count >= 3) { back.Add(new CSGPolygon(b, polygon.shared)); } break; } }