diff --git a/glm/gtx/intersect.hpp b/glm/gtx/intersect.hpp index 1c090b67..a997555c 100644 --- a/glm/gtx/intersect.hpp +++ b/glm/gtx/intersect.hpp @@ -68,6 +68,15 @@ namespace glm genType const & vert0, genType const & vert1, genType const & vert2, genType & position); + //! Compute the intersection distance of a ray and a sphere. + //! The ray direction vector is unit length. + //! From GLM_GTX_intersect extension. + template + bool intersectRaySphere( + genType const & rayStarting, genType const & rayNormalizedDirection, + genType const & sphereCenter, const typename genType::value_type sphereRadiusSquered, + typename genType::value_type & intersectionDistance); + //! Compute the intersection of a ray and a sphere. //! From GLM_GTX_intersect extension. template diff --git a/glm/gtx/intersect.inl b/glm/gtx/intersect.inl index ad55837f..89e18886 100644 --- a/glm/gtx/intersect.inl +++ b/glm/gtx/intersect.inl @@ -127,6 +127,27 @@ namespace glm return true; } + template + GLM_FUNC_QUALIFIER bool intersectRaySphere + ( + genType const & rayStarting, genType const & rayNormalizedDirection, + genType const & sphereCenter, const typename genType::value_type sphereRadiusSquered, + typename genType::value_type & intersectionDistance + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + genType diff = sphereCenter - rayStarting; + typename genType::value_type t0 = dot(diff, rayNormalizedDirection); + typename genType::value_type dSquared = dot(diff, diff) - t0 * t0; + if( dSquared > sphereRadiusSquered ) + { + return false; + } + typename genType::value_type t1 = sqrt( sphereRadiusSquered - dSquared ); + intersectionDistance = t0 > t1 + Epsilon ? t0 - t1 : t0 + t1; + return intersectionDistance > Epsilon; + } + template GLM_FUNC_QUALIFIER bool intersectRaySphere (