Thread: Bounding Box Collision...not working

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071

    Question Bounding Box Collision...not working

    Iv'e attempted to add bounding box collision detection to my engine, and it compiles properly (which is farther than I got yesterday), but its not working. It calculates a bounding box for every object (3DS) loaded, and passes the min and max values to a struct array. The input functions then call a loop function when a key is pressed, that cycles through all the bounding boxes, and tests to see if the camera is inside them. If not, the camera can move, if so, don't move the camera. The problem: it dosn't recognize that the camera is in the bounding box for some reason.

    Heres some code to aid the explination:

    collision.cpp:
    Code:
    extern CCamera gCam;
    
    boundingbox boxP[MAX_OBJECTS];
    int num_boxes = 0;
    
    collision::collision()
    {
    }
    
    collision::~collision()
    {
    }
    
    char collision::createBbox(float cx, float cy, float cz,
    						   float minx, float miny, float minz,
    						   float maxx, float maxy, float maxz)
    {
    	boxP[num_boxes].min.x = minx+cx;
    	boxP[num_boxes].min.y = miny+cy;
    	boxP[num_boxes].min.z = minz+cz;
    
    	boxP[num_boxes].max.x = maxx+cx;
    	boxP[num_boxes].max.y = maxy+cy;
    	boxP[num_boxes].max.z = maxz+cz;
    
    	num_boxes++;
    	return (1);
    }
    
    bool collision::onBboxCollision(float x, float y, float z,
    							    float minx, float miny, float minz,
    							    float maxx, float maxy, float maxz)
    {
    	if (x > minx)
    		return false;
    	if (x < maxx)
    		return false;
    
    	if (y > miny)
    		return false;
    	if (y < maxy)
    		return false;
    
    	if (z> minz)
    		return false;
    	if (z < maxz)
    		return false;
    
    	return true;
    }
    
    int collision::loop(float x, float y, float z)
    {
    	for (int i = 0; i<num_boxes; i++)
    	{
    		if(onBboxCollision(x, y, z,
    						   boxP[i].min.x, boxP[i].min.y, boxP[i].min.z,
    						   boxP[i].max.x, boxP[i].max.y, boxP[i].max.z)==1)
    		{
    			return (i);
    		}
    	}
    	return (-1);
    }
    input.cpp (snippet):
    Code:
    void Input::CheckForInput(float speed)
    {
    	if(GetKeyState('W') & 0x80){ 
    		if(_peCollision->loop(gCam.m_vView.x, gCam.m_vView.y, gCam.m_vView.z)==!-1)exit(0);
    	else if(_peCollision->loop(gCam.m_vView.x, gCam.m_vView.y, gCam.m_vView.z)==-1)gCam.MoveCamera(speed);}
    	
    	if(GetKeyState('S') & 0x80){ if(_peCollision->loop(gCam.m_vPosition.x, gCam.m_vPosition.y, gCam.m_vPosition.z)==-1)gCam.MoveCamera(-speed); }
    	
    	if(GetKeyState('A') & 0x80){ /*if(_peCollision->loop()==1)*/gCam.StrafeCamera(-speed); }
    	
    	if(GetKeyState('D') & 0x80){ /*if(_peCollision->loop()==1)*/gCam.StrafeCamera(speed); }
    	
    	
    	
    	if(GetKeyState('O') &0x80){ ShowCursor(false); }
    
    	if(GetKeyState('P') &0x80){	ShowCursor(true); }
    }
    Please help if you can. Let me know if I didn't give enough information.

    thanx,
    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  2. #2
    Registered User
    Join Date
    May 2005
    Location
    Sweden
    Posts
    16
    I have only looked at your code briefly, but I think you use the wrong operator for comparison (assuming I read the code correctly).

    Assuming maxx - minx describes the length of the box on the x-axis, then the camera is outisde the box if it's x-coordinate is less than minx or greater than maxx. You return false if the x-coord is larger than minx or smaller than maxx, which would suggest it might just lie inside the box. Same with the other axes.

    Another thing I noticed, you have an if statement that looks something like this:
    Code:
    if(/*stuff*/ == !-1)
    As !-1 == 0, what you probably want is:
    Code:
    if(/*stuff*/ != -1)
    Also, some things you might want to remember:
    Code:
    // This...
    if(foo() != -1)
       do_stuff();
    
    if(foo() == -1)
       do_other_stuff();
    
    // ...yields the same results as this (as long as 'foo' doesn't rely on anything but the arguments when returning a value)
    if(foo() != -1)
       do_stuff();
    
    else
       do_other_stuff();
    
    // This...
    if(foo() == 1)
       stuff1();
    else if(foo() == 2)
       stuff2();
    else
       stuff3();
    
    // ...is the same as:
    int f = foo();
    if(f == 1)
       stuff1();
    else if(f == 2)
       stuff2();
    else
       stuff3();
    These two examples are especially important to remember if 'foo' is an expensive call or if the code is located in the inner loop of a critical section.

  3. #3
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Iv'e made some changes, and now, instead of not colliding, it thinks i'm always colliding!?

    heres the modified code:
    Code:
    bool collision::onBboxCollision(float x, float y, float z,
    							    float minx, float miny, float minz,
    							    float maxx, float maxy, float maxz)
    {
    	if (x > minx | x < maxx|
    		y > miny | y < maxy|
    		z > minz | z < maxz)
    		return true; //we collided
    	else
    		return false; //we didn't
    }
    
    int collision::loop(float x, float y, float z)
    {
    	for (int i = 0; i<num_boxes; i++)
    	{
    		if(onBboxCollision(x, y, z,
    						   boxP[i].min.x, boxP[i].min.y, boxP[i].min.z,
    						   boxP[i].max.x, boxP[i].max.y, boxP[i].max.z))
    		{
    			return (i); //we collided
    		}
    		else
    			return (-1); //we didn't
    	}
    }
    Code:
    void Input::CheckForInput(float speed)
    {
    	if(GetKeyState('W') & 0x80)
    	{ 
    		if(_peCollision->loop(gCam.m_vView.x, gCam.m_vView.y, gCam.m_vView.z)>=0)
    			exit (0);
    		else 
    			gCam.MoveCamera(speed);
    	}
    	
    	if(GetKeyState('S') & 0x80){ if(_peCollision->loop(gCam.m_vPosition.x, gCam.m_vPosition.y, gCam.m_vPosition.z)==-1)gCam.MoveCamera(-speed); }
    	
    	if(GetKeyState('A') & 0x80){ /*if(_peCollision->loop()==1)*/gCam.StrafeCamera(-speed); }
    	
    	if(GetKeyState('D') & 0x80){ /*if(_peCollision->loop()==1)*/gCam.StrafeCamera(speed); }
    	
    	
    	
    	if(GetKeyState('O') &0x80){ ShowCursor(false); }
    
    	if(GetKeyState('P') &0x80){	ShowCursor(true); }
    }
    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Code:
    bool collision::onBboxCollision(float x, float y, float z,
    							 float minx, float miny, float minz,
    							 float maxx, float maxy, float maxz)
    {
    	if (x > minx | x < maxx|
    		y > miny | y < maxy|
    		z > minz | z < maxz)
    		return true; //we collided
    	else
    		return false; //we didn't
    }
    Remember you want to use logical operators and not bitwise operators in this case. Also, you want to use AND not OR logical operator ( && instead of || ).

    So your code may look something like:

    Code:
    bool collision::onBboxCollision(float x, float y, float z,
    							 float minx, float miny, float minz,
    							 float maxx, float maxy, float maxz)
    {
      if (x > minx && x < maxx &&
           y > miny && y < maxy &&
           z > minz && z < maxz)
         return true; //we collided
       else
         return false; //we didn't
    }
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  5. #5
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Ok, thanx. Iv'e gotten it to work somewhat, but the calculation of the bounding box objects needs to be fixed, but I think I can handle that on my own.

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 01-18-2008, 04:06 AM
  2. Parent of a BrowseForFolder dialog box
    By @nthony in forum Windows Programming
    Replies: 4
    Last Post: 01-08-2007, 02:54 PM
  3. fgets() to list box
    By tao in forum Windows Programming
    Replies: 4
    Last Post: 06-08-2006, 08:23 AM
  4. New Theme
    By XSquared in forum A Brief History of Cprogramming.com
    Replies: 160
    Last Post: 04-01-2004, 08:00 PM
  5. collision detection
    By DavidP in forum Game Programming
    Replies: 2
    Last Post: 05-11-2002, 01:31 PM