DEV Community

Jalil Habri
Jalil Habri

Posted on

How to correctly rotate an OBB ?

Hello everyone, I made, with OpenGL, a car simulator. For the car collision box, I used an OBB.The problem is when i wanna rotate the collision box. for this, I use this function :

std::vector<glm::vec3> rotateCollisionBox(float angle, glm::vec3 boxMin, glm::vec3 boxMax) { std::vector<glm::vec3> rotatedVertices; glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0, 1.0, 0.0)); std::vector<glm::vec3> corners = { glm::vec3(boxMin.x, boxMin.y, boxMin.z), glm::vec3(boxMax.x, boxMin.y, boxMin.z), glm::vec3(boxMin.x, boxMax.y, boxMin.z), glm::vec3(boxMax.x, boxMax.y, boxMin.z), glm::vec3(boxMin.x, boxMin.y, boxMax.z), glm::vec3(boxMax.x, boxMin.y, boxMax.z), glm::vec3(boxMin.x, boxMax.y, boxMax.z), glm::vec3(boxMax.x, boxMax.y, boxMax.z) }; for (auto& vertex : corners) { glm::vec3 rotatedVertex = glm::vec3(rotationMatrix * glm::vec4(vertex, 1.0f)); rotatedVertices.push_back(rotatedVertex); } glm::vec3 xAxis = glm::normalize(glm::vec3(rotationMatrix[0])); glm::vec3 yAxis = glm::normalize(glm::vec3(rotationMatrix[1])); glm::vec3 zAxis = glm::normalize(glm::vec3(rotationMatrix[2])); // Calculer les projections des coins sur chaque axe float minX = std::numeric_limits<float>::max(); float minY = std::numeric_limits<float>::max(); float minZ = std::numeric_limits<float>::max(); float maxX = std::numeric_limits<float>::min(); float maxY = std::numeric_limits<float>::min(); float maxZ = std::numeric_limits<float>::min(); for (const auto& vertex : rotatedVertices) { float projX = glm::dot(vertex, xAxis); float projY = glm::dot(vertex, yAxis); float projZ = glm::dot(vertex, zAxis); minX = std::min(minX, projX); minY = std::min(minY, projY); minZ = std::min(minZ, projZ); maxX = std::max(maxX, projX); maxY = std::max(maxY, projY); maxZ = std::max(maxZ, projZ); } glm::vec3 newMin = glm::vec3(minX, minY, minZ); glm::vec3 newMax = glm::vec3(maxX, maxY, maxZ); return {newMin, newMax}; } 
Enter fullscreen mode Exit fullscreen mode

the function, with min and max points of the OBB calculate all the corners and rotate them with a rotation matrix (calculated with angle). Then, the function determines the newMin and newMax points and return them. So, the problem I encountered is the function don't works with values of angle that are not equal to 0° or 180°. newMin and newMax don't match with the car.

at the base, to calculate the newMin and newMax values, I was just multiplying boxMin and boxMax with the rotationMatrix, but this method did not takes into account all the corners. To solve this problem, I made this function :

std::vector<glm::vec3> rotateCollisionBox(float angle, glm::vec3 boxMin, glm::vec3 boxMax) { std::vector<glm::vec3> rotatedVertices; glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0, 1.0, 0.0)); std::vector<glm::vec3> corners = { glm::vec3(boxMin.x, boxMin.y, boxMin.z), glm::vec3(boxMax.x, boxMin.y, boxMin.z), glm::vec3(boxMin.x, boxMax.y, boxMin.z), glm::vec3(boxMax.x, boxMax.y, boxMin.z), glm::vec3(boxMin.x, boxMin.y, boxMax.z), glm::vec3(boxMax.x, boxMin.y, boxMax.z), glm::vec3(boxMin.x, boxMax.y, boxMax.z), glm::vec3(boxMax.x, boxMax.y, boxMax.z) }; for (auto& vertex : corners) { glm::vec3 rotatedVertex = glm::vec3(rotationMatrix * glm::vec4(vertex, 1.0f)); rotatedVertices.push_back(rotatedVertex); } float minX; float minY; float minZ; float maxX; float maxY; float maxZ; for (const auto& vertex : rotatedVertices) { minX = std::min(minX, vertex.x); minY = std::min(minY, vertex.y); minZ = std::min(minZ, vertex.z); maxX = std::max(maxX, vertex.x); maxY = std::max(maxY, vertex.y); maxZ = std::max(maxZ, vertex.z); } glm::vec3 newMin = glm::vec3(minX, minY, minZ); glm::vec3 newMax = glm::vec3(maxX, maxY, maxZ); return {newMin, newMax}; } 
Enter fullscreen mode Exit fullscreen mode

this function was better because it worked for all angles multiples of 90 but it was not enough.So, I made the first function but it's worst than the second because it don't works for those angles : 90° and 270°. Please help me.

Top comments (0)