Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Apr 24th, 2005, 8: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
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 9:41 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC