public void testBSPTree()
    {
        Mesh mesh = (meshFilter.mesh.vertexCount > 0) ? meshFilter.mesh : meshFilter.sharedMesh;

        PrintMesh(mesh);

        var materials = new List <Material>(); meshRenderer.GetSharedMaterials(materials);
        var start     = System.DateTime.Now;

        tree = CSG.BSPTreeCreator.Construct(mesh, materials, maxTrianglesInLeaves, nbCandidates, precision);
        Debug.Log("BSPTree created in: " + (System.DateTime.Now - start).TotalMilliseconds + " ms");
        Debug.Log(tree.PrintString());
        Mesh computedMesh = tree.ComputeMesh();

        PrintMesh(computedMesh);

        GameObject go = new GameObject();

        go.AddComponent <MeshFilter>().sharedMesh        = computedMesh;
        go.AddComponent <MeshRenderer>().sharedMaterials = tree.Materials.ToArray();
        go.transform.localPosition = transform.localPosition;
        go.transform.localRotation = transform.localRotation;
        go.transform.localScale    = transform.localScale;
        go.transform.Translate(1.5f, 0, 0);
    }
Beispiel #2
0
        // -- UTILS' METHODS FOR THE GENERATION OF A BSPTREE

        private static bool ConstructInternal(this BSPNode node, int maxTrianglesInLeaves, int nbCandidates, float precision)
        {
            if (node == null || node.TrianglesCount <= maxTrianglesInLeaves)
            {
                return(true); // return without splitting, it's a leaf
            }

            // Compute split
            Plane plane = node.ChooseSplittingPlane(nbCandidates, precision);

            if (plane.normal == Vector3.zero)
            {
                Debug.Log("Impossible to compute a plane at depth " + node.DepthFromRoot + ". Try to increase precision or number of candidates.");
                return(false);
            }
            Split(node.SubMeshIndices, plane, node.MeshData.vertices, precision, out var zeros, out var plus, out var minus, out var newVertices);

            // Apply split
            node.Plane          = plane;
            node.Plus           = new BSPNode(node, node.MeshData, plus);
            node.Minus          = new BSPNode(node, node.MeshData, minus);
            node.SubMeshIndices = zeros;
            node.MeshData.AddData(newVertices);

            // recurse
            bool result = true;

            result &= node.Plus.ConstructInternal(maxTrianglesInLeaves, nbCandidates, precision);
            result &= node.Minus.ConstructInternal(maxTrianglesInLeaves, nbCandidates, precision);
            return(result);
        }
Beispiel #3
0
        public static GeneratedShape Intersect(Shape lhs, Shape rhs)
        {
            var a        = new BSPNode(lhs.CreatePolygons());
            var b        = new BSPNode(rhs.CreatePolygons());
            var polygons = BSPNode.Intersect(a, b).AllPolygons();

            return(new GeneratedShape(polygons));
        }
Beispiel #4
0
        public static BSPNode Construct(Mesh inMesh, List <Material> inMaterials, int maxTrianglesInLeaves = 1, int nbCandidates = 5, float precision = 1E-06f)
        {
            // retrieve indices by submesh index
            IndicesList subMeshIndices = new IndicesList(inMesh.subMeshCount);

            for (int i = 0; i < inMesh.subMeshCount; i++)
            {
                Debug.Assert(inMesh.GetTopology(i) == MeshTopology.Triangles, "Only triangle topology is supported by the BSP tree currently.");
                subMeshIndices.Add(inMesh.GetTriangles(i).ToList());
            }

            var rootNode = new BSPNode(null, new MeshData(inMesh, inMaterials), subMeshIndices);

            rootNode.ConstructInternal(maxTrianglesInLeaves, nbCandidates, precision);

            return(rootNode);
        }
Beispiel #5
0
        private static Plane ComputeSplittingPlane(this BSPNode node, int triangle)
        {
            int subMeshIndex        = 0;
            int firstIndexInSubMesh = triangle * 3;

            Debug.Assert(firstIndexInSubMesh < node.IndicesCount);
            while (subMeshIndex < node.SubMeshCount && firstIndexInSubMesh > node[subMeshIndex].Count)
            {
                firstIndexInSubMesh -= node[subMeshIndex].Count;
                subMeshIndex++;
            }

            var subMesh = node[subMeshIndex];
            var v0      = node.MeshData.vertices[subMesh[firstIndexInSubMesh]];
            var v1      = node.MeshData.vertices[subMesh[firstIndexInSubMesh + 1]];
            var v2      = node.MeshData.vertices[subMesh[firstIndexInSubMesh + 2]];

            Plane plane = new Plane();

            plane.Set3Points(v0, v1, v2);
            return(plane);
        }
Beispiel #6
0
        private static Plane ChooseSplittingPlane(this BSPNode node, int nbCandidates, float precision)
        {
            Plane bestCandidate = new Plane();
            int   bestResult    = int.MaxValue;

            for (int i = 0; i < nbCandidates && bestResult > 0; i++)
            {
                Plane candidate = node.ComputeSplittingPlane(Random.Range(0, node.TrianglesCount));
                if (candidate.normal != Vector3.zero)
                {
                    int result = SplitCost(node.SubMeshIndices, candidate, node.MeshData.vertices, precision);

                    if (result < bestResult)
                    {
                        bestCandidate = candidate;
                        bestResult    = result;
                    }
                }
            }

            return(bestCandidate);
        }