Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


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.

  • You cannot reply to this topic
3 replies to this topic

#1 ic0de   Members   -  Reputation: 909

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;


Sponsor:

#2 L. Spiro   Crossbones+   -  Reputation: 14198

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
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#3 Krypt0n   Crossbones+   -  Reputation: 2631

Like
2Likes
Like

Posted 01 February 2013 - 12:39 AM

your bug is indeed in 

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]));


#4 ic0de   Members   -  Reputation: 909

Like
0Likes
Like

Posted 01 February 2013 - 07:11 AM

your bug is indeed in 

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.



PARTNERS