in libraries/hvvr/shared/bvh.cpp [196:249]
size_t helpBuildBVH2(Box2* node, float* temp, const Box** boxes, size_t size) {
if (size < 2)
return 0;
// Look along each axis to determine which contains the lowest cost split.
int axis = 0;
size_t index = 0;
float cost = Infinity;
scanAxis(index, cost, temp, boxes, size, 0);
if (scanAxis(index, cost, temp, boxes, size, 1))
axis = 1;
if (scanAxis(index, cost, temp, boxes, size, 2))
axis = 2;
// Sort the boxes along the axis with the best split.
std::sort(boxes, boxes + size, [axis](const Box*& a, const Box*& b) {
return a->lower[axis] + a->upper[axis] <
b->lower[axis] + b->upper[axis];
});
// Recurse on the lower half of the split range.
size_t offset = 1;
if (size_t count = helpBuildBVH2(node + offset, temp, boxes, index)) {
node->boxes[0] = node[offset].bound();
node->offset(0) = (uint32_t)offset;
offset += count;
} else {
node->boxes[0] = *boxes[0];
for (size_t i = 1; i < index; i++)
node->boxes[0] |= *boxes[i];
node->offset(0) = 0;
}
node->size(0) = (uint32_t)index;
// Recurse on the upper half of the split range.
if (size_t count = helpBuildBVH2(node + offset, temp + index, boxes + index, size - index)) {
node->boxes[1] = node[offset].bound();
node->offset(1) = (uint32_t)offset;
offset += count;
} else {
node->boxes[1] = *boxes[index];
for (size_t i = index + 1; i < size; i++)
node->boxes[1] |= *boxes[i];
node->offset(1) = 0;
}
node->size(1) = (uint32_t)(size - index);
// Should we subdivide further? This controls the balance of tree depth vs leaf size.
// Check to see if this split costs more than just intersecting the triangles directly.
// Left side is the cost to intersect the triangles, right side is the cost to intersect the children.
const float nodeIntersectMultiplier = 2.0f; // intersecting a node costs the same as 2 triangles
// size < cost / node->bound().surfaceArea() + nodeIntersectMultiplier
return node->bound().surfaceArea() * (float(size) - nodeIntersectMultiplier) < cost ? 0 : offset;
}