From 091bf9e418ffdcf36e1735ed78d544f3d1b86785 Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 5 Feb 2024 13:48:13 +0100 Subject: More precise collision detection (and less NaNs) --- src/Math/AABB.hpp | 6 +++--- src/Math/Functions.hpp | 7 +++++++ src/Math/Ray.hpp | 2 ++ src/Math/Vector.hpp | 9 +++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'src/Math') diff --git a/src/Math/AABB.hpp b/src/Math/AABB.hpp index b298126..bff543e 100644 --- a/src/Math/AABB.hpp +++ b/src/Math/AABB.hpp @@ -27,15 +27,15 @@ struct AABB { } Bool intersects_on_x(AABB other) const { - return min.x() <= other.max.x() && max.x() >= other.min.x(); + return Math::floats_less(min.x(), other.max.x()) && Math::floats_less(other.min.x(), max.x()); } Bool intersects_on_y(AABB other) const { - return min.y() <= other.max.y() && max.y() >= other.min.y(); + return Math::floats_less(min.y(), other.max.y()) && Math::floats_less(other.min.y(), max.y()); } Bool intersects_on_z(AABB other) const { - return min.z() <= other.max.z() && max.z() >= other.min.z(); + return Math::floats_less(min.z(), other.max.z()) && Math::floats_less(other.min.z(), max.z()); } Bool collides(AABB other) const { diff --git a/src/Math/Functions.hpp b/src/Math/Functions.hpp index fd99c6d..0cda6bd 100644 --- a/src/Math/Functions.hpp +++ b/src/Math/Functions.hpp @@ -38,9 +38,16 @@ R sign(T x) { // III. Utility functions. +// Compares two floating point numbers for equality, with a given epsilon. template Bool floats_equal(T a, T b, Real epsilon = 0.0001f) { return std::abs(a - b) < epsilon; } +// Compares two floating point numbers for inequality, with a given epsilon. +template +Bool floats_less(T a, T b, Real epsilon = 0.0001f) { + return a < b - epsilon; +} + } \ No newline at end of file diff --git a/src/Math/Ray.hpp b/src/Math/Ray.hpp index db37ac2..4050a02 100644 --- a/src/Math/Ray.hpp +++ b/src/Math/Ray.hpp @@ -15,6 +15,8 @@ struct Ray { // [1]: https://gdbooks.gitbooks.io/3dcollisions/content/Chapter3/raycast_aabb.html // [2]: https://tavianator.com/2015/ray_box_nan.html RaycastResult cast(AABB box, Real max_distance = 0) const { + if (direction.is_zero()) return {}; + RaycastResult hit{ true }; // `t` is the time at which the ray intersects a plane of the AABB. diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp index 7d07d5c..3525e42 100644 --- a/src/Math/Vector.hpp +++ b/src/Math/Vector.hpp @@ -125,6 +125,15 @@ struct Vector { return mostly_equal(zero()); } + Bool is_nan() const { + for (UInt i = 0; i < S; i++) { + if (std::isnan(elements[i])) { + return true; + } + } + return false; + } + T operator[](USize index) const { return elements[index]; } -- cgit 1.4.1