示例#1
0
        /**
         * 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);
        }