bevy_mod_raycast icon indicating copy to clipboard operation
bevy_mod_raycast copied to clipboard

intersects_aabb can return NaN which fails the filter predicate when checking for intersections

Open StrikeForceZero opened this issue 1 year ago • 1 comments

From investigating https://github.com/aevyrie/bevy_mod_picking/issues/341, I've discovered that:

https://github.com/aevyrie/bevy_mod_raycast/blob/dbc5ef32fe48997a1a7eeec7434d9dd8b829e52e/src/primitives.rs#L165-L204

intersects_aabb returns [NaN, NaN] because of a divide by 0 when the intersection check is right on the edge of a mesh, thus failing the filter predicate far > 0.0 here:

https://github.com/aevyrie/bevy_mod_raycast/blob/dbc5ef32fe48997a1a7eeec7434d9dd8b829e52e/src/immediate.rs#L260

It was not apparent to me what the right approach to prevent intersects_aabb from returning NaN. It's possible I'm being naive, and there's a more obvious fix, however, this diff seems to solve the symptom of that issue. (I have no idea if this introduces other side effects, but all the tests seem to pass?)

Index: src/immediate.rs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/immediate.rs b/src/immediate.rs
--- a/src/immediate.rs	(revision Staged)
+++ b/src/immediate.rs	(date 1720831909681)
@@ -257,7 +257,7 @@
                 };
                 if should_raycast {
                     if let Some([near, _]) = intersects_aabb(ray, aabb, &transform.compute_matrix())
-                        .filter(|[_, far]| *far >= 0.0)
+                        .filter(|[_, far]| *far >= 0.0 || far.is_nan())
                     {
                         aabb_hits_tx.send((FloatOrd(near), entity)).ok();
                     }

StrikeForceZero avatar Jul 13 '24 01:07 StrikeForceZero