Sign in to follow this  
STORM76

Transform AABB from local to world space for frustum-culling

Recommended Posts

STORM76    148
Hi there, I am working on a little scene-graph engine and want to facilitate frustum-culling for AABBs. Calculation of the view-frustum works fine as well as the calculation of the AABB for each model to render in its local coordinate space. Now in order to perform an intersection test of the model's AABB with the view frustum I need to transform the local AABB to world space. And there is my problem. When multiplying the two corners of the AABB with the transformation matrix (collected while visiting the scene-graph nodes (including rotation, scale and translation)) the results are unexpected. I also draw the AABB for debugging purposes. Is there a general method for performing frustum-culling of AABBs using a scene-graph? I am not sure if I do something essentially wrong. Thanks for any advice! Greetings, Guido

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Take a look here:
http://www.soe.ucsc.edu/~pang/160/f98/Gems/Gems/

and download "TransBox.c"

Share this post


Link to post
Share on other sites
dimebolt    440
If your method involves transforming all AABBs of the geometric objects to the scene root, you may want to consider reversing the problem and transform the frustum towards the end nodes instead. That will involve much less transformations.

Anyway, on the actual problem:
transforming the min and max vectors will not do what you want. A box has 8 corners and can only be simplified to two when it is axis aligned, while an arbitrary transformation on the box means that it is no longer axis aligned.

This code transforms a AABB into a new AABB:

/**
* apply a matrix to a box
* note that the resulting box will be axis aligned as well
* therefore the resulting box may be larger than the previous
*
* @param box the box to transform
* @param mat the trnsformation matrix to apply
**/

Box transform(const Box &box, const Matrix &mat)
{
float av, bv;
int i, j;
Box new_box(mat.m[12], mat.m[13], mat.m[14], mat.m[12], mat.m[13], mat.m[14]);
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
av = mat.element(i, j) * box.min[j];
bv = mat.element(i, j) * box.max[j];
if (av < bv)
{
new_box.min[i] += av;
new_box.max[i] += bv;
} else {
new_box.min[i] += bv;
new_box.max[i] += av;
}
}
return new_box;
};

where box.max and box.min are the two corner vectors of the AABB and matrix.m is the OpenGL style representation of a 4x4 matrix.








Tom

EDIT: which is indeed based upon the code from Graphics Gems pointed to by the AP who beat me :)

[Edited by - dimebolt on October 4, 2005 6:48:53 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this