• Advertisement

Archived

This topic is now archived and is closed to further replies.

frustum culling, box outside but still inside

This topic is 5033 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have setup frustum culling and it seems to work except for one simple case where all the points of a box are outside the frustum planes but the box is still inside the frustum. What would be the best way to check for this, would I have to calculate out faces and edges for frustum and box and check those (probably slow) or is there a better way of doing this? anybody have any samples of how to do this special check? thanks

Share this post


Link to post
Share on other sites
Advertisement
Use a sphere instead of box for objects bigger than the frustrum.
[edit]
Alternatively, check for the center of the box if it is in the frustrum or not.

[edited by - Raduprv on May 9, 2004 4:44:55 PM]

Share this post


Link to post
Share on other sites
i have done both, sphere check also fails in that case and the center of the box isn''t in view either.

Share this post


Link to post
Share on other sites
actually checking the eye point, how do i check the whole frustum

Share this post


Link to post
Share on other sites
Well, basically, if all the box is outside the frustrum, but also inside of it then check for all the corners of the frustrum vs all the corners of the box...
Can you show a picture (ascii or something) to show the exact situation? (like where is the frustrum and where is the box).

Share this post


Link to post
Share on other sites

The situation is something like the following, so all the points are outside and yet the box should be visible



______________
\ /
.-\----------/--.
| \ / |
| \ / |
.----\----/-----.
\ /
\/
(eye)

Share this post


Link to post
Share on other sites
Then you can try some hack like:
If the object is betwen the close and the far plan, check to see if it is larger than the frustrum, and if one of it''s corners is in the left, and another in the right (left and right of the line perpendicular to the farplane, from the eye)

Share this post


Link to post
Share on other sites
Using a sphere instead of a box should work in this case.
Say we have a plane Ax+By+Cz+D (one of the 6 frustum planes),
and a sphere of radius R located at position px,py,pz,
if we want to know whether any part of the sphere lies within the frustum or not, we calculate a K factor this way:

K=A*px+B*py+C*pz+D

Now if K+R is negative the sphere is outside the frustum volume.

NOTE: If K+R isn''t negative means that the sphere might be inside the frustum, so we need to keep calculating with the rest of the planes.

Share this post


Link to post
Share on other sites

I do a sphere check at the beginning before checking all the points of the box. The sphere check fails though, i am using the exact same formula that you listed.

Share this post


Link to post
Share on other sites
i think you simply missed a little detail. all points of the box have to be outside the SAME frustum plane.

Share this post


Link to post
Share on other sites
Behold the magic:

void AxisAlignedBox::initLut(){
vertices[0]=Vector3(max[0], max[1], max[2]); vertices[1]=Vector3(max[0], max[1], min[2]);
vertices[2]=Vector3(max[0], min[1], max[2]); vertices[3]=Vector3(max[0], min[1], min[2]);
vertices[4]=Vector3(min[0], max[1], max[2]); vertices[5]=Vector3(min[0], max[1], min[2]);
vertices[6]=Vector3(min[0], min[1], max[2]); vertices[7]=Vector3(min[0], min[1], min[2]);
}


intersect_type AxisAlignedBox::classifyPlane(const Plane3& p) const{
Vector3 n(p.getNormal());
//const static float EPS(10e-7);

/* Three bit bit mask that is used to indicate sign of the
* components of the planes normal. lowest bit is z-component
* and highest is x.
*/

unsigned char bitMask=0;

if(n[0]<0.0f)
bitMask |= (unsigned char)4;
if(n[1]<0.0f)
bitMask |= (unsigned char)2;
if(n[2]<0.0f)
bitMask |= (unsigned char)1;

Vector3 vP(vertices[bitMask]);
Vector3 vN(vertices[(unsigned char)7-bitMask]);

float a=p.getDistance(vN);
if(a>0)
return OUTSIDE;
float b=p.getDistance(vP);
if(b>0)
return INTERSECT;

return INSIDE;
}

intersect_type AxisAlignedBox::classifyFrustum(const Plane3* p) const{
bool intersecting=false;

for(int i=0; i<6; i++){
intersect_type t=classifyPlane(p[i]);

if(OUTSIDE==t)
return t;
if(INTERSECT==t)
intersecting=true;
}

if(intersecting)
return INTERSECT;
else
return INSIDE;
}


There''s a paper explaining the technique: "Optimized View Frustum Culling Algorithms for Bounding Boxes" by Thomas Möller and Ulf Assarsson.

Share this post


Link to post
Share on other sites
Isn't a box outside the frustum IF and ONLY IF all its points are outside the SAME plane ?
Otherwise in many cases you may cull an object that IS inside the frustum.

(in that case, in rare cases you may select objects that are outside the frustum, but the graphic chip should get ride of that rather quickly. Better send something invisible rather than forget to send something visible)


-* So many things to do, so little time to spend. *-


[edited by - Ingenu on May 10, 2004 7:19:49 AM]

Share this post


Link to post
Share on other sites

  • Advertisement