Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool OrientedRectToOrientedRectEx(Transform2D * OBB1, Transform2D * OBB2, Contact * pResult)
- {
- //Extract Rotation and Inverse Rotation as a Matrix for OBB1
- Transform2D Temporal_Transform_OBB1 = *OBB1;
- Temporal_Transform_OBB1.mScale /= 2;
- Temporal_Transform_OBB1.mPosition = { 0, 0 };
- Matrix33 trans1 = Temporal_Transform_OBB1.GetMatrix();
- Matrix33 inv1 = Temporal_Transform_OBB1.GetInvMatrix();
- //Extract Rotation and Inverse Rotation as a Matrix for OBB2
- Transform2D Temporal_Transform_OBB2 = *OBB2;
- Temporal_Transform_OBB2.mScale /= 2;
- Temporal_Transform_OBB2.mPosition = { 0, 0 };
- Matrix33 trans2 = Temporal_Transform_OBB2.GetMatrix();
- Matrix33 inv2 = Temporal_Transform_OBB2.GetInvMatrix();
- //Compute D which is the vector from OBB1 to OBB2
- Vector2 D = OBB2->mPosition - OBB1->mPosition;
- //Compute the 4 axis of both OBB's
- Vector2 axis[] = { trans1.MultVec(Vector2(1, 0)), trans1.MultVec(Vector2(0, 1)), trans2.MultVec(Vector2(1, 0)), trans2.MultVec(Vector2(0, 1)) };
- //Arrays for containing the Projection of D in the 4 axis and the addition of the Length in T
- float projAxis[4]{};
- float T[4]{};
- for (int i = 0; i < 4; i++)
- {//For each Axis
- //Save the Projection in the array
- projAxis[i] = D.Project(axis[i]).Length();
- //Temporal for the actual axis
- Vector2 axis_ = axis[i];
- //Again For each Axix
- for (int j = 0; j < 4; j++)
- {
- //If it's the same axis
- if (i == j)
- T[i] += axis_.Length();
- //If the axis is different, we project it to the actual axis 'i' and save it's length
- else
- {
- T[i] += (axis[j].Project(axis_)).Length();
- }
- }
- }
- //Arrays for containing the overlap in each axis
- float overlap[4]{};
- for (int i = 0; i < 4; i++)
- {
- //Compute the overlap over the axis 'i'
- overlap[i] = T[i] - projAxis[i];
- //If the overlap is negative then it exist a Separating Axis Between OBB1 and OBB2, so there is no collision
- if (overlap[i] < 0)
- return false;
- }
- if (pResult)
- {//We search now the axis that have the minimum overlap
- //We declare a minoverlap that will store the length of the overlap and the minaxis will store the axis correspounding minimum overlap
- float minoverlap = overlap[0];
- Vector2 minaxis = axis[0];
- for (int i = 1; i < 4; i++)
- {
- //if the actual overlap is smaller than the saved one we overwrite the minoverlap and minaxis
- if (overlap[i] < minoverlap)
- {
- minoverlap = overlap[i];
- minaxis = axis[i];
- }
- }
- //Then the penetration is the minimum overlap we have found
- pResult->mPenetration = minoverlap;
- //Also the Normal is the axis that correspound to this minimum overlap
- pResult->mNormal = minaxis.Normalize();
- //As always we have to inverse the normal if the Dot product of the axis and the Vector from the OBB1 to the OBB2
- pResult->mNormal = pResult->mNormal.Dot(D) > 0 ? pResult->mNormal : -pResult->mNormal;
- //Now we need to search the Point of Impact
- //We compute first both position of the OBB's Roted back to the World
- Vector2 WorldOBB1Pos;
- WorldOBB1Pos.x = OBB1->mPosition.x * cos(-OBB1->mOrientation) - OBB1->mPosition.y * sin(-OBB1->mOrientation);
- WorldOBB1Pos.y = OBB1->mPosition.y * cos(-OBB1->mOrientation) + OBB1->mPosition.x * sin(-OBB1->mOrientation);
- Vector2 WorldOBB2Pos;
- WorldOBB2Pos.x = OBB2->mPosition.x * cos(-OBB2->mOrientation) - OBB2->mPosition.y * sin(-OBB2->mOrientation);
- WorldOBB2Pos.y = OBB2->mPosition.y * cos(-OBB2->mOrientation) + OBB2->mPosition.x * sin(-OBB2->mOrientation);
- //Temporal Value of the Scale for writting convinience
- Vector2 Scale1 = OBB1->mScale;
- //We create an Array of Vector2 that will store the position of the corners from the OBB1
- Vector2 corners1[4] = { { WorldOBB1Pos.x + Scale1.x / 2, WorldOBB1Pos.y + Scale1.y / 2 },
- { WorldOBB1Pos.x + Scale1.x / 2, WorldOBB1Pos.y - Scale1.y / 2 },
- { WorldOBB1Pos.x - Scale1.x / 2, WorldOBB1Pos.y + Scale1.y / 2 },
- { WorldOBB1Pos.x - Scale1.x / 2, WorldOBB1Pos.y - Scale1.y / 2 } };
- //Temporal Value of the Scale for writting convinience
- Vector2 Scale2 = OBB2->mScale;
- //We create an Array of Vector2 that will store the position of the corners from the OBB2
- Vector2 corners2[4] = { { WorldOBB2Pos.x + Scale2.x / 2, WorldOBB2Pos.y + Scale2.y / 2 },
- { WorldOBB2Pos.x + Scale2.x / 2, WorldOBB2Pos.y - Scale2.y / 2 },
- { WorldOBB2Pos.x - Scale2.x / 2, WorldOBB2Pos.y + Scale2.y / 2 },
- { WorldOBB2Pos.x - Scale2.x / 2, WorldOBB2Pos.y - Scale2.y / 2 } };
- //Now for each Corner in a OBB
- for (unsigned i = 0; i < 4; i++)
- {
- //We move back each corner to each OBB's World
- Vector2 result1;
- result1.x = corners1[i].x * cos(OBB1->mOrientation) - corners1[i].y * sin(OBB1->mOrientation);
- result1.y = corners1[i].y * cos(OBB1->mOrientation) + corners1[i].x * sin(OBB1->mOrientation);
- corners1[i] = result1;
- Vector2 result2;
- result2.x = corners2[i].x * cos(OBB2->mOrientation) - corners2[i].y * sin(OBB2->mOrientation);
- result2.y = corners2[i].y * cos(OBB2->mOrientation) + corners2[i].x * sin(OBB2->mOrientation);
- corners2[i] = result2;
- }
- //Again for each Corner in a OBB
- for (int i = 0; i < 4; i++)
- {
- //We look for the Point of Impact that is locate in one of the corners
- if ((minaxis.x == axis[0].x && minaxis.y == axis[0].y) || (minaxis.x == axis[1].x && minaxis.y == axis[1].y))
- {
- if (StaticPointToOrientedRect(&corners1[i], &Temporal_Transform_OBB2.GetInvMatrix().MultVec(OBB2->mPosition), OBB2->mScale.x, OBB2->mScale.y, OBB1->mOrientation - OBB2->mOrientation))
- {
- //Now as we find this closest point, we save it
- pResult->mPi = trans1.MultVec(corners1[i]);
- break;
- }
- }
- if ((minaxis.x == axis[2].x && minaxis.y == axis[2].y) || (minaxis.x == axis[3].x && minaxis.y == axis[3].y))
- {
- if (StaticPointToOrientedRect(&corners1[i], &Temporal_Transform_OBB2.GetInvMatrix().MultVec(OBB2->mPosition), OBB2->mScale.x, OBB2->mScale.y, OBB2->mOrientation - OBB1->mOrientation))
- {
- //Now as we find this closest point, we save it
- pResult->mPi = trans2.MultVec(corners2[i]);
- break;
- }
- }
- }
- }
- //Finally return...
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement