in libraries/hvvr/raycaster/traverse_ref_frustum.cpp [131:175]
uint32_t Frustum::testBVHNodeChildren(const BVHNode& node) const {
uint32_t result = childMaskAll;
vector3 aabbMin[childCount];
vector3 aabbMax[childCount];
for (int c = 0; c < childCount; c++) {
aabbMin[c].x = -node.xNegMin[c];
aabbMin[c].y = -node.yNegMin[c];
aabbMin[c].z = -node.zNegMin[c];
aabbMax[c].x = node.xMax[c];
aabbMax[c].y = node.yMax[c];
aabbMax[c].z = node.zMax[c];
}
// test AABB against frustum faces
// n-vertex of AABB for this plane - the most negative along the plane normal
// n-vertex (and p-vertex) is a permutation of AABB min and max components
for (int p = 0; p < planeCount; p++) {
for (int c = 0; c < childCount; c++) {
vector3 nPoint(
plane[p].x < 0 ? aabbMax[c].x : aabbMin[c].x,
plane[p].y < 0 ? aabbMax[c].y : aabbMin[c].y,
plane[p].z < 0 ? aabbMax[c].z : aabbMin[c].z);
float d = dot(vector3(plane[p]), nPoint);
if (d > plane[p].w) {
result &= ~(1 << c); // child culled by frustum face
}
}
}
// test frustum against AABB faces
// check for overlap of frustum's projection onto AABB axes
for (int c = 0; c < childCount; c++) {
if (projMax.x < aabbMin[c].x || projMin.x > aabbMax[c].x ||
projMax.y < aabbMin[c].y || projMin.y > aabbMax[c].y ||
projMax.z < aabbMin[c].z || projMin.z > aabbMax[c].z) {
result &= ~(1 << c); // child culled due to no overlap
}
}
return result;
}