From 26abbb2bdae701a6ba090e3156ff0411d0114cbb Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 24 Feb 2023 23:52:58 -0800 Subject: [PATCH] Fixed? Normal calculation on 3D AABB --- src/dawn/physics/3d/Ray3D.cpp | 42 +++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/dawn/physics/3d/Ray3D.cpp b/src/dawn/physics/3d/Ray3D.cpp index 99c5bed8..75f7111e 100644 --- a/src/dawn/physics/3d/Ray3D.cpp +++ b/src/dawn/physics/3d/Ray3D.cpp @@ -70,7 +70,7 @@ bool_t Dawn::raytestTriangle( glm::vec3 n0 = glm::cross(edge0, c0); glm::vec3 n1 = glm::cross(edge1, c1); glm::vec3 n2 = glm::cross(edge2, c2); - if (glm::dot(n0, normal) >= 0 && glm::dot(n1, normal) >= 0 && glm::dot(n2, normal) >= 0) { + if(glm::dot(n0, normal) >= 0 && glm::dot(n1, normal) >= 0 && glm::dot(n2, normal) >= 0) { // If the intersection point is inside the triangle, set the hit point, normal and distance *hitPoint = intersectionPoint; *hitNormal = normal; @@ -89,6 +89,10 @@ bool_t Dawn::raytestAABB( glm::vec3 *normal, float_t *distance ) { + assertNotNull(point); + assertNotNull(normal); + assertNotNull(distance); + // Compute the inverse direction of the ray, for numerical stability glm::vec3 invDir(1.0f / ray.direction.x, 1.0f / ray.direction.y, 1.0f / ray.direction.z); @@ -103,7 +107,7 @@ bool_t Dawn::raytestAABB( float tFar = glm::compMin(t2); // If tNear is greater than or equal to tFar, there is no intersection - if (tNear >= tFar) return false; + if(tNear >= tFar) return false; // If tFar is negative, the ray is pointing away from the box if(tFar < 0.0f) return false; @@ -111,25 +115,25 @@ bool_t Dawn::raytestAABB( // Compute the hit point and normal glm::vec3 hitPoint = ray.origin + tNear * ray.direction; - if(point != nullptr) *point = hitPoint; - if(distance != nullptr) *distance = tNear; - if(normal != nullptr) { - if (hitPoint.x == box.min.x) { - *normal = glm::vec3(-1, 0, 0); - } else if (hitPoint.x == box.max.x) { - *normal = glm::vec3(1, 0, 0); - } else if (hitPoint.y == box.min.y) { - *normal = glm::vec3(0, -1, 0); - } else if (hitPoint.y == box.max.y) { - *normal = glm::vec3(0, 1, 0); - } else if (hitPoint.z == box.min.z) { - *normal = glm::vec3(0, 0, -1); - } else if (hitPoint.z == box.max.z) { - *normal = glm::vec3(0, 0, 1); - } + *point = hitPoint; + *distance = tNear; + + // Small value to account for floating point imprecision + const float epsilon = 0.001f; + if(std::abs(hitPoint.x - box.min.x) < epsilon) { + *normal = glm::vec3(-1, 0, 0); + } else if(std::abs(hitPoint.x - box.max.x) < epsilon) { + *normal = glm::vec3(1, 0, 0); + } else if(std::abs(hitPoint.y - box.min.y) < epsilon) { + *normal = glm::vec3(0, -1, 0); + } else if(std::abs(hitPoint.y - box.max.y) < epsilon) { + *normal = glm::vec3(0, 1, 0); + } else if(std::abs(hitPoint.z - box.min.z) < epsilon) { + *normal = glm::vec3(0, 0, -1); + } else if(std::abs(hitPoint.z - box.max.z) < epsilon) { + *normal = glm::vec3(0, 0, 1); } - // The ray intersects the box return true; }