Open StrikeForceZero opened 4 months ago
snippet to reproduce it in headless
#[cfg(test)]
mod tests {
use super::*;
use bevy_math::{Dir3, Mat4, Ray3d, Vec3, Vec4};
use bevy_render::primitives::Aabb;
#[test]
fn test_intersects_aabb_nan() {
let ray = Ray3d {
origin: Vec3::new(275.0, 247.0, 1000.0),
direction: Dir3::new_unchecked(Vec3::new(0.0, 0.0, -1.0)),
};
let aabb = Aabb {
center: Vec3A::new(0.0, 0.0, 0.0),
half_extents: Vec3A::new(25.0, 25.0, 0.0),
};
let model_to_world = Mat4 {
x_axis: Vec4::new(1.0, 0.0, 0.0, 0.0),
y_axis: Vec4::new(0.0, 1.0, 0.0, 0.0),
z_axis: Vec4::new(0.0, 0.0, 1.0, 0.0),
w_axis: Vec4::new(250.0, 350.0, 1.0, 1.0),
};
let result = intersects_aabb(ray, &aabb, &model_to_world);
assert_eq!(result.map(|[near, far]| [near.is_nan(), far.is_nan()]), Some([true, true]));
}
}
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 predicatefar > 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 returningNaN
. 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?)