Advertisement
Guest User

OBB vs OBB

a guest
Mar 23rd, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.13 KB | None | 0 0
  1. bool OrientedRectToOrientedRectEx(Transform2D * OBB1, Transform2D * OBB2, Contact * pResult)
  2. {
  3.     //Extract Rotation and Inverse Rotation as a Matrix for OBB1
  4.     Transform2D Temporal_Transform_OBB1 = *OBB1;
  5.     Temporal_Transform_OBB1.mScale /= 2;
  6.     Temporal_Transform_OBB1.mPosition = { 0, 0 };
  7.     Matrix33 trans1 = Temporal_Transform_OBB1.GetMatrix();
  8.     Matrix33 inv1 = Temporal_Transform_OBB1.GetInvMatrix();
  9.  
  10.     //Extract Rotation and Inverse Rotation as a Matrix for OBB2
  11.     Transform2D Temporal_Transform_OBB2 = *OBB2;
  12.     Temporal_Transform_OBB2.mScale /= 2;
  13.     Temporal_Transform_OBB2.mPosition = { 0, 0 };
  14.     Matrix33 trans2 = Temporal_Transform_OBB2.GetMatrix();
  15.     Matrix33 inv2 = Temporal_Transform_OBB2.GetInvMatrix();
  16.  
  17.     //Compute D which is the vector from OBB1 to OBB2
  18.     Vector2 D = OBB2->mPosition - OBB1->mPosition;
  19.  
  20.     //Compute the 4 axis of both OBB's
  21.     Vector2 axis[] = { trans1.MultVec(Vector2(1, 0)), trans1.MultVec(Vector2(0, 1)), trans2.MultVec(Vector2(1, 0)), trans2.MultVec(Vector2(0, 1)) };
  22.  
  23.     //Arrays for containing the Projection of D in the 4 axis and the addition of the Length in T
  24.     float projAxis[4]{};
  25.     float T[4]{};
  26.  
  27.     for (int i = 0; i < 4; i++)
  28.     {//For each Axis
  29.  
  30.         //Save the Projection in the array
  31.         projAxis[i] = D.Project(axis[i]).Length();
  32.         //Temporal for the actual axis
  33.         Vector2 axis_ = axis[i];
  34.         //Again For each Axix
  35.         for (int j = 0; j < 4; j++)
  36.         {
  37.             //If it's the same axis
  38.             if (i == j)
  39.                 T[i] += axis_.Length();
  40.            
  41.             //If the axis is different, we project it to the actual axis 'i' and save it's length
  42.             else
  43.             {
  44.                 T[i] += (axis[j].Project(axis_)).Length();
  45.             }
  46.         }
  47.     }
  48.  
  49.     //Arrays for containing the overlap in each axis
  50.     float overlap[4]{};
  51.  
  52.     for (int i = 0; i < 4; i++)
  53.     {
  54.         //Compute the overlap over the axis 'i'
  55.         overlap[i] = T[i] - projAxis[i];
  56.  
  57.         //If the overlap is negative then it exist a Separating Axis Between OBB1 and OBB2, so there is no collision
  58.         if (overlap[i] < 0)
  59.             return false;
  60.     }
  61.     if (pResult)
  62.     {//We search now the axis that have the minimum overlap
  63.     //We declare a minoverlap that will store the length of the overlap and the minaxis will store the axis correspounding minimum overlap
  64.         float minoverlap = overlap[0];
  65.         Vector2 minaxis = axis[0];
  66.  
  67.         for (int i = 1; i < 4; i++)
  68.         {
  69.             //if the actual overlap is smaller than the saved one we overwrite the minoverlap and minaxis
  70.             if (overlap[i] < minoverlap)
  71.             {
  72.                 minoverlap = overlap[i];
  73.                 minaxis = axis[i];
  74.             }
  75.         }
  76.         //Then the penetration is the minimum overlap we have found
  77.         pResult->mPenetration = minoverlap;
  78.  
  79.         //Also the Normal is the axis that correspound to this minimum overlap
  80.         pResult->mNormal = minaxis.Normalize();
  81.  
  82.         //As always we have to inverse the normal if the Dot product of the axis and the Vector from the OBB1 to the OBB2
  83.         pResult->mNormal = pResult->mNormal.Dot(D) > 0 ? pResult->mNormal : -pResult->mNormal;
  84.  
  85.         //Now we need to search the Point of Impact
  86.         //We compute first both position of the OBB's Roted back to the World
  87.         Vector2 WorldOBB1Pos;
  88.         WorldOBB1Pos.x = OBB1->mPosition.x * cos(-OBB1->mOrientation) - OBB1->mPosition.y * sin(-OBB1->mOrientation);
  89.         WorldOBB1Pos.y = OBB1->mPosition.y * cos(-OBB1->mOrientation) + OBB1->mPosition.x * sin(-OBB1->mOrientation);
  90.         Vector2 WorldOBB2Pos;
  91.         WorldOBB2Pos.x = OBB2->mPosition.x * cos(-OBB2->mOrientation) - OBB2->mPosition.y * sin(-OBB2->mOrientation);
  92.         WorldOBB2Pos.y = OBB2->mPosition.y * cos(-OBB2->mOrientation) + OBB2->mPosition.x * sin(-OBB2->mOrientation);
  93.  
  94.         //Temporal Value of the Scale for writting convinience
  95.         Vector2 Scale1 = OBB1->mScale;
  96.  
  97.         //We create an Array of Vector2 that will store the position of the corners from the OBB1
  98.         Vector2 corners1[4] = { { WorldOBB1Pos.x + Scale1.x / 2, WorldOBB1Pos.y + Scale1.y / 2 },
  99.         { WorldOBB1Pos.x + Scale1.x / 2, WorldOBB1Pos.y - Scale1.y / 2 },
  100.         { WorldOBB1Pos.x - Scale1.x / 2, WorldOBB1Pos.y + Scale1.y / 2 },
  101.         { WorldOBB1Pos.x - Scale1.x / 2, WorldOBB1Pos.y - Scale1.y / 2 } };
  102.  
  103.         //Temporal Value of the Scale for writting convinience
  104.         Vector2 Scale2 = OBB2->mScale;
  105.  
  106.         //We create an Array of Vector2 that will store the position of the corners from the OBB2
  107.         Vector2 corners2[4] = { { WorldOBB2Pos.x + Scale2.x / 2, WorldOBB2Pos.y + Scale2.y / 2 },
  108.         { WorldOBB2Pos.x + Scale2.x / 2, WorldOBB2Pos.y - Scale2.y / 2 },
  109.         { WorldOBB2Pos.x - Scale2.x / 2, WorldOBB2Pos.y + Scale2.y / 2 },
  110.         { WorldOBB2Pos.x - Scale2.x / 2, WorldOBB2Pos.y - Scale2.y / 2 } };
  111.  
  112.         //Now for each Corner in a OBB
  113.         for (unsigned i = 0; i < 4; i++)
  114.         {
  115.             //We move back each corner to each OBB's World
  116.  
  117.             Vector2 result1;
  118.             result1.x = corners1[i].x * cos(OBB1->mOrientation) - corners1[i].y * sin(OBB1->mOrientation);
  119.             result1.y = corners1[i].y * cos(OBB1->mOrientation) + corners1[i].x * sin(OBB1->mOrientation);
  120.             corners1[i] = result1;
  121.  
  122.             Vector2 result2;
  123.             result2.x = corners2[i].x * cos(OBB2->mOrientation) - corners2[i].y * sin(OBB2->mOrientation);
  124.             result2.y = corners2[i].y * cos(OBB2->mOrientation) + corners2[i].x * sin(OBB2->mOrientation);
  125.             corners2[i] = result2;
  126.         }
  127.  
  128.         //Again for each Corner in a OBB
  129.         for (int i = 0; i < 4; i++)
  130.         {
  131.             //We look for the Point of Impact that is locate in one of the corners
  132.  
  133.             if ((minaxis.x == axis[0].x && minaxis.y == axis[0].y) || (minaxis.x == axis[1].x && minaxis.y == axis[1].y))
  134.             {
  135.                 if (StaticPointToOrientedRect(&corners1[i], &Temporal_Transform_OBB2.GetInvMatrix().MultVec(OBB2->mPosition), OBB2->mScale.x, OBB2->mScale.y, OBB1->mOrientation - OBB2->mOrientation))
  136.                 {
  137.                     //Now as we find this closest point, we save it
  138.                     pResult->mPi = trans1.MultVec(corners1[i]);
  139.                     break;
  140.                 }
  141.             }
  142.  
  143.             if ((minaxis.x == axis[2].x && minaxis.y == axis[2].y) || (minaxis.x == axis[3].x && minaxis.y == axis[3].y))
  144.             {
  145.                 if (StaticPointToOrientedRect(&corners1[i], &Temporal_Transform_OBB2.GetInvMatrix().MultVec(OBB2->mPosition), OBB2->mScale.x, OBB2->mScale.y, OBB2->mOrientation - OBB1->mOrientation))
  146.  
  147.                 {
  148.                     //Now as we find this closest point, we save it
  149.                     pResult->mPi = trans2.MultVec(corners2[i]);
  150.                     break;
  151.                 }
  152.             }
  153.         }
  154.     }
  155.     //Finally return...
  156.     return true;
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement