Transform AABB from local to world space for frustum-culling

Started by
2 comments, last by STORM76 18 years, 6 months ago
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
Greetings,STORM!
Advertisement
Take a look here:
http://www.soe.ucsc.edu/~pang/160/f98/Gems/Gems/

and download "TransBox.c"
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 += av;				new_box.max += bv;			} else {				new_box.min += bv;				new_box.max += 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]
Thank you all very much!

I will add this method to my engine this evening:-)

Greetings,
Guido
Greetings,STORM!

This topic is closed to new replies.

Advertisement