internal void InitInterior(BVHBuildNode left, BVHBuildNode right, int axis) {
     children[0] = left;
     children[1] = right;
     splitAxis = axis;
     bounds = left.bounds.Union(right.bounds);
     nPrims = 0;
 }
 public void InitInterior(int axis, BVHBuildNode c0, BVHBuildNode c1)
 {
     children[0] = c0;
     children[1] = c1;
     bounds      = c0.bounds.Union(c1.bounds);
     splitAxis   = axis;
 }
Beispiel #3
0
        private int FlattenBuildTree(BVHBuildNode node, ref int offset)
        {
            var linearNode = nodes[offset];

            linearNode.Bounds = node.Bounds;

            var myOffset = offset++;

            // Leaf node
            if (node.PrimitiveCount > 0)
            {
                linearNode.PrimitivesOffset = node.FirstPrimitiveOffset;
                linearNode.PrimitiveCount   = node.PrimitiveCount;
            }
            // Interior node
            else
            {
                linearNode.Axis           = node.SplitAxis;
                linearNode.PrimitiveCount = 0;

                FlattenBuildTree(node.Children[0], ref offset);

                linearNode.SecondChildOffset = FlattenBuildTree(node.Children[1], ref offset);
            }

            return(myOffset);
        }
Beispiel #4
0
 public void InitInterior(int axis, BVHBuildNode child1, BVHBuildNode child2)
 {
     Children[0]    = child1;
     Children[1]    = child2;
     PrimitiveCount = 0;
     Bounds         = child1.Bounds.Union(child2.Bounds);
     SplitAxis      = axis;
 }
Beispiel #5
0
    // List of BVHPrimitive infos including each triangle of the object
    // Start/end/total nodes for recursive split of the list
    private BVHBuildNode BuildRecursiveBVH(ref List <BVHPrimitiveInfo> primitiveInfos,
                                           int start, int end, ref int totalNodes)
    {
        BVHBuildNode node = new BVHBuildNode();

        totalNodes++;

        Bounds3 bounds = new Bounds3();

        bounds.pMin = Vector3.positiveInfinity;
        bounds.pMax = Vector3.negativeInfinity;

        // Calculate bounds of the parent BVH node from its children
        for (int i = start; i < end; i++)
        {
            bounds = bounds.Union(primitiveInfos[i].bounds);
        }

        int nPrimitives = end - start;

        // Create leaf
        if (nPrimitives == 1)
        {
            node.InitLeaf(primitiveInfos[start].triangleNo, bounds);
            return(node);
        }

        else
        {
            Bounds3 centroidBounds = new Bounds3();
            centroidBounds.pMin = Vector3.positiveInfinity;
            centroidBounds.pMax = Vector3.negativeInfinity;

            for (int i = start; i < end; i++)
            {
                centroidBounds = centroidBounds.Union(primitiveInfos[i].center);
            }
            int dim = centroidBounds.MaximumExtend();

            int mid = (start + end) / 2;

            // Order Primitives in axis 'dim' and split the list into 2 equal sized lists
            EqualCounts(ref primitiveInfos, dim, start, end);

            node.InitInterior(dim,
                              BuildRecursiveBVH(ref primitiveInfos, start, mid, ref totalNodes),
                              BuildRecursiveBVH(ref primitiveInfos, mid, end, ref totalNodes)
                              );
            return(node);
        }
    }
Beispiel #6
0
    public BVHAcc(ref List <BVHPrimitiveInfo> primitiveInfos)
    {
        //Debug.Log("count of primitiveInfos: " + primitiveInfos.Count);

        int totalNodes = 0;

        root = BuildRecursiveBVH(ref primitiveInfos, 0, primitiveInfos.Count, ref totalNodes);

        //Debug.Log("Total nodes: " + totalNodes);
        LinearBVHArr = new LinearBVHNode[totalNodes];
        int offset = 0;

        FlattenBVHTree(root, ref offset);
        //Debug.Log("offset: " + offset);
    }
Beispiel #7
0
    private int FlattenBVHTree(BVHBuildNode node, ref int offset)
    {
        int myOffset = offset++;

        LinearBVHArr[myOffset].bounds          = node.bounds;
        LinearBVHArr[myOffset].primitiveOffset = node.triangleNo;

        // Inner node
        if (node.triangleNo < 0)
        {
            FlattenBVHTree(node.children[0], ref offset);
            LinearBVHArr[myOffset].secondChildOffset =
                FlattenBVHTree(node.children[1], ref offset);
        }

        return(myOffset);
    }
Beispiel #8
0
        private BVHBuildNode RecursiveBuild(List <PrimitiveInfo> primitiveInfos, int start, int end, ref int nodeCount, ref List <Primitive> orderedPrimitives)
        {
            var node = new BVHBuildNode();

            ++nodeCount;

            // Compute the bounds of all the primitives below this node
            Bounds3 <float> bounds = new Bounds3 <float>();

            for (var i = start; i < end; ++i)
            {
                bounds = bounds.Union(primitiveInfos[i].Bounds);
            }

            var primitiveCount = end - start;

            // Create leaf node
            if (primitiveCount == 1)
            {
                var firstPrimitiveOffset = orderedPrimitives.Count();

                for (var i = start; i < end; ++i)
                {
                    orderedPrimitives.Add(allPrimitives[primitiveInfos[i].Index]);
                }

                node.InitLeaf(firstPrimitiveOffset, primitiveCount, bounds);
            }
            // Create interior node
            else
            {
                // Choose the axis to split (with the longest extent)
                var centroidBounds = new Bounds3 <float>();
                for (var i = start; i < end; ++i)
                {
                    centroidBounds = centroidBounds.Union(primitiveInfos[i].Centroid);
                }
                var dim = centroidBounds.MaximumExtent();

                var mid = (start + end) / 2;

                // Juste create a leaf node if the bounds have zero volume
                // (all centroids are at the same position)
                if (centroidBounds.Max[dim] == centroidBounds.Min[dim])
                {
                    var firstPrimitiveOffset = orderedPrimitives.Count();

                    for (var i = start; i < end; ++i)
                    {
                        orderedPrimitives.Add(allPrimitives[primitiveInfos[i].Index]);
                    }

                    node.InitLeaf(firstPrimitiveOffset, primitiveCount, bounds);
                }
                else
                {
                    // Sort primitives in the current range along the split dimension

                    var orderedRange = primitiveInfos
                                       .GetRange(start, end - start)
                                       .OrderBy(p => p.Centroid[dim]);

                    primitiveInfos = primitiveInfos.GetRange(0, start)
                                     .Concat(orderedRange)
                                     .Concat(primitiveInfos.GetRange(end, primitiveInfos.Count - end))
                                     .ToList();

                    // Recursively split the rest of the tree
                    node.InitInterior(
                        dim,
                        RecursiveBuild(primitiveInfos, start, mid, ref nodeCount, ref orderedPrimitives),
                        RecursiveBuild(primitiveInfos, mid, end, ref nodeCount, ref orderedPrimitives));
                }
            }

            return(node);
        }