From ed12134f342d4443fef47cc8558cff415f9cee2d Mon Sep 17 00:00:00 2001 From: boromisp Date: Sun, 11 Nov 2012 23:41:11 +0100 Subject: [PATCH] Fixed the original ray-sphere intersection Changed the original analytic method to a geometrical. The errors in the original intersection calculation: The function has a sphere center parameter, but ignores it and assumes that the sphere is in the origo. It calculates the length of the ray direction vector, but later on uses this vector as a unit vector. The position calculation is simply wrong. It multiplies the direction vector with the radius of the sphere instead of the calculated intersection distance. The quadratic equation solving could be improved too: There should be an early exit for negative discriminant. The naive implementation sould be changed to a floating-point specialized one. --- glm/gtx/intersect.hpp | 6 +++--- glm/gtx/intersect.inl | 29 +++++++---------------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/glm/gtx/intersect.hpp b/glm/gtx/intersect.hpp index a997555c..56aabbc9 100644 --- a/glm/gtx/intersect.hpp +++ b/glm/gtx/intersect.hpp @@ -81,9 +81,9 @@ namespace glm //! From GLM_GTX_intersect extension. template bool intersectRaySphere( - genType const & orig, genType const & dir, - genType const & center, typename genType::value_type radius, - genType & position, genType & normal); + genType const & rayStarting, genType const & rayNormalizedDirection, + genType const & sphereCenter, const typename genType::value_type sphereRadius, + genType & intersectionPosition, genType & intersectionNormal); //! Compute the intersection of a line and a sphere. //! From GLM_GTX_intersect extension diff --git a/glm/gtx/intersect.inl b/glm/gtx/intersect.inl index 89e18886..3c8527e7 100644 --- a/glm/gtx/intersect.inl +++ b/glm/gtx/intersect.inl @@ -151,31 +151,16 @@ namespace glm template GLM_FUNC_QUALIFIER bool intersectRaySphere ( - genType const & rayStarting, genType const & rayDirection, - genType const & sphereCenter, typename genType::value_type sphereRadius, - genType & position, genType & normal + genType const & rayStarting, genType const & rayNormalizedDirection, + genType const & sphereCenter, const typename genType::value_type sphereRadius, + genType & intersectionPosition, genType & intersectionNormal ) { - typename genType::value_type Epsilon = std::numeric_limits::epsilon(); - - typename genType::value_type a = dot(rayDirection, rayDirection); - typename genType::value_type b = typename genType::value_type(2) * dot(rayStarting, rayDirection); - typename genType::value_type c = dot(rayStarting, rayStarting) - sphereRadius * sphereRadius; - typename genType::value_type d = b * b - typename genType::value_type(4) * a * c; - typename genType::value_type e = sqrt(d); - typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a); - typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a); - - if(x1 > Epsilon) + typename genType::value_type distance; + if( intersectRaySphere( rayStarting, rayNormalizedDirection, sphereCenter, sphereRadius * sphereRadius, distance ) ) { - position = rayStarting + rayDirection * sphereRadius; - normal = (position - sphereCenter) / sphereRadius; - return true; - } - else if(x2 > Epsilon) - { - position = rayStarting + rayDirection * sphereRadius; - normal = (position - sphereCenter) / sphereRadius; + intersectionPosition = rayStarting + rayNormalizedDirection * distance; + intersectionNormal = (intersectionPosition - sphereCenter) / sphereRadius; return true; } return false;