View Single Post
Old Apr 24th, 2005, 7:08 AM   #1
xennon
Newbie
 
Join Date: Apr 2005
Posts: 1
Rep Power: 0 xennon is on a distinguished road
Separating Axis Test. Desperate for help

Hey :-)

Basically, i'm at the end of my tether while trying to get this thing to work. I've tried everything I can think of, and I just can't get it to work. I understand what the test does, and how it works, but when coding it, it just won't do what I want. I can get it to test correctly if two boxes are axis aligned, but as soon as they are oriented, it won't work.

I will follow with my code

This is where the OBB is updated. Its extent and edge vectors are set.

void drawBox()
     {          
          glPushMatrix();     

          glColor3f(1.0,1.0,1.0);
          
          center.x = center.x + dMove*cos(PI/2+turn1*PI/180.0);
          center.y = center.y + dMove*sin(PI/2+turn1*PI/180.0);     
     
          glTranslatef(center.x, center.y, center.z);
          glRotatef(turn1,0.0,0.0,1.0);
          glRotatef(turn2,0.0,1.0,0.0);
          
          //Rotation Vector
          Vec3d temp;
          temp.Set(0, turn2, turn1);

          //Sets extremity vector and edge vectors
          extrem.Set(center.x+width/2, center.y+height/2, center.z+depth/2);
          edgeX.Set(center.x+width/2, center.y, center.z);
          edgeY.Set(center.x, center.y+height/2, center.z);
          edgeZ.Set(center.x, center.y, center.z+depth/2);

          //Rotates those vectors with the box
          extrem.Rotate(center.xyz,temp); 
          edgeX.Rotate(center.xyz,temp);
          edgeY.Rotate(center.xyz,temp);
          edgeZ.Rotate(center.xyz,temp);
          glScalef(width, height, depth);
          glutWireCube(1);
     
          glPopMatrix();     
     }

This is where the test is performed. Anything with 'this' is the local box (BOX A) and anything with 'box' is the passed in box (BOX B).
bool checkCollision(OBB *box)
     {
          Vec3d     CA;  
          Vec3d     CB;  
          Vec3d     L;
          Vec3d centerB, Labs;
          
          //Extent Vectors of Boxes relative to their local axis
          CA.Set(this->extrem-this->center);
          CB.Set(box->extrem-box->center);
          
          centerB.Set(box->center-this->center);

          for (int i = 0; i < 3; ++i)
          {
               //The 3 edge vectors of the box A (anything with 'this' is box A)
               if(i == 0)
               {
                    L.Set(this->edgeX-this->center);
               }
               else if( i == 1)
               {
                    L.Set(this->edgeY-this->center);
               }
               else if(i == 2)
               {
                    L.Set(this->edgeZ-this->center);
               }     
               
               L.Normalize();

               //|L|
               Labs.Set(fabs(L.x), fabs(L.y), fabs(L.z));

               float min1 = L.Dot(this->center-this->center) - Labs.Dot(CA);
               float max1 = L.Dot(this->center-this->center) + Labs.Dot(CA);
               float min2 = L.Dot(centerB) - Labs.Dot(CB);
               float max2 = L.Dot(centerB) + Labs.Dot(CB);

               float d0 = min1 - max2;
               float d1 = min2 - max1;    
          
               if(d0>0 || d1>0)
               {
                    return false;
               }
          
               //Edge vectors of box B (anything with 'box->' is box B)
               if(i == 0)
               {
                    L.Set((box->edgeX-box->center+centerB));
               }
               else if( i == 1)
               {
                    L.Set((box->edgeY-box->center+centerB));
               }
               else if(i == 2)
               {
                    L.Set((box->edgeZ-box->center+centerB));
               }          
          
               L.Normalize();
               Labs.Set(fabs(L.x), fabs(L.y), fabs(L.z));
               min1 = L.Dot(this->center-this->center) - Labs.Dot(CA);
               max1 = L.Dot(this->center-this->center) + Labs.Dot(CA);
               min2 = L.Dot(centerB) - Labs.Dot(CB);
               max2 = L.Dot(centerB) + Labs.Dot(CB);

               d0 = min1 - max2;
               d1 = min2 - max1;    

               if(d0>0 || d1>0)
               {
                    return false;
               }          
          }
     
          // and now for the cross product axes
          for (int i = 0; i < 3; ++i)
          {
               if(i == 0)
               {
                    L.Set(this->edgeX-this->center);
               }
               else if( i == 1)
               {
                    L.Set(this->edgeY-this->center);
               }
               else if(i == 2)
               {
                    L.Set(this->edgeZ-this->center);
               }

               for (int j = 0; j < 3; ++j)
               {
                    Vec3d temp3;
                    if(j == 0)
                    {                    
                         temp3.Set((box->edgeX-box->center+centerB));
                         L.Set(L.Cross(temp3));
                    }
                    else if( j == 1)
                    {
                         temp3.Set((box->edgeY-box->center+centerB));
                         L.Set(L.Cross(temp3));
                    }
                    else if(j == 2)
                    {
                         temp3.Set((box->edgeZ-box->center+centerB));
                         L.Set(L.Cross(temp3));
                    }

                    L.Normalize();
                    Labs.Set(fabs(L.x), fabs(L.y), fabs(L.z));
                    float min1 = L.Dot(this->center-this->center) - Labs.Dot(CA);
                    float max1 = L.Dot(this->center-this->center) + Labs.Dot(CA);
                    float min2 = L.Dot(centerB) - Labs.Dot(CB);
                    float max2 = L.Dot(centerB) + Labs.Dot(CB);

                    float d0 = min1 - max2;
                    float d1 = min2 - max1;    

                    if(d0>0 || d1>0)
                    {
                         return false;
                    }                    
               }
          }     

          return true;
          }

Now, I know this may sound annoying or whatever, but I don't want references or anything to websites or vague descriptions of how the test works, because I have checked every website I can find, and spent hours trying lots of different things to get this test to work. I have Van Den Bergens 'Collision detection in interactive 3d environments' which is where I got the theory from, and I think I understand it.

I really just need help with this code and getting it to work. PLEASE, i'm seriously desperate :-)
xennon is offline   Reply With Quote