Your check is painfully slow and should be heavily refactored. It’s not the correct logic for frustum culling—you don’t ever check on a point-by-point basis.

Assuming your AABB is in the following format:

/**
* Class CAabb
* \brief A min-max axis-aligned bounding box.
*
* Description: A min-max axis-aligned bounding box.
*/
class CAabb {
// All is public. This class has no secrets.
public :
// == Members.
/**
* The minimum X-, Y-, and Z- axis values.
*/
CVector3 m_vMin;
/**
* The maximum X-, Y-, and Z- axis values.
*/
CVector3 m_vMax;
};

And your frustum is an array of 6 planes, the code to check for being

*outside* of the frustum (the only thing you need to cull) is as follows:

First you need to classify the AABB with respect to a plane. And you should return enumerations, not integers. Enumerations are numbers with easily understood meanings. So starting with a

*classify* method:

/**
* Classifies an axis-aligned bounding box in relation to a given plane.
*
* \param _aAabb The AABB to test against the given plane.
* \param _pPlane The plane to test against the given AABB.
* \return Returns a plane classification.
*/
LSE_INLINE LSM_PLANE_INTERSECT LSE_CALL CClassify::Aabb( const CAabb &_aAabb, const CPlane3 &_pPlane ) {
// Center of the AABB.
CVector3 vC = (_aAabb.m_vMax + _aAabb.m_vMin) * LSM_HALF;
// Positive extents.
CVector3 vE = _aAabb.m_vMax - vC;
// Compute the projected interval radius of _aAabb onto L(t) = _aAabb.c + t * _pPlane.n.
LSREAL fR = vE[0] * CMathLib::Abs( _pPlane.n[0] ) +
vE[1] * CMathLib::Abs( _pPlane.n[1] ) +
vE[2] * CMathLib::Abs( _pPlane.n[2] );
// Distance from box center to plane.
LSREAL fS = _pPlane.n.Dot( vC ) - _pPlane.dist;
// If less than R, return overlap.
if ( CMathLib::Abs( fS ) <= fR ) { return LSM_PI_INTERSECT; }
// Otherwise it is in front or back of the plane.
return fS > fR ? LSM_PI_FRONT : LSM_PI_BACK;
}

And then you can easily just check the 6 planes on the frustum as a “test” method (a method that early-outs when a fail condition is met, but in exchange for this early-out it returns only true/false and no other information such as intersecting the frustum or being fully inside, etc.):

/**
* Determines if the given AABB is partially or entirely inside the frustum.
*
* \param _aAabb The AABB to check for being partially or fully inside the frustum.
* \param _fFrustum The frustum.
* \return Returns true if the AABB is fully or partially inside the given frustum.
*/
LSE_INLINE LSBOOL LSE_CALL CTest::AabbFrustum( const CAabb &_aAabb, const CFrustum &_fFrustum ) {
if ( (CClassify::Aabb( _aAabb, _fFrustum[LSM_FP_LEFT] ) == LSM_PI_BACK)
|| (CClassify::Aabb( _aAabb, _fFrustum[LSM_FP_RIGHT] ) == LSM_PI_BACK)
|| (CClassify::Aabb( _aAabb, _fFrustum[LSM_FP_TOP] ) == LSM_PI_BACK)
|| (CClassify::Aabb( _aAabb, _fFrustum[LSM_FP_BOTTOM] ) == LSM_PI_BACK)
|| (CClassify::Aabb( _aAabb, _fFrustum[LSM_FP_NEAR] ) == LSM_PI_BACK)
|| (CClassify::Aabb( _aAabb, _fFrustum[LSM_FP_FAR] ) == LSM_PI_BACK) ) {
return false;
}
return true;
}

In other words, instead of rendering anything that either intersects the frustum or is inside it, your logic should be flipped so that you

*don’t* render what is

*outside* the frustum.

L. Spiro

**Edited by L. Spiro, 11 October 2013 - 07:54 AM.**