summary refs log tree commit diff
path: root/src/Math
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-02-05 13:48:13 +0100
committerMel <einebeere@gmail.com>2024-02-05 13:48:13 +0100
commit091bf9e418ffdcf36e1735ed78d544f3d1b86785 (patch)
tree58b1cd88d9822b14c90da757cc26acb64bf9bad5 /src/Math
parentbcb89e0554e43d37daf74b3ef6e466b6630752cd (diff)
downloadmeowcraft-091bf9e418ffdcf36e1735ed78d544f3d1b86785.tar.zst
meowcraft-091bf9e418ffdcf36e1735ed78d544f3d1b86785.zip
More precise collision detection (and less NaNs)
Diffstat (limited to 'src/Math')
-rw-r--r--src/Math/AABB.hpp6
-rw-r--r--src/Math/Functions.hpp7
-rw-r--r--src/Math/Ray.hpp2
-rw-r--r--src/Math/Vector.hpp9
4 files changed, 21 insertions, 3 deletions
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 <typename T>
 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 <typename T>
+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];
     }