// TODO : I think this is what this means public static CSG_Node Compliment(CSG_Node a1) { CSG_Node a = a1.Clone(); a.Invert(); return(a); }
public CSG_Node(List <CSG_Polygon> list, CSG_Plane plane, CSG_Node front, CSG_Node back) { this.polygons = list; this.plane = plane; this.front = front; this.back = back; }
public CSG_Tree(CSG_Tree lhs, CSG_Tree rhs, CSG_Operation op) { left = lhs; right = rhs; operation = op; current_object = null; }
public CSG_Node(List<CSG_Polygon> list, CSG_Plane plane, CSG_Node front, CSG_Node back) { this.polygons = list; this.plane = plane; this.front = front; this.back = back; }
public CSG_Node() { front = null; back = null; polygons = null; plane = null; }
// Invert the object - inner is the default representation of an object public static CSG_Node Outer(CSG_Node a1) { CSG_Node a = a1.Clone(); a.Invert(); return(a); }
//for leaf nodes public CSG_Tree(GameObject obj) { operation = CSG_Operation.no_op; CSG_Model csg_model_a = new CSG_Model(obj); current_object = new CSG_Node(csg_model_a.ToPolygons()); left = null; right = null; }
public void clean() { this.current_object = null; if (left != null) { left.clean(); } if (right != null) { right.clean(); } }
/// <summary> /// Returns a new mesh by intersecting @lhs with @rhs. /// </summary> /// <param name="lhs">The base mesh of the boolean operation.</param> /// <param name="rhs">The input mesh of the boolean operation.</param> /// <returns>A new mesh if the operation succeeds, or null if an error occurs.</returns> public static CSG_Model Intersect(GameObject lhs, GameObject rhs) { CSG_Model csg_model_a = new CSG_Model(lhs); CSG_Model csg_model_b = new CSG_Model(rhs); CSG_Node a = new CSG_Node(csg_model_a.ToPolygons()); CSG_Node b = new CSG_Node(csg_model_b.ToPolygons()); List <CSG_Polygon> polygons = CSG_Node.Intersect(a, b).AllPolygons(); return(new CSG_Model(polygons)); }
/** * Returns a new mesh by subtracting @rhs from @lhs. */ public static Mesh Subtract(GameObject lhs, GameObject rhs) { CSG_Model csg_model_a = new CSG_Model(lhs); CSG_Model csg_model_b = new CSG_Model(rhs); CSG_Node a = new CSG_Node(csg_model_a.ToPolygons()); CSG_Node b = new CSG_Node(csg_model_b.ToPolygons()); List <CSG_Polygon> polygons = CSG_Node.Subtract(a, b).AllPolygons(); CSG_Model result = new CSG_Model(polygons); return(result.ToMesh()); }
// Remove all polygons in this BSP tree that are inside the other BSP tree // `bsp`. public void ClipTo(CSG_Node other) { this.polygons = other.ClipPolygons(this.polygons); if (this.front != null) { this.front.ClipTo(other); } if (this.back != null) { this.back.ClipTo(other); } }
public void remove_references() { this.current_object = null; if (left != null) { left.remove_references(); left = null; } if (right != null) { right.remove_references(); right = null; } }
/** * Return a new mesh by intersecting @lhs with @rhs. This operation * is non-commutative, so set @lhs and @rhs accordingly. */ public static Mesh Intersect(GameObject lhs, GameObject rhs) { CSG_Model csg_model_a = new CSG_Model(lhs); CSG_Model csg_model_b = new CSG_Model(rhs); CSG_Node a = new CSG_Node( csg_model_a.ToPolygons() ); CSG_Node b = new CSG_Node( csg_model_b.ToPolygons() ); List<CSG_Polygon> polygons = CSG_Node.Intersect(a, b).AllPolygons(); CSG_Model result = new CSG_Model(polygons); return result.ToMesh(); }
// Build a BSP tree out of `polygons`. When called on an existing tree, the // new polygons are filtered down to the bottom of the tree and become new // nodes there. Each set of polygons is partitioned using the first polygon // (no heuristic is used to pick a good split). public void Build(List <CSG_Polygon> list) { if (list == null || list.Count < 1) { return; } if (plane == null || !plane.Valid()) { plane = new CSG_Plane { normal = list[0].plane.normal, w = list[0].plane.w }; } if (polygons == null) { polygons = new List <CSG_Polygon>(); } var listFront = new List <CSG_Polygon>(); var listBack = new List <CSG_Polygon>(); for (int i = 0; i < list.Count; i++) { plane.SplitPolygon(list[i], polygons, polygons, ref listFront, ref listBack); } if (listFront.Count > 0) { if (front == null) { front = new CSG_Node(); } front.Build(listFront); } if (listBack.Count > 0) { if (back == null) { back = new CSG_Node(); } back.Build(listBack); } }
// Build a BSP tree out of `polygons`. When called on an existing tree, the // new polygons are filtered down to the bottom of the tree and become new // nodes there. Each set of polygons is partitioned using the first polygon // (no heuristic is used to pick a good split). public void Build(List <CSG_Polygon> list) { if (list.Count < 1) { return; } if (this.plane == null || !this.plane.Valid()) { this.plane = new CSG_Plane(); this.plane.normal = list[0].plane.normal; this.plane.w = list[0].plane.w; } if (this.polygons == null) { this.polygons = new List <CSG_Polygon>(); } List <CSG_Polygon> list_front = new List <CSG_Polygon>(); List <CSG_Polygon> list_back = new List <CSG_Polygon>(); for (int i = 0; i < list.Count; i++) { this.plane.SplitPolygon(list[i], this.polygons, this.polygons, list_front, list_back); } if (list_front.Count > 0) { if (this.front == null) { this.front = new CSG_Node(); } this.front.Build(list_front); } if (list_back.Count > 0) { if (this.back == null) { this.back = new CSG_Node(); } this.back.Build(list_back); } }
internal CSG_Node render_tree() { if (operation == CSG_Operation.no_op) { CSG_Model csg_model_a = new CSG_Model(m); current_object = new CSG_Node(csg_model_a.ToPolygons()); return(current_object); } else { switch (operation) { case CSG_Operation.Inner: current_object = CSG_Node.Inner(left.render_tree()); return(current_object); case CSG_Operation.Outer: current_object = CSG_Node.Outer(left.render_tree()); return(current_object); case CSG_Operation.On: current_object = CSG_Node.On(left.render_tree()); return(current_object); case CSG_Operation.Compliment: current_object = CSG_Node.Compliment(left.render_tree()); return(current_object); case CSG_Operation.Union: current_object = CSG_Node.Union(left.render_tree(), right.render_tree()); return(current_object); case CSG_Operation.Intersect: current_object = CSG_Node.Intersect(left.render_tree(), right.render_tree()); return(current_object); case CSG_Operation.Subtract: current_object = CSG_Node.Subtract(left.render_tree(), right.render_tree()); return(current_object); } } return(null); }
// Return a new CSG solid representing space both this solid and in the // solid `csg`. Neither this solid nor the solid `csg` are modified. public static CSG_Node Intersect(CSG_Node a1, CSG_Node b1) { CSG_Node a = a1.Clone(); CSG_Node b = b1.Clone(); a.Invert(); b.ClipTo(a); b.Invert(); a.ClipTo(b); b.ClipTo(a); a.Build(b.AllPolygons()); a.Invert(); CSG_Node ret = new CSG_Node(a.AllPolygons()); return(ret); }
// Convert solid space to empty space and empty space to solid space. public void Invert() { for (int i = 0; i < this.polygons.Count; i++) this.polygons[i].Flip(); this.plane.Flip(); if (this.front != null) { this.front.Invert(); } if (this.back != null) { this.back.Invert(); } CSG_Node tmp = this.front; this.front = this.back; this.back = tmp; }
// Convert solid space to empty space and empty space to solid space. public void Invert() { for (int i = 0; i < this.polygons.Count; i++) { this.polygons[i].Flip(); } this.plane.Flip(); if (this.front != null) { this.front.Invert(); } if (this.back != null) { this.back.Invert(); } CSG_Node tmp = this.front; this.front = this.back; this.back = tmp; }
// Build a BSP tree out of `polygons`. When called on an existing tree, the // new polygons are filtered down to the bottom of the tree and become new // nodes there. Each set of polygons is partitioned using the first polygon // (no heuristic is used to pick a good split). public void Build(List<CSG_Polygon> list) { if (list.Count < 1) return; if (this.plane == null || !this.plane.Valid()) { this.plane = new CSG_Plane(); this.plane.normal = list[0].plane.normal; this.plane.w = list[0].plane.w; } if(this.polygons == null) this.polygons = new List<CSG_Polygon>(); List<CSG_Polygon> list_front = new List<CSG_Polygon>(); List<CSG_Polygon> list_back = new List<CSG_Polygon>(); for (int i = 0; i < list.Count; i++) { this.plane.SplitPolygon(list[i], this.polygons, this.polygons, list_front, list_back); } if (list_front.Count > 0) { if (this.front == null) this.front = new CSG_Node(); this.front.Build(list_front); } if (list_back.Count > 0) { if (this.back == null) this.back = new CSG_Node(); this.back.Build(list_back); } }
public void render() { current_object = render_tree(); }
public CSG_Node() { this.front = null; this.back = null; }
// Return a new CSG solid representing space both this solid and in the // solid `csg`. Neither this solid nor the solid `csg` are modified. public static CSG_Node Intersect(CSG_Node a1, CSG_Node b1) { CSG_Node a = a1.Clone(); CSG_Node b = b1.Clone(); a.Invert(); b.ClipTo(a); b.Invert(); a.ClipTo(b); b.ClipTo(a); a.Build(b.AllPolygons()); a.Invert(); CSG_Node ret = new CSG_Node(a.AllPolygons()); return ret; }
public CSG_Node Clone() { CSG_Node clone = new CSG_Node(this.polygons, this.plane, this.front, this.back); return(clone); }
public CSG_Node Clone() { CSG_Node clone = new CSG_Node(this.polygons, this.plane, this.front, this.back); return clone; }
// Do nothing because inner is the default representation of an object public static CSG_Node Inner(CSG_Node a1) { return(a1.Clone()); }
// TODO : I dont understand what on does public static CSG_Node On(CSG_Node a1) { return(a1.Clone()); }