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; }
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); }
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; }
// 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); } }
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); }
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); }
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); }