uint32_t Frustum::testBVHNodeChildren()

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