I have a problem.
When im rendering my objects, i first cull them by comparing the view frustum to their axis aligned bounding box. The problem is, that sometimes, when the camera is really close, objects can "pop" away. Ie they are beeing culled when they should not. This only happens when the camera is really close, and most often below the camera, on the bottom plane i think (not sure).
See screenshot:
http://hem.passagen.se/storage/culling_bug.jpg
I think this may be because my plane_to_aabb() intersection function must contain a bug.
Could anyone take a look at it for me?
Thanks in advance.
enum plane_intersection_t
{
PLANE_INTERSECTION_BACK,
PLANE_INTERSECTION_FRONT,
PLANE_INTERSECTION_INTERSECT
};
//////////////////////////////////////////////////////////////////////////
plane_intersection_t intersect(const plane3_t* plane, const aab3_t* box)
{
vector3_t min_point;
vector3_t max_point;
if (plane->m_normal.x > 0.0f)
{
min_point.x = (float)box->m_min.x;
max_point.x = (float)box->m_max.x;
}
else
{
min_point.x = (float)box->m_max.x;
max_point.x = (float)box->m_min.x;
}
if (plane->m_normal.y > 0.0f)
{
min_point.y = (float)box->m_min.y;
max_point.y = (float)box->m_max.y;
}
else
{
min_point.y = (float)box->m_max.y;
max_point.y = (float)box->m_min.y;
}
if (plane->m_normal.z > 0.0f)
{
min_point.z = (float)box->m_min.z;
max_point.z = (float)box->m_max.z;
}
else
{
min_point.z = (float)box->m_max.z;
max_point.z = (float)box->m_min.z;
}
float min_distance = plane3_signed_distance(plane, &min_point);
float max_distance = plane3_signed_distance(plane, &max_point);
if (min_distance * max_distance < 0.0f)
return PLANE_INTERSECTION_INTERSECT;
else if (min_distance >= 0.0f)
return PLANE_INTERSECTION_FRONT;
return PLANE_INTERSECTION_BACK;
}
// the frustum intersection function, tought id add it, but i dont think there could be anything wrong here, since its so simple.
//////////////////////////////////////////////////////////////////////////
bool intersect(const aab3_t* a, const frustum3_t* f)
{
plane_intersection_t left = intersect(&f->m_left, a);
plane_intersection_t right = intersect(&f->m_right, a);
plane_intersection_t top = intersect(&f->m_top, a);
plane_intersection_t bottom = intersect(&f->m_bottom, a);
plane_intersection_t near = intersect(&f->m_near, a);
plane_intersection_t far = intersect(&f->m_far, a);
if((left == PLANE_INTERSECTION_BACK)
|| (right == PLANE_INTERSECTION_BACK)
|| (top == PLANE_INTERSECTION_BACK)
|| (bottom == PLANE_INTERSECTION_BACK)
|| (near == PLANE_INTERSECTION_BACK)
|| (far == PLANE_INTERSECTION_BACK))
return false;
return true;
}