Код: Выделить всё
std::vector rotateCollisionBox(float angle, glm::vec3 boxMin, glm::vec3 boxMax) {
std::vector rotatedVertices;
glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0, 1.0, 0.0));
std::vector 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::max();
float minY = std::numeric_limits::max();
float minZ = std::numeric_limits::max();
float maxX = std::numeric_limits::min();
float maxY = std::numeric_limits::min();
float maxZ = std::numeric_limits::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};
}
Изначально, чтобы вычислить значения newMin и newMax, я просто умножал boxMin и boxMax на RotationMatrix, но этот метод не учитывал учесть все углы. Чтобы решить эту проблему, я создал эту функцию:
Код: Выделить всё
std::vector rotateCollisionBox(float angle, glm::vec3 boxMin, glm::vec3 boxMax) {
std::vector rotatedVertices;
glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0, 1.0, 0.0));
std::vector 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 = std::numeric_limits::max();
float minY = std::numeric_limits::max();
float minZ = std::numeric_limits::max();
float maxX = std::numeric_limits::min();
float maxY = std::numeric_limits::min();
float maxZ = std::numeric_limits::min();
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};
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... ate-an-obb