public static SliceTriangle ( CSG.Triangle triangle, Plane plane, IList |
||
triangle | CSG.Triangle | |
plane | Plane | |
lessThan | IList |
|
greaterThan | IList |
|
lessThanPlanar | IList |
|
greaterThanPlanar | IList |
|
return | Orientation |
/** * Rescursive version of AddTriangles. 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. */ private void AddTriangles(Node node, FastLinkedList <Triangle> triangles) { if (triangles == null) { return; } if (node == null) { return; } // get a reference to the list of triangles that are co-planar with // @node's split plane FastLinkedList <Triangle> nodeTriangles = node.GetTriangleList(); 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. co-planar triangles go into @nodeTriangles, triangles on the front // side go into @greaterThan, traingles on the back side go into @lessThan. triangles.Iterate((Triangle tri) => { Partitioner.Orientation orient = Partitioner.SliceTriangle(tri, node.SplitPlane, lessThan, greaterThan, nodeTriangles, nodeTriangles); }); // release clear memory occupied by @triangles triangles.Clear(); // recurse on the back side of @node's split plane if (lessThan.First != null) { if (node.LessThan == null) { node.LessThan = Node.Create(lessThan.First.Value.OrientationPlane); } AddTriangles(node.LessThan, lessThan); } // recurse on the front side of @node's split plane if (greaterThan.First != null) { if (node.GreaterThan == null) { node.GreaterThan = Node.Create(greaterThan.First.Value.OrientationPlane); } AddTriangles(node.GreaterThan, greaterThan); } }
/** * Returns geometry corresponding to volume @a that is divided into * two separate pieces by @b, but @b is treated as a plane (the first split plane * from the first node is used for splitting). * * Return results in the form of two List<Triangle> instances: @side and @side2. */ public static void FastSlice(BSPTree a, BSPTree b, out List <Triangle> side1, out List <Triangle> side2) { side1 = null; side2 = null; BSPTree bClone = b.Clone(); float startTime = Time.realtimeSinceStartup; bClone.ClipByTree(a, false); float clipTime = Time.realtimeSinceStartup - startTime; List <Triangle> aTriangles = a.GetAllTriangles(); List <Triangle> bTriangles = bClone.GetAllTriangles(); bClone.Invert(); List <Triangle> bInvertedTriangles = bClone.GetAllTriangles(); if (bTriangles.Count > 0) { Plane splitPlane = bTriangles[0].OrientationPlane; side1 = new List <Triangle>(); side2 = new List <Triangle>(); var coplanar = new List <Triangle>(); for (int i = 0; i < aTriangles.Count; i++) { Triangle tri = aTriangles[i]; Partitioner.SliceTriangle(tri, splitPlane, side1, side2, coplanar, coplanar); } side1.AddRange(bTriangles); side2.AddRange(bInvertedTriangles); } else { side1 = aTriangles; side2 = null; } }
/** * 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); }