diff --git a/geom/ray.hpp b/geom/ray.hpp index fabac6c0..1c142479 100644 --- a/geom/ray.hpp +++ b/geom/ray.hpp @@ -90,8 +90,13 @@ namespace util::geom { /////////////////////////////////////////////////////////////////////////// // returns the distance along a ray to an aabb // - // the return value may be negative if the plane lies behind the ray. - // the return value may be infinity in the case the ray and plane are parallel + // the distance will never be negative + // + // the origin point of the ray does not provoke an intersection, so the + // returned distances _should_ always be strictly positive. + // + // if a forward intersection cannot be found then 'infinity' is returned + // instead. template constexpr T distance (const ray r, const aabb b) @@ -105,12 +110,17 @@ namespace util::geom { const auto tmax = min (max (t1, t2)); // did not intersect - if (tmin > tmax) + if (tmin >= tmax) return std::numeric_limits::infinity (); // closest is behind us - if (tmin < 0) - return tmax; + if (tmin <= 0) { + if (tmax <= 0) { + return std::numeric_limits::infinity (); + } else { + return tmax; + } + } // closest is in front of us return tmin; diff --git a/test/geom/aabb.cpp b/test/geom/aabb.cpp index 23571147..0ad63a42 100644 --- a/test/geom/aabb.cpp +++ b/test/geom/aabb.cpp @@ -12,7 +12,7 @@ main (int, char**) util::TAP::logger tap; { - + const auto upright = normalised (util::vector2f {1}); static struct { util::point2f lo; @@ -25,12 +25,24 @@ main (int, char**) const char *message; } const TESTS[] { + { + { 0, 0 }, { 1, 1 }, + { 0, 0 }, upright, + std::sqrt (2.f), + "ray on aabb corner, pointing to opposite corner", + }, + { + { 0, 0 }, { 1, 1 }, + { 0, 1 }, upright, + INFINITY, + "ray on aabb implied corner, pointing away", + }, { { 1, 1 }, { 9, 9 }, - { 2, 2 }, { 1/std::sqrt (2.f), 1/std::sqrt (2.f) }, + { 2, 2 }, upright, std::sqrt (7.f * 7 * 2), - "ray doesn't give negative distance to closest edge" - } + "ray inside aabb, close to one corner and pointing to far corner", + }, }; for (auto const &t: TESTS) { diff --git a/test/geom/ray.cpp b/test/geom/ray.cpp index 7209d988..717691c4 100644 --- a/test/geom/ray.cpp +++ b/test/geom/ray.cpp @@ -20,34 +20,6 @@ test_intersect_plane (util::TAP::logger &tap) } -//----------------------------------------------------------------------------- -void -test_intersect_aabb (util::TAP::logger &tap) -{ - using util::geom::aabb2f; - - // trivial case: unit aabb at origin, ray from (0.5,-0.5) upwards - const aabb2f box { - { 0.f, 0.f }, - { 1.f, 1.f } - }; - - const ray2f forward { - util::point2f { 0.5f, -0.5f }, - util::vector2f { 0.0f, 1.0f } - }; - - tap.expect_eq (distance (forward, box), 0.5f, "ray-aabb intersect"); - - const ray2f behind { - util::point2f { 0.5f, 2.0f }, - util::vector2f { 0.0f, 1.0f } - }; - - tap.expect_eq (distance (behind, box), -1.f, "ray-aabb intersect behind"); -} - - //----------------------------------------------------------------------------- int main (void) @@ -55,7 +27,6 @@ main (void) util::TAP::logger tap; test_intersect_plane (tap); - test_intersect_aabb (tap); return tap.status (); }