in libraries/hvvr/shared/bvh.cpp [427:467]
std::vector<Box4> buildBVH4(std::vector<Box2>& node2s) {
std::vector<Box4> nodePlus4s((node2s.size() + 2) / 3);
// Collapse the 2-BVH to a 4-BVH. Note: out is updated by the helper function.
Box4* out = nodePlus4s.data() + nodePlus4s.size();
BoxPlus cache[3];
uint32_t cacheSize = helpBuildBVH4(out, node2s.data(), cache, 0);
// Check to see if we need to process the root separately.
if (cacheSize == 1) {
if (nodePlus4s.data() != out)
fail("Internal consistency LogFatalure with respect to BVH4 normalization.");
return nodePlus4s;
}
// Allocate a new box from the output list.
BoxPlus* outBoxes = (--out)->boxes;
if (nodePlus4s.data() != out)
fail("Internal consistency LogFatalure with respect to BVH4 normalization.");
// Add some empty boxes to fill up the output;
BoxPlus empty = {};
for (uint32_t extra = 4 - cacheSize; extra; --extra)
*outBoxes++ = empty;
// Add these boxes to the root.
for (uint32_t i = 0; i < cacheSize; i++) {
// Update the cache offsets.
if (cache[i].offset)
cache[i].offset -= (uint32_t)(out - (Box4*)nullptr);
*outBoxes++ = cache[i];
}
// Sort each box such that the leaves are first and nodes of the same type are sorted by surface area.
std::sort(out->boxes, out->boxes + 4, [](const BoxPlus& a, const BoxPlus& b) {
return (a.offset == 0 && b.offset != 0) ||
((a.offset == 0 || b.offset != 0) && a.box.surfaceArea() > b.box.surfaceArea());
});
return nodePlus4s;
}