Wie dreht man ein OBB richtig?C++

Programme in C++. Entwicklerforum
Guest
 Wie dreht man ein OBB richtig?

Post by Guest »

Ich habe mit OpenGL einen Autosimulator erstellt. Für die Autokollisionsbox habe ich ein OBB verwendet. Das Problem ist, wenn ich die Kollisionsbox drehen möchte. Dafür verwende ich diese Funktion:

Code: Select all

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};
}
Die Funktion berechnet mit den Min- und Max-Punkten des OBB alle Ecken und dreht sie mit einer Rotationsmatrix (berechnet mit Winkel). Anschließend ermittelt die Funktion die Punkte newMin und newMax und gibt sie zurück. Das Problem, auf das ich gestoßen bin, ist, dass die Funktion nicht mit Winkelwerten funktioniert, die ungleich 0° oder 180° sind. newMin und newMax stimmen nicht mit dem Auto überein.
An der Basis habe ich zur Berechnung der newMin- und newMax-Werte nur boxMin und boxMax mit der rotationMatrix multipliziert, was bei dieser Methode jedoch nicht der Fall war berücksichtigt alle Ecken. Um dieses Problem zu lösen, habe ich diese Funktion erstellt:

Code: Select all

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;
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};
}
Diese Funktion war besser, weil sie für alle Winkel funktionierte, die ein Vielfaches von 90 sind, aber sie reichte nicht aus. Also habe ich die erste Funktion erstellt, aber sie ist schlechter als die zweite, weil sie für nicht funktioniert diese Winkel: 90° und 270°. Bitte helfen Sie mir.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post