Beispiel #1
0
        /**
         * Create a new BSPTree instance from @mesh using @transform
         * to transform all vertices, normals, and tangents.
         */
        public static BSPTree FromMesh(Mesh mesh, Matrix4x4 transform)
        {
            BSPTree tree = new BSPTree();

            // get a list of all triangles in @mesh
            List <Triangle> meshTriangles = GetMeshTriangles(mesh);

            // loop through each triangle and transform its vertices by @transform
            for (int i = 0; i < meshTriangles.Count; i++)
            {
                Triangle tri = meshTriangles[i];

                for (int vi = 0; vi < 3; vi++)
                {
                    Vertex vtx = TransformVertex(tri.GetVertexByIndex(vi), transform);
                    tri.SetVertexByIndex(vi, vtx);
                }

                tri.RebuildOrientationPlane();
                meshTriangles[i] = tri;
            }

            tree.AddTriangles(meshTriangles);
            return(tree);
        }
Beispiel #2
0
        /**
         * Produce a deep copy of this BSPTree instance.
         */
        public BSPTree Clone()
        {
            BSPTree copy = new BSPTree();

            copy.root = Clone(root);
            return(copy);
        }
Beispiel #3
0
 /**
  * Create a Mesh instance from @tree.
  */
 public static Mesh FromBSPtree(BSPTree tree)
 {
     if (tree == null)
     {
         return(null);
     }
     return(FromList(tree.GetAllTriangles()));
 }
Beispiel #4
0
        /**
         * Recursive version of ClipByTree. This method recursively visits each node in this
         * BSPTree instance and clips the triangles of each based on the geometry of @tree.
         * By default it will remove the portions of triangles that are completely inside the
         * geometry contained by @tree.
         *
         * If @clipLessThan is false, the operation is reversed and triangle portions
         * outside the geometry of @tree instance are removed.
         */
        private void ClipByTree(Node node, BSPTree tree, bool clipLessThan = true, IList <Triangle> discarded = null)
        {
            if (node == null)
            {
                return;
            }

            tree.ClipOutTriangles(node.GetTriangleList(), clipLessThan, discarded);
            ClipByTree(node.LessThan, tree, clipLessThan, discarded);
            ClipByTree(node.GreaterThan, tree, clipLessThan, discarded);
        }
Beispiel #5
0
        /**
         * Returns geometry corresponding to volume that is occupied by @a,
         * but not by @b.
         */
        public static BSPTree Subtract(BSPTree a, BSPTree b)
        {
            BSPTree aClone = a.Clone();
            BSPTree bClone = b.Clone();

            float startTime = Time.realtimeSinceStartup;

            bClone.Invert();
            bClone.ClipByTree(a, false);
            aClone.ClipByTree(b);
            aClone.AddTriangles(bClone.GetAllTriangles());

            return(aClone);
        }
Beispiel #6
0
        /**
         * Returns geometry corresponding to volume @a that is divided into
         * two separate pieces by @b. Return results in the form of two BSPTree
         * instances: @side and @side2.
         */
        public static void Slice(BSPTree a, BSPTree b, out BSPTree side1, out BSPTree side2)
        {
            side1 = a.Clone();
            BSPTree bClone = b.Clone();

            List<Triangle> side1Discarded = new List<Triangle>();

            bClone.Invert ();
            bClone.ClipByTree (a, false);
            side1.ClipByTree (b, true, side1Discarded);
            side1.AddTriangles(bClone.GetAllTriangles());

            bClone.Invert();
            side2 = new BSPTree();
            side2.AddTriangles(bClone.GetAllTriangles());
            side2.AddTriangles(side1Discarded);
        }
Beispiel #7
0
        /**
         * Returns geometry corresponding to volume @a that is divided into
         * two separate pieces by @b. Return results in the form of two BSPTree
         * instances: @side and @side2.
         */
        public static void Slice(BSPTree a, BSPTree b, out BSPTree side1, out BSPTree side2)
        {
            side1 = a.Clone();
            BSPTree bClone = b.Clone();

            List <Triangle> side1Discarded = new List <Triangle>();

            bClone.Invert();
            bClone.ClipByTree(a, false);
            side1.ClipByTree(b, true, side1Discarded);
            side1.AddTriangles(bClone.GetAllTriangles());

            bClone.Invert();
            side2 = new BSPTree();
            side2.AddTriangles(bClone.GetAllTriangles());
            side2.AddTriangles(side1Discarded);
        }
Beispiel #8
0
        /**
         * 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;
            }
        }
Beispiel #9
0
        /**
         * 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;
            }
        }
Beispiel #10
0
 /**
  * Produce a deep copy of this BSPTree instance.
  */
 public BSPTree Clone()
 {
     BSPTree copy = new BSPTree();
     copy.root = Clone(root);
     return copy;
 }
Beispiel #11
0
 /**
  * Remove the triangles in this BSPTree instance that are completely inside the
  * geometry contained by @tree. Triangles that are partially inside the geometry
  * are clipped against it.
  *
  * If @clipLessThan is false, the operation is reversed and triangle portions
  * outside the geometry of @tree instance are removed.
  */
 public void ClipByTree(BSPTree tree, bool clipLessThan = true, IList<Triangle> discarded = null)
 {
     ClipByTree (root, tree, clipLessThan, discarded);
 }
Beispiel #12
0
        /**
         * Recursive version of ClipByTree. This method recursively visits each node in this
         * BSPTree instance and clips the triangles of each based on the geometry of @tree.
         * By default it will remove the portions of triangles that are completely inside the
         * geometry contained by @tree.
         *
         * If @clipLessThan is false, the operation is reversed and triangle portions
         * outside the geometry of @tree instance are removed.
         */
        private void ClipByTree(Node node, BSPTree tree, bool clipLessThan = true, IList<Triangle> discarded = null)
        {
            if(node == null)return;

            tree.ClipOutTriangles (node.GetTriangleList(), clipLessThan, discarded);
            ClipByTree (node.LessThan, tree, clipLessThan, discarded);
            ClipByTree (node.GreaterThan, tree, clipLessThan, discarded);
        }
Beispiel #13
0
        /**
         * Returns geometry corresponding to volume that is occupied by @a,
         * but not by @b.
         */
        public static BSPTree Subtract(BSPTree a, BSPTree b)
        {
            BSPTree aClone = a.Clone();
            BSPTree bClone = b.Clone();

            bClone.Invert ();
            bClone.ClipByTree (a, false);
            aClone.ClipByTree (b);
            aClone.AddTriangles(bClone.GetAllTriangles());

            return aClone;
        }
Beispiel #14
0
 /**
  * Remove the triangles in this BSPTree instance that are completely inside the
  * geometry contained by @tree. Triangles that are partially inside the geometry
  * are clipped against it.
  *
  * If @clipLessThan is false, the operation is reversed and triangle portions
  * outside the geometry of @tree instance are removed.
  */
 public void ClipByTree(BSPTree tree, bool clipLessThan = true, IList <Triangle> discarded = null)
 {
     ClipByTree(root, tree, clipLessThan, discarded);
 }