public static CSG sphere(Vector3 center, float radius = 1, float slices = 16f, float stacks = 8f) { float r = radius; List <Polygon> polygons = new List <Polygon>(); List <IVertex> vertices; for (int i = 0; i < slices; i++) { for (int j = 0; j < stacks; j++) { vertices = new List <IVertex>(); makeSphereVertex(ref vertices, center, r, i / slices, j / stacks); if (j > 0) { makeSphereVertex(ref vertices, center, r, (i + 1) / slices, j / stacks); } if (j < stacks - 1) { makeSphereVertex(ref vertices, center, r, (i + 1) / slices, (j + 1) / stacks); } makeSphereVertex(ref vertices, center, r, i / slices, (j + 1) / stacks); polygons.Add(new Polygon(vertices)); } } return(CSG.fromPolygons(polygons)); }
/// <summary> /// Cube function, Untested but compiles /// </summary> /// <param name="center">world space center of the cube</param> /// <param name="radius">size of the cube created at center</param> /// <returns></returns> public static CSG cube(Vector3?center, Vector3?radius) { Vector3 c = center.GetValueOrDefault(Vector3.zero); Vector3 r = radius.GetValueOrDefault(Vector3.one); //TODO: Test if this works Polygon[] polygons = new Polygon[6]; int[][][] data = new int[][][] { new int[][] { new int[] { 0, 4, 6, 2 }, new int[] { -1, 0, 0 } }, new int[][] { new int[] { 1, 3, 7, 5 }, new int[] { 1, 0, 0 } }, new int[][] { new int[] { 0, 1, 5, 4 }, new int[] { 0, -1, 0 } }, new int[][] { new int[] { 2, 6, 7, 3 }, new int[] { 0, 1, 0 } }, new int[][] { new int[] { 0, 2, 3, 1 }, new int[] { 0, 0, -1 } }, new int[][] { new int[] { 4, 5, 7, 6 }, new int[] { 0, 0, 1 } } }; for (int x = 0; x < 6; x++) { int[][] v = data[x]; Vector3 normal = new Vector3((float)v[1][0], (float)v[1][1], (float)v[1][2]); IVertex[] verts = new IVertex[4]; for (int i = 0; i < 4; i++) { verts[i] = new Vertex( new Vector3( c.x + (r.x * (2 * (((v[0][i] & 1) > 0) ? 1 : 0) - 1)), c.y + (r.y * (2 * (((v[0][i] & 2) > 0) ? 1 : 0) - 1)), c.z + (r.z * (2 * (((v[0][i] & 4) > 0) ? 1 : 0) - 1))), normal ); } polygons[x] = new Polygon(verts); } return(CSG.fromPolygons(polygons)); }
/// <summary> /// Create CSG from array, does not clone the polygons /// </summary> /// <param name="polygon"></param> /// <returns></returns> private static CSG fromPolygons(Polygon[] polygons) { //TODO: Optimize polygons to share vertices CSG csg = new CSG(); csg.polygons.AddRange(polygons); return(csg); }
/// <summary> /// Clone /// </summary> /// <returns></returns> public CSG clone() { CSG csg = new CSG(); foreach (Polygon p in this.polygons) { csg.polygons.Add(p.clone()); } return csg; }
public CSG inverse() { CSG csg = this.clone(); foreach (Polygon p in csg.polygons) { p.flip(); } return(csg); }
/// <summary> /// Clone /// </summary> /// <returns></returns> public CSG clone() { CSG csg = new CSG(); foreach (Polygon p in this.polygons) { csg.polygons.Add(p.clone()); } return(csg); }
/// <summary> /// Construct a CSG solid from a list of `Polygon` instances. /// The polygons are cloned /// </summary> /// <param name="polygons"></param> /// <returns></returns> public static CSG fromPolygons(List <Polygon> polygons) { //TODO: Optimize polygons to share vertices CSG csg = new CSG(); foreach (Polygon p in polygons) { csg.polygons.Add(p.clone()); } return(csg); }
/// <summary> /// Return a new CSG solid representing space both this solid and in the /// solid `csg`. Neither this solid nor the solid `csg` are modified. /// </summary> /// <remarks> /// A.intersect(B) /// /// +-------+ /// | | /// | A | /// | +--+----+ = +--+ /// +----+--+ | +--+ /// | B | /// | | /// +-------+ /// </remarks> /// <param name="csg"></param> /// <returns>CSG of the intersection</returns> public CSG intersect(CSG csg) { Node a = new Node(this.polygons); Node b = new Node(csg.polygons); a.invert(); b.invert(); a.clipTo(b); b.clipTo(a); a.build(b.allPolygons()); return(CSG.fromPolygons(a.allPolygons()).inverse()); }
public static CSG fromMesh(Mesh m, Transform tf) { List <Polygon> triangles = new List <Polygon>(); int[] tris = m.triangles; for (int t = 0; t < tris.Length; t += 3) { Vertex[] vs = new Vertex[3]; vs[0] = TranslateVertex(m, tf, tris[t]); vs[1] = TranslateVertex(m, tf, tris[t + 1]); vs[2] = TranslateVertex(m, tf, tris[t + 2]); //Debug.Log("Tri index: " + (t+i).ToString() + ", Vertex: " + vs[i].pos); triangles.Add(new Polygon(vs)); } return(CSG.fromPolygons(triangles)); }
/// <summary> /// Return a new CSG solid representing space in this solid but not in the /// solid `csg`. Neither this solid nor the solid `csg` are modified. /// </summary> /// <remarks> /// A.subtract(B) /// +-------+ +-------+ /// | | | | /// | A | | | /// | +--+----+ = | +--+ /// +----+--+ | +----+ /// | B | /// | | /// +-------+ /// </remarks> /// <param name="csg"></param> /// <returns></returns> public CSG subtract(CSG csg) { Node a = new Node(this.polygons); Node b = new Node(csg.polygons); //Debug.Log(this.clone().polygons.Count + " -- " + csg.clone().polygons.Count); //Debug.Log("CSG.subtract: Node a = " + a.polygons.Count + " polys, Node b = " + b.polygons.Count + " polys."); a.invert(); a.clipTo(b); b.clipTo(a); b.invert(); b.clipTo(a); b.invert(); a.build(b.allPolygons()); a.invert(); return(CSG.fromPolygons(a.allPolygons())); }
/// <summary> /// Return a new CSG solid representing space both this solid and in the /// solid `csg`. Neither this solid nor the solid `csg` are modified. /// </summary> /// <remarks> /// A.intersect(B) /// /// +-------+ /// | | /// | A | /// | +--+----+ = +--+ /// +----+--+ | +--+ /// | B | /// | | /// +-------+ /// </remarks> /// <param name="csg"></param> /// <returns>CSG of the intersection</returns> public CSG intersect(CSG csg) { Node a = new Node(this.polygons); Node b = new Node(csg.polygons); a.invert(); //Debug.Log("Intersect 1 polygons: " + a.polygons.Count); b.invert(); //Debug.Log("Intersect 2 polygons: " + b.polygons.Count); a.clipTo(b); //Debug.Log("Intersect 3 polygons: " + a.polygons.Count); b.clipTo(a); //Debug.Log("Intersect 5 polygons: " + b.polygons.Count); a.build(b.allPolygons()); //Debug.Log("Intersect 6 polygons: " + a.polygons.Count); //Debug.Log("Intersect 7 all polygons: " + a.allPolygons().Count); //Debug.Log("Intersect 8 polygons finalll cgs: " + CSG.fromPolygons(a.allPolygons()).inverse().polygons.Count); return(CSG.fromPolygons(a.allPolygons()).inverse()); }
public CSG subtract(GameObject targetGo, GameObject brushGo) { Model.submeshIndices = new List <List <int> >(); Model csg_model_a = new Model(targetGo.gameObject, false, false); Model csg_model_b = new Model(brushGo.gameObject, true, false); Node a = new Node(csg_model_a.ToPolygons()); Node b = new Node(csg_model_b.ToPolygons()); //Debug.Log(this.clone().polygons.Count + " -- " + csg.clone().polygons.Count); //Debug.Log("CSG.subtract: Node a = " + a.polygons.Count + " polys, Node b = " + b.polygons.Count + " polys."); a.invert(); a.clipTo(b); b.clipTo(a); b.invert(); b.clipTo(a); b.invert(); a.build(b.allPolygons()); a.invert(); return(CSG.fromPolygons(a.allPolygons())); }
/// <summary> /// Create CSG from array, does not clone the polygons /// </summary> /// <param name="polygon"></param> /// <returns></returns> private static CSG fromPolygons(Polygon[] polygons) { //TODO: Optimize polygons to share vertices CSG csg = new CSG(); csg.polygons.AddRange(polygons); return csg; }
/// <summary> /// Construct a CSG solid from a list of `Polygon` instances. /// The polygons are cloned /// </summary> /// <param name="polygons"></param> /// <returns></returns> public static CSG fromPolygons(List<Polygon> polygons) { //TODO: Optimize polygons to share vertices CSG csg = new CSG(); foreach (Polygon p in polygons) { csg.polygons.Add(p.clone()); } return csg; }
/// <summary> /// Return a new CSG solid representing space both this solid and in the /// solid `csg`. Neither this solid nor the solid `csg` are modified. /// </summary> /// <remarks> /// A.intersect(B) /// /// +-------+ /// | | /// | A | /// | +--+----+ = +--+ /// +----+--+ | +--+ /// | B | /// | | /// +-------+ /// </remarks> /// <param name="csg"></param> /// <returns>CSG of the intersection</returns> public CSG intersect(CSG csg) { Node a = new Node(this.polygons); Node b = new Node(csg.polygons); a.invert(); b.invert(); a.clipTo(b); b.clipTo(a); a.build(b.allPolygons()); return CSG.fromPolygons(a.allPolygons()).inverse(); }
/// <summary> /// Return a new CSG solid representing space in this solid but not in the /// solid `csg`. Neither this solid nor the solid `csg` are modified. /// </summary> /// <remarks> /// A.subtract(B) /// +-------+ +-------+ /// | | | | /// | A | | | /// | +--+----+ = | +--+ /// +----+--+ | +----+ /// | B | /// | | /// +-------+ /// </remarks> /// <param name="csg"></param> /// <returns></returns> public CSG subtract(CSG csg) { Node a = new Node(this.polygons); Node b = new Node(csg.polygons); //Debug.Log(this.clone().polygons.Count + " -- " + csg.clone().polygons.Count); //Debug.Log("CSG.subtract: Node a = " + a.polygons.Count + " polys, Node b = " + b.polygons.Count + " polys."); a.invert(); a.clipTo(b); b.clipTo(a); b.invert(); b.clipTo(a); b.invert(); a.build(b.allPolygons()); a.invert(); return CSG.fromPolygons(a.allPolygons()); }