/** * Recursive version of ClipOutTriangles. This method partitions the triangles * in @triangles using @node's split plane, and then recursively calls itself * with the resulting greater-than and less-than lists. If the recursion reaches a * point where triangles in @triangles are on the back side of @node's split plane, * but this instance of BSPTree contains no geometry on that side (node.LessThan == null), * then the triangles placed in @lessThan are deleted from @triangles. This removes * the portions of triangles in @triangles that lie inside the geometry of this BSPTree * instance. * * If @clippLessThan is false, then we perform the reverse of the above oepration. * Triangles placed in @greaterThan than are removed when node.GreaterThan == null. * In that case the portions of triangles in @triangles that lie outside the geometry * of this BSPTree instance are removed. */ private void ClipOutTriangles(Node node, FastLinkedList <Triangle> triangles, bool clipLessThan = true, IList <Triangle> discarded = null) { if (triangles == null || triangles.First == null) { return; } if (node == null) { return; } FastLinkedList <Triangle> lessThan = new FastLinkedList <Triangle>(); FastLinkedList <Triangle> greaterThan = new FastLinkedList <Triangle>(); // iterate through each triangle in @triangles and classify/partition each according // @node's split plane. triangles on the front side go into @greaterThan, triangles // on the back side go into @lessThan. co-planar triangles whose normal matches that of // @node's split plane go into @greaterThan; the rest go into @lessThan. triangles.Iterate((Triangle tri) => { Partitioner.Orientation orient = Partitioner.SliceTriangle(tri, node.SplitPlane, lessThan, greaterThan, lessThan, greaterThan, true); }); // release memory used by @triangles triangles.Clear(); // recurse on the back side of @node's split plane if this BSPTree contains // geometry on that side. if it does not, and we want to clip out triangles // inside this BSPTree's geometry (@clipLessThan == true), then we clear out @lessThan. if (node.LessThan != null) { ClipOutTriangles(node.LessThan, lessThan, clipLessThan, discarded); } else if (clipLessThan) { if (discarded != null) { lessThan.CopyInto(discarded); } lessThan.Clear(); } // recurse on the front side of @node's split plane if this BSPTree contains // geometry on that side. if it does not, and we want to clip out triangles // outside this BSPTree's geometry (@clipLessThan == false), then we clear out @greaterThan. if (node.GreaterThan != null) { ClipOutTriangles(node.GreaterThan, greaterThan, clipLessThan, discarded); } else if (!clipLessThan) { if (discarded != null) { greaterThan.CopyInto(discarded); } greaterThan.Clear(); } // rebuild @triangles with the properly clipped triangles triangles.AppendIntoList(lessThan); triangles.AppendIntoList(greaterThan); }