Strange frustum problem...

Started by
14 comments, last by cozzie 13 years, 6 months ago
Hi all,

When I check a sphere against my frustum (d3d dx9 engine, c++), it's all good.
Now I made a function to check a bounding box against the frustum, but it now does this:

every object is only rendered when it's inside the frustum AND somehow intersects with the frustum planes.

I've double checked the min and max positions of the bounding boxes, they're all ok.

Can someone help me out?

Here's the code:

bool CD3dcam::SphereInFrustum(D3DXVECTOR3* pPosition, float pRadius){	float fDistance;	for(int i=0;i<6;++i)    {		fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pPosition) + pRadius;		if(fDistance < -pRadius) return false; // outside the frustum		if((float)fabs(fDistance) < pRadius) return true; // intersects    }    return true; // inside the frustum completely or intersecting; see XLS}// NO PROBLEMS WITH SHERE CHECKINGbool CD3dcam::BoxInFrustum(D3DXVECTOR3* pMinPosition, D3DXVECTOR3* pMaxPosition){	float fDistance;	for(int i=0;i<6;++i)    {		fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);		if(fDistance <= 0) return true;		fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMaxPosition);		if(fDistance <= 0) return true;    }	return false;}

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement
fDistance = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);
if(fDistance >= 0) return true;

maybe...
Just a quick look (didn't go into it in depth):

Should:

if(fDistance <= 0) return true;

be?:

if(fDistance >= 0) return true;

EDIT: ninja'd

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

hi szecs,
that would sound logical indeed, because inside the frustum the value should allways be 0 or higher.
I tried it out, but now all objects are rendered at all time, even when there not in the frustum (I keep a counter).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Just think about it a bit, and you should see what's the problem.

For example if the first condition is not true the second one will surely be: the two conditions should be in AND relation, now they are in OR (think about it)
Reviewed your code. Any coordinate in the world will be on the positive side of one of the frustum planes.

Try checking for both min/max < 0 for each plane. That will, at least, cull boxes entirely on the outside of one of the planes.

EDIT:
fdist1 = D3DXPlane..(plane,min);
fdist2 = D3DXPlane..(plane,max);
if( fdist1 < 0 && fdist2 < 0 ) return false;

If false is not returned for any frustum plane, return true.

EDIT: ninja #2 [smile]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Both thanks for the hints, I understand that I should check both (and not or), the reason why I used or is that I also want to render boxen that intersect the frustum.

I changed the code now to this:

bool CD3dcam::BoxInFrustum(D3DXVECTOR3* pMinPosition, D3DXVECTOR3* pMaxPosition){	float fDistanceMin, fDistanceMax;	for(int i=0;i<6;i++)    {		fDistanceMin = D3DXPlaneDotCoord(&mFrustumPlane, pMinPosition);		fDistanceMax = D3DXPlaneDotCoord(&mFrustumPlane, pMaxPosition);		if(fDistanceMin < 0 && fDistanceMax < 0) return false;     }	return true;}

This works almost, only now objects that are not fully in the frustum are not rendered I think. When I change it to '<= 0' instead of "<0" still objects that are partially in the frustum are not returned as 'true' and therefor not rendered.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Because you're using AABB, it's possible that min and max could be outside the frustum, but one of the corners (not min or max) could be inside the frustum.

I think you'll have to test all 8 corners of the AABB.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Ok, I can make that work and code that.
But will checking all 8 points still be be quicker then just checking all objects (included boxes) with a radius as a bounding sphere?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Quote:But will checking all 8 points still be be quicker then just checking all objects (included boxes) with a radius as a bounding sphere?

Unfortunately, no. However, depending on how many objects and what their shapes are, you can cull bounding spheres that are outside the frustum. Then do the full 8 point AABB check only for those objects whose bounding spheres are not outside the frustum.

EDIT: I don't know how you determine the bounding radius, but you can precalculate the radius (and sphere center position) for each object if you don't already. That would speed things up a bit as you wouldn't have to calculate the radius for each "in-frustum" call.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement