예제 #1
0
        public BVH(List <Mesh> allMeshes)
        {
            //Build the BVH
            List <int> meshIndices = new List <int>();

            for (int i = 0; i < allMeshes.Count; i++)
            {
                meshIndices.Add(i);
            }

            _root = new BVHNode(meshIndices, allMeshes);
        }
예제 #2
0
        private void Subdivide(List <Mesh> allMeshes)
        {
            List <int> leftSide  = null;
            List <int> rightSide = null;

            float minimalSplitCost = float.MaxValue;

            float boxWidth   = Math.Abs(bounds.minX - bounds.maxX);
            float boxHeight  = Math.Abs(bounds.minY - bounds.maxY);
            float boxForward = Math.Abs(bounds.minZ - bounds.maxZ);

            int splitPlaneCount = Config.BINNING_SPLIT_PLANE_COUNT;

            GenerateBins(allMeshes, splitPlaneCount, boxWidth, boxHeight, boxForward, out List <List <int> > xBins, out List <List <int> > yBins, out List <List <int> > zBins);

            for (int i = 0; i < 3; i++)             //0 = X, 1 = Y, 2 = Z
            {
                for (int j = 0; j < splitPlaneCount; j++)
                {
                    float splitCost = SplitCost(i, j, allMeshes, xBins, yBins, zBins, out List <int> leftSideMeshes, out List <int> rightSideMeshes);

                    if (splitCost < minimalSplitCost)
                    {
                        leftSide  = leftSideMeshes;
                        rightSide = rightSideMeshes;

                        minimalSplitCost = splitCost;
                    }
                }
            }

            if (minimalSplitCost >= bounds.SurfaceArea() * meshIndices.Count)
            {
                isLeaf = true;
                return;
            }

            leftChildNode  = new BVHNode(leftSide, allMeshes);
            rightChildNode = new BVHNode(rightSide, allMeshes);
        }
예제 #3
0
        private void SubdivideWithAlternativeBinningMethod(List <Mesh> allMeshes)
        {
            List <int> leftSide         = new List <int>();
            List <int> rightSide        = new List <int>();
            float      minimalSplitCost = float.MaxValue;

            float boxWidth   = Math.Abs(bounds.minX - bounds.maxX);
            float boxHeight  = Math.Abs(bounds.minY - bounds.maxY);
            float boxForward = Math.Abs(bounds.minZ - bounds.maxZ);

            int splitBins = Config.BINNING_SPLIT_PLANE_COUNT;

            for (int i = 0; i < 3; i++)             //0 = X, 1 = Y, 2 = Z
            {
                float binSize = i == 0 ? boxWidth / splitBins : (i == 1 ? boxHeight / splitBins : boxForward / splitBins);

                for (int j = 0; j < splitBins; j++)
                {
                    float splitInterval = j * binSize;
                    float splitCost     = SplitCostWithAlternativeBinningMethod(i, splitInterval, allMeshes, out List <int> leftSideMeshes, out List <int> rightSideMeshes);

                    if (splitCost < minimalSplitCost)
                    {
                        leftSide  = leftSideMeshes;
                        rightSide = rightSideMeshes;

                        minimalSplitCost = splitCost;
                    }
                }
            }

            if (minimalSplitCost >= bounds.SurfaceArea() * meshIndices.Count)
            {
                isLeaf = true;
                return;
            }

            leftChildNode  = new BVHNode(leftSide, allMeshes);
            rightChildNode = new BVHNode(rightSide, allMeshes);
        }