uint32_t Frustum::testBVHNodeChildrenRefine()

in libraries/hvvr/raycaster/traverse_ref_frustum.cpp [177:218]


uint32_t Frustum::testBVHNodeChildrenRefine(const BVHNode& node, uint32_t prevResult) const {
    uint32_t result = prevResult;

    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 the remaining axes of separation, the cross products of
    // unique edge direction combinations from the frustum and AABB
    for (int e = 0; e < edgeCount; e++) {
        for (int c = 0; c < childCount; c++) {
            // find the p-vertex
            vector3 pPoint(
                refineEdge[e].x >= 0 ? aabbMax[c].x : aabbMin[c].x,
                refineEdge[e].y >= 0 ? aabbMax[c].y : aabbMin[c].y,
                refineEdge[e].z >= 0 ? aabbMax[c].z : aabbMin[c].z);

            // find the n-vertex
            vector3 nPoint(
                refineEdge[e].x <  0 ? aabbMax[c].x : aabbMin[c].x,
                refineEdge[e].y <  0 ? aabbMax[c].y : aabbMin[c].y,
                refineEdge[e].z <  0 ? aabbMax[c].z : aabbMin[c].z);

            float dMax = dot(refineEdge[e], pPoint);
            float dMin = dot(refineEdge[e], nPoint);

            if (dMax < refineMin[e] || dMin > refineMax[e]) {
                result &= ~(1 << c); // child culled due to no overlap along the edge axis
            }
        }
    }

    return result;
}