Original Post
Hello, I needed an intersection test of the view frustum vs an axis aligned bounding box (AABB). Of course I could check all 8 box vertices against all 6 planes of the frustum, but I found a faster algorithm on this website, which uses a p-vertex and n-vertex: Link (section Geometric Approach - Testing Boxes II) To implement this algorithm I just used this code: I assume that this algorithm is correct. But this is the problem: The frustum is described by 6 planes, where each plane has an infinite extentsion in all 3 dimensions. The real frustum actually is not composed of planes, rather it is composed of 6 rectangles (each with a finite extension). So the problem that I have is that the algorithm doesnt check if the AABB intersects the finite frustum; it checks for intersections with the 6 infinite planes. (Because I don't know if I explained the problem quite well, I will give an example: Imagine you have a far plane of 1000 units and a box which goes from 900 to 1100 units on the z-axis. The x coordinates of the box are huge, so the box is placed at a huge distance on the right side of the frustum and does NOT intersect the real frustum. But the box DOES intersect the far plane, so the algorithm will deliver an intersection). My question: Is there a (relatively) simple way to modify this algorithm (or use an other algorithm) to get only the REAL intersections with the frustum (and not with the infinite planes)?
// Returns: INTERSECT : 0
// INSIDE : 1
// OUTSIDE : 2
int FrustumAABBIntersect(Plane *planes, Vector &mins, Vector &maxs) {
int ret = INSIDE;
Vector vmin, vmax;
for(int i = 0; i < 6; ++i) {
// X axis
if(planes.normal.x > 0) {
vmin.x = mins.x;
vmax.x = maxs.x;
} else {
vmin.x = maxs.x;
vmax.x = mins.x;
}
// Y axis
if(planes.normal.y > 0) {
vmin.y = mins.y;
vmax.y = maxs.y;
} else {
vmin.y = maxs.y;
vmax.y = mins.y;
}
// Z axis
if(planes.normal.z > 0) {
vmin.z = mins.z;
vmax.z = maxs.z;
} else {
vmin.z = maxs.z;
vmax.z = mins.z;
}
if(Vector::DotProduct(planes.normal, vmin) + planes.d > 0)
return OUTSIDE;
if(Vector::DotProduct(planes.normal, vmax) + planes.d >= 0)
ret = INTERSECT;
}
return ret;
}
