所以我有这个函数来获取射线与OBB的交点:
std::optional<float> Ray::hitsOBB(const glm::vec3& min, const glm::vec3& max, const glm::mat4& modelMatrix) {
float tMin = 0.0f;
float tMax = 100000.0f;
glm::vec3 OBBposition_worldspace(modelMatrix[3].x, modelMatrix[3].y, modelMatrix[3].z);
glm::vec3 delta = OBBposition_worldspace - origin;
{
glm::vec3 xaxis(modelMatrix[0].x, modelMatrix[0].y, modelMatrix[0].z);
float e = glm::dot(xaxis, delta);
float f = glm::dot(direction, xaxis);
if (fabs(f) > 0.001f) {
float t1 = (e + min.x) / f;
float t2 = (e + max.x) / f;
if (t1 > t2) std::swap(t1, t2);
if (t2 < tMax) tMax = t2;
if (t1 > tMin) tMin = t1;
if (tMin > tMax) return {};
}
else {
if (-e + min.x > 0.0f || -e + max.x < 0.0f) return {};
}
}
{
glm::vec3 yaxis(modelMatrix[1].x, modelMatrix[1].y, modelMatrix[1].z);
float e = glm::dot(yaxis, delta);
float f = glm::dot(direction, yaxis);
if (fabs(f) > 0.001f) {
float t1 = (e + min.y) / f;
float t2 = (e + max.y) / f;
if (t1 > t2) std::swap(t1, t2);
if (t2 < tMax) tMax = t2;
if (t1 > tMin) tMin = t1;
if (tMin > tMax) return {};
}
else {
if (-e + min.y > 0.0f || -e + max.y < 0.0f) return {};
}
}
{
glm::vec3 zaxis(modelMatrix[2].x, modelMatrix[2].y, modelMatrix[2].z);
float e = glm::dot(zaxis, delta);
float f = glm::dot(direction, zaxis);
if (fabs(f) > 0.001f) {
float t1 = (e + min.z) / f;
float t2 = (e + max.z) / f;
if (t1 > t2) std::swap(t1, t2);
if (t2 < tMax) tMax = t2;
if (t1 > tMin) tMin = t1;
if (tMin > tMax) return {};
}
else {
if (-e + min.z > 0.0f || -e + max.z < 0.0f) return {};
}
}
return tMin;
}
我用它来点击OpenGL中的立方体。测试用例是一个立方体,最小值和最大值分别为(-1,-1,-1)和(1,1,1)。现在,当旋转和平移modelMatrix时,这工作得很好,但它似乎没有考虑到比例。我试过将最小值和最大值与modelMatrix比例相乘,但没有用。有人知道发生什么事了吗
1条答案
按热度按时间abithluo1#
我遇到了同样的问题,我通过不缩放modelMatrix并只为aabb_min和aabb_max提供scale来解决它: