Collision Handling

Sage
Posts: 1,066
Joined: 2004.07
Post: #16
Here's my attempt at cube to cube collision checking. It doesn't work at all right now. I know that my problem lies in this code because I have a backup of earlier code with everything but the actual checking (the code here) being the same. I'm not sure what the problem is. The code should be fairly easy to understand. The Get_() functions return a coordinate value (X,Y, or Z) or a dimension (Height,Width, and Depth). The variable object is a pointer. W is an integer value and LEFT, RIGHT, BOTTOM, TOP, FRONT, and BACK are all defined constants.

Code:
if ( ( GetX() + GetW() >= object->GetX() - object->GetW() ) &&
         ( GetX() - GetW() <= object->GetX() + object->GetW() ) &&
         ( GetY() + GetH() >= object->GetY() - object->GetH() ) &&
         ( GetY() - GetH() <= object->GetY() + object->GetH() ) &&
         ( GetZ() + GetD() >= object->GetZ() - object->GetD() ) &&
         ( GetZ() - GetD() <= object->GetZ() + object->GetD() ) )
    {    
        if ( GetX() < object->GetX() ) { w += LEFT; }
        if ( GetX() > object->GetX() ) { w += RIGHT; }
        if ( GetY() < object->GetY() ) { w += BOTTOM; }
        if ( GetY() > object->GetY() ) { w += TOP; }
        if ( GetZ() < object->GetZ() ) { w += BACK; }
        if ( GetZ() > object->GetZ() ) { w += FRONT; }
    }
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #17
SimReality/Nick Wrote:W is an integer value and LEFT, RIGHT, BOTTOM, TOP, FRONT, and BACK are all defined constants.
Er... what is W used for, and what are those directional constants defined as?

Perhaps you could explain what your collision detection is supposed to be doing. I'm having difficulty visualising how it works just from looking at the code. Wacko

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Member
Posts: 233
Joined: 2003.05
Post: #18
Is width (height, depth) the WHOLE width of the cube... or the distance from the center out?

"Pay no attention to that man behind the curtain." - Wizard of Oz
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #19
Sorry about the vague description. W is called later from the individual handling functions to tell them where the collision is taking place so that it can respond properly. For example if it finds w to be defined as LEFT, it can move the character to the left side of the object. The directional constants are defined as RIGHT = 1, LEFT = 5, TOP = 10, BOTTOM = 20, FRONT = 40, BACK = 80. The numbers are doubling so that there will never be a possibility of adding 2 or three of them (if the collision hits the front right, W = FRONT+RIGHT. if the collision hits the front, top, and right, W = FRONT+RIGHT+TOP). You cannot find a combination that adds up to other values.

The dimensions are from the center of the cube, not the whole width of the cube.

The current basic collision response is for types of CBuilding. I purposely set the left and right collisions to also take over all of the other cases because it caused trouble otherwise.

I actually have the collisions working for the top, bottom, left and right. The problem comes from the front and back.

Here's the whole code:
Code:
void CCharacter::CollideBuilding(CActiveObject *object, int w)
{
    switch (w)
    {
        case LEFT :;
        case (LEFT+BOTTOM) :;
        case (LEFT+FRONT) :;
        case (LEFT+BACK) :;
        case (LEFT+BOTTOM+FRONT) :;
        case (LEFT+BOTTOM+BACK) :
        {
            SetX(object->GetX()-object->GetW()-GetW());
            break;
        }
        case RIGHT :
        case (RIGHT+BOTTOM) :;
        case (RIGHT+FRONT) :;
        case (RIGHT+BACK) :;
        case (RIGHT+BOTTOM+FRONT) :;
        case (RIGHT+BOTTOM+BACK) :
        {
            SetX(object->GetX()+object->GetW()+GetW());
            break;
        }
        case TOP :;
        case (TOP+LEFT) :;
        case (TOP+RIGHT) :
        {
            SetDescent(0);
            SetY(object->GetY()+object->GetH()+GetH());
            break;
        }
        case BOTTOM :;
        {
            SetY(object->GetY()-object->GetH()-GetH());
            break;
        }
        case FRONT :;
        case (FRONT+TOP) :;
        case (FRONT+BOTTOM) :
        {
            SetZ(object->GetZ()+object->GetD()+GetD());
            break;
        }
        case BACK :;
        case (BACK+TOP) :;
        case (BACK+BOTTOM) :
        {
            SetZ(object->GetZ()-object->GetD()-GetD());
        }
    }
}

void CCharacter::CheckCollision(CActiveObject *object)
{
    
    int w = 0;
    
    if ( ( ( GetZ() + GetD() ) >= ( object->GetZ() - object->GetD() ) ) &&
         ( ( GetZ() - GetD() ) <= ( object->GetZ() + object->GetD() ) ) &&
         ( ( GetY() - GetH() ) >= ( object->GetY() - object->GetH() ) ) &&
         ( ( GetY() - GetH() ) <= ( object->GetY() + object->GetH() ) ) )
        
    {
        if ( ( ( GetX() + GetW() ) >= ( object->GetX() - object->GetW() ) ) &&
             ( ( GetX() - GetW() ) <= ( object->GetX() - object->GetW() ) ) ) { w += LEFT; }
        
        if ( ( ( GetX() - GetW() ) <= ( object->GetX() + object->GetW() ) ) &&
             ( ( GetX() + GetW() ) >= ( object->GetX() + object->GetW() ) ) ) { w += RIGHT; }
    }
    
    if ( ( ( GetZ() + GetD() ) >= ( object->GetZ() - object->GetD() ) ) &&
         ( ( GetZ() - GetD() ) <= ( object->GetZ() + object->GetD() ) ) &&
         ( ( GetX() + GetW() ) >= ( object->GetX() - object->GetW() ) ) &&
         ( ( GetX() - GetW() ) <= ( object->GetX() + object->GetW() ) ) )
    {
        if ( ( ( GetY() - GetH() ) <= ( object->GetY() + object->GetH() ) ) &&
             ( ( GetY() + GetH() ) >= ( object->GetY() + object->GetH() ) ) ) { w += TOP; }
        
        if ( ( ( GetY() + GetH() ) >= ( object->GetY() - object->GetH() ) ) &&
             ( ( GetY() - GetH() ) <= ( object->GetY() - object->GetH() ) ) ) { w += BOTTOM; }
    }
    
    if ( ( ( GetX() - GetW() ) >= ( object->GetX() - object->GetW() ) ) &&
         ( ( GetX() + GetW() ) <= ( object->GetX() + object->GetW() ) ) &&
         ( ( GetY() - GetH() ) >= ( object->GetY() - object->GetH() ) ) &&
         ( ( GetY() + GetH() ) <= ( object->GetY() + object->GetH() ) ) )
    {
        if ( ( ( GetZ() - GetD() ) <= ( object->GetZ() + object->GetD() ) ) &&
             ( ( GetZ() + GetD() ) >= ( object->GetZ() + object->GetD() ) ) ) { w += FRONT; }
        
        if ( ( ( GetZ() + GetD() ) <= ( object->GetZ() - object->GetD() ) ) &&
             ( ( GetZ() - GetD() ) >= ( object->GetZ() - object->GetD() ) ) ) { w += BACK; }
    }
    
    if ( w != 0 )
    {
        if ( object->GetType() == BUILDING_TYPE ) { CollideBuilding(object,w); }
    }
}

I apologize about the spacing. The if() statements all lined up nicely in Xcode making it easier to read.

Hope I cleared things up for my sake so I can get some help. Again, the only sides not working are the front and back. The are the last couple sets of if() statements.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Verlet integration - Collision Handling - C++ utdiscant 2 3,642 Dec 21, 2007 09:02 PM
Last Post: utdiscant
  What collision handling code to use Tasnu Arakun 5 3,217 Sep 25, 2004 08:59 AM
Last Post: FCCovett
  CB Key handling skyhawk 6 3,563 Aug 12, 2003 10:13 AM
Last Post: kelvin