• Create Account

am I making a mistake with my frustum culling?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

3 replies to this topic

#1ic0de  Members

954
Like
0Likes
Like

Posted 31 January 2013 - 09:07 PM

I am trying to test an AABB against a frustum, the frustum is set up as a 6x4 2d array (6 plane equations). Somehow my code isn't exactly right. Here it is:

bool AABBInFrustum(vec min, vec max)
{
float m, n;
int i;

for (i = 0; i < 6; i++)
{
//basically two dot products
m = (min.x * Vfrustum[i][0]) + (min.y * Vfrustum[i][1]) + (min.z * Vfrustum[i][2]) + Vfrustum[i][3];
n = (max.x * fabs(Vfrustum[i][0])) + (max.y * fabs(Vfrustum[i][1])) + (max.z * fabs(Vfrustum[i][2]));

if(m + n < 0)
{
return false;
}
if(m - n < 0)
{
return true;
}
}

return true;
} 

I got the algorithm from here:
http://www.cescg.org/CESCG-2002/DSykoraJJelinek/index.html

min and max in my code are the two farthest corners of an axis aligned bounding box, I think that might be where I made a mistake I think I need to do something to the points before they can be plugged into the algorithm but the source isn't quite clear. Anybody know how to fix it?

Edited by ic0de, 31 January 2013 - 09:08 PM.

you know you program too much when you start ending sentences with semicolons;

#2L. Spiro  Members

24826
Like
1Likes
Like

Posted 31 January 2013 - 09:23 PM

This is how I do it.
	/**
* 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;
}
	/**
* 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;
}
The frustum is made of planes and each plane is a CVector3 and float distance.
Don’t mix your types. For example, you are doing a dot product manually. Why? Use your primitive types everywhere so that what you are doing is not only clearer but easier and faster to code.

L. Spiro

#3Krypt0n  Members

4529
Like
2Likes
Like

Posted 01 February 2013 - 12:39 AM

m = (min.x * Vfrustum[i][0]) + (min.y * Vfrustum[i][1]) + (min.z * Vfrustum[i][2]) + Vfrustum[i][3];
n = (max.x * fabs(Vfrustum[i][0])) + (max.y * fabs(Vfrustum[i][1])) + (max.z * fabs(Vfrustum[i][2]));

while you are using min and max, the paper actually states

Vector (mx,my,mz) represents the center of the AABB. Absolute values of the normal vector of the plane (a,b,c) transform all possible values to the first octant so its dot product with the vector representing a half of the AABB diagonal (dx,dy,dz) will be always positive.

so what you actually want to do is

m = ((min.x+max.x)*0.5f * Vfrustum[i][0]) + ((min.y+max.y)*0.5f * Vfrustum[i][1]) + ((min.z+max.z)*0.5f * Vfrustum[i][2]) + Vfrustum[i][3];
n = ((max.x-min.x)*0.5f * fabs(Vfrustum[i][0])) + ((max.y-min.y)*0.5f * fabs(Vfrustum[i][1])) + ((max.z-min.z)*0.5f * fabs(Vfrustum[i][2]));

#4ic0de  Members

954
Like
0Likes
Like

Posted 01 February 2013 - 07:11 AM

m = (min.x * Vfrustum[i][0]) + (min.y * Vfrustum[i][1]) + (min.z * Vfrustum[i][2]) + Vfrustum[i][3];
n = (max.x * fabs(Vfrustum[i][0])) + (max.y * fabs(Vfrustum[i][1])) + (max.z * fabs(Vfrustum[i][2]));
while you are using min and max, the paper actually states

Vector (mx,my,mz) represents the center of the AABB. Absolute values of the normal vector of the plane (a,b,c) transform all possible values to the first octant so its dot product with the vector representing a half of the AABB diagonal (dx,dy,dz) will be always positive.

so what you actually want to do is

m = ((min.x+max.x)*0.5f * Vfrustum[i][0]) + ((min.y+max.y)*0.5f * Vfrustum[i][1]) + ((min.z+max.z)*0.5f * Vfrustum[i][2]) + Vfrustum[i][3];
n = ((max.x-min.x)*0.5f * fabs(Vfrustum[i][0])) + ((max.y-min.y)*0.5f * fabs(Vfrustum[i][1])) + ((max.z-min.z)*0.5f * fabs(Vfrustum[i][2]));

Thank you, it works now

you know you program too much when you start ending sentences with semicolons;

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.