AABB collision (bounding boxes)

Started by
14 comments, last by BlackWind 19 years, 2 months ago
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?
Advertisement
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
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
nope, thats not the problem :S
// 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;
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;
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.....
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;}

Everything is better with Metal.

no, that doesnt works either.....
iam getting desperated.....
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.
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..........

This topic is closed to new replies.

Advertisement