Sign in to follow this  

AABB collision (bounding boxes)

This topic is 4687 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

hi, i am having troubles on detecting an AABB collision. my bounding box is a cube with mins and max. here is the code where i draw the cube:
void CPaint::DrawCube(BBox bbox, float size)
{

	
	bbox.Min.x = bbox.Max.x - size;
	bbox.Min.y = bbox.Max.y - size;
	bbox.Max.z = bbox.Min.z - size;

	// clear the code a bit
	CVector bmax = bbox.Max;
	CVector bmin = bbox.Min;

	
	//glColor3ub ( 255,128, 98);
	//front
	glBegin( GL_QUADS );
		glVertex3f ( bmin.x , bmin.y, bmin.z );
		glVertex3f ( bmax.x , bmin.y, bmin.z );
		glVertex3f ( bmax.x , bmax.y, bmin.z );
		glVertex3f ( bmin.x , bmax.y, bmin.z );
	glEnd ();

	// back
	glBegin( GL_QUADS );
		glVertex3f ( bmin.x , bmin.y, bmax.z );
		glVertex3f ( bmax.x , bmin.y, bmax.z );
		glVertex3f ( bmax.x , bmax.y, bmax.z );
		glVertex3f ( bmin.x , bmax.y, bmax.z );
	glEnd ();

	// up
	glBegin( GL_QUADS );
		glVertex3f ( bmin.x , bmax.y, bmax.z );
		glVertex3f ( bmax.x , bmax.y, bmax.z );
		glVertex3f ( bmax.x , bmax.y, bmin.z );
		glVertex3f ( bmin.x , bmax.y, bmin.z );
	glEnd ();

	// down
	glBegin( GL_QUADS );
		glVertex3f ( bmin.x , bmin.y, bmax.z );
		glVertex3f ( bmax.x , bmin.y, bmax.z );
		glVertex3f ( bmax.x , bmin.y, bmin.z );
		glVertex3f ( bmin.x , bmin.y, bmin.z );
	glEnd ();

	// left side
	glBegin( GL_QUADS );
		glVertex3f ( bmin.x , bmin.y, bmax.z );
		glVertex3f ( bmin.x , bmax.y, bmax.z );
		glVertex3f ( bmin.x , bmax.y, bmin.z );
		glVertex3f ( bmin.x , bmin.y, bmin.z );
	glEnd ();

	// rigth side
	glBegin( GL_QUADS );
		glVertex3f ( bmax.x , bmin.y, bmax.z );
		glVertex3f ( bmax.x , bmax.y, bmax.z );
		glVertex3f ( bmax.x , bmax.y, bmin.z );
		glVertex3f ( bmax.x , bmin.y, bmin.z );
	glEnd ();
}

here is how i init the cube and what does the BBox is
void CPaint::InitCube(BBox bbox[])
{
	
	bbox[0].Max.x = 1;	
	bbox[0].Max.y = 1;
	bbox[0].Min.z = 1;

	bbox[1].Max.x = 5;	
	bbox[1].Max.y = 2;
	bbox[1].Min.z = 5;
	
}

struct BBox
{
	CVector Min;
	CVector Max;
};

with all that code i have no problem, i can move the cube only changing the Max.x , Max.y and Min.z and can draw as many cubes as i want. (static or dinamic). the real problem is where i try to check if 2 AABB collide. this is the code:
bool CPaint::BboxCollision( BBox box1, BBox box2 )
{
	
	if( box1.Min.x > box2.Max.x ) return false;
	if( box1.Max.x < box2.Min.x ) return false;
	if( box1.Max.z > box2.Min.z ) return false;
	if( box1.Min.z < box2.Max.z ) return false;
		
	
	else
		return true;
}
since i only move them in Z or X, i didnt put the Y. but that doesnt works..... it says that it is colliding when it doesnt.... what am i doing wrong?

Share this post


Link to post
Share on other sites
your not testing along the y axis

EDIT: well for correctness' sake put it in there anyways


box1.Max.z > box2.Min.z

should be

box1.Max.z < box2.Min.z


same with this line:
box1.Min.z < box2.Max.z

hope that helps
-Dan

Share this post


Link to post
Share on other sites
// x slice is correct:

if( box1.Min.x > box2.Max.x ) return false;
if( box1.Max.x < box2.Min.x ) return false;

//This should be like above, instead of:
if( box1.Max.z > box2.Min.z ) return false;
if( box1.Min.z < box2.Max.z ) return false;


if( box1.Min.z > box2.Max.z ) return false;
if( box1.Max.z < box2.Min.z ) return false;

Share this post


Link to post
Share on other sites
Hi,
(Doh took too long to write the reply and was beaten to it)

As Dan said these two lines ARE the problem

if( box1.Max.z > box2.Min.z ) return false;
if( box1.Min.z < box2.Max.z ) return false;

The false test is to test the min of one box against its respective max of the other. That is if the min > max or (max < min) they cannot overlap. Checking if the max of one box is more than the minimum of another doesn't tell you anything, as the min of the first box could overlap the max of second.

Juts compare those lines with the first two you wrote, they are correct, but you've switched the comparrsions on the second two.

So it should be

if( box1.Min.x > box2.Max.x ) return false;
if( box1.Max.x < box2.Min.x ) return false;
if( box1.Max.z < box2.Min.z ) return false;
if( box1.Min.z > box2.Max.z ) return false;

Share this post


Link to post
Share on other sites
thats how i have the code, but it isnt working.
i have no idea what is going wrong
maybe if i put some more of my code can help

this is what i do in my "renderscene"

// draw NON static cube
glPushMatrix();
glTranslatef( bbox[0].Max.x, bbox[0].Max.y, bbox[0].Min.z);
g_Paint.DrawCube(bbox[0] , 1.0f);
glPopMatrix();

// draw static box
glPushMatrix();
if( g_Paint.BboxCollision( bbox[0], bbox[1] ) )
glColor3ub ( 255, 0, 0);
else
glColor3ub ( 10, 233, 93);
g_Paint.DrawCube(bbox[1], 1.0f);
glPopMatrix();



and this how i move the cube in a method called "keypressed" (i am using allegro)

// move the cube
if ( key[KEY_D] )
bbox[0].Max.x += 0.1;

if ( key[KEY_A] )
bbox[0].Max.x -= 0.1;

if ( key[KEY_W] )
bbox[0].Min.z -= 0.1;

if ( key[KEY_S] )
bbox[0].Min.z += 0.1;



hope with this i can be helped.....

Share this post


Link to post
Share on other sites
I'll have a shot

bool CPaint::BboxCollision( BBox box1, BBox box2 )
{
if( box1.Min.x > box2.Max.x ) return false;
if( box1.Max.x < box2.Min.x ) return false;
if( box1.Min.z > box2.Max.z ) return false;
if( box1.Max.z < box2.Min.z ) return false;

return true;
}

Share this post


Link to post
Share on other sites
Glancing over your code, I see one possible problem. The min and max variables for each box represent its actual position in world space, and you appear to be using these coordinates to render them. Therefore no translation is necessary, i.e. you shouldn't be calling glPushMatrix() or glTranslate(). If you are in fact translating them before rendering, their visual positions won't match their actual world positions, and your collision results will appear to be incorrect.

Based on your code I'm not positive that that's the problem, but it might be worth looking into.

Share this post


Link to post
Share on other sites
yeah, i just checked that i few minutes ago and i deleted that part (it was for no use)
and i changed for this:


// draw static cube
g_Paint.DrawCube(bbox[1], 1.0f);


// draw Non static cube

if( g_Paint.BboxCollision( bbox[0], bbox[1] ) == true )
glColor3ub ( 0, 255, 0);
else
glColor3ub ( 0, 0, 255);
g_Paint.DrawCube(bbox[0] , 1.0f);




but it still has the same problem.....
i dont know what could the problem be..........

Share this post


Link to post
Share on other sites
Hm. The way you're moving your boxes and resetting the min/max looks a little suspect. How about something like this.

Vector3 delta(0, 0);
if (keyleft) delta.x = -speed;
else if (keyright) delta.x = speed;
if (keyup) delta.z = -speed;
else if (keydown) delta.z = speed;

min += delta;
max += delta;

This way, when you called your collision and rendering functions, you would be sure that min and max matched what was on the screen.

Anyway, I think you've just got something turned around somewhere. Intersection between two AABBs is straightforward and the solution to that has been posted. So, I think there must be some discrepency between what you're seeing on the screen and where your boxes actually are.

Share this post


Link to post
Share on other sites
this is delphi code, i believe you won't have any troubles translating it into language of your choice:


function overlap(const La, Ra, Lb, Rb: decimal): boolean;
begin
result:= (Ra > Lb) and (La < Rb);
end;

function TestAABB(const A, B: Taabb): boolean;
begin
Result:= overlap(a.left, a.right, b.left, b.right) and
overlap(a.top, a.bottom, b.top, b.bottom);
end;



and this one works.

Share this post


Link to post
Share on other sites
i assume the default returnig is true, but i dont understand this:

overlap(a.left, a.right, b.left, b.right) and
overlap(a.top, a.bottom, b.top, b.bottom);

a is the Box1 and b the Box2......but what is left, right top and bottom?
max.x , min.x, max.y and min.y¿

Share this post


Link to post
Share on other sites

This topic is 4687 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.

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