fix: Possible NaN due to denormalised quaternions in AABB implementations for round shapes. (#14240)

# Objective

With an unlucky denormalised quaternion (or just a regular very
denormalised quaternion), it's possible to obtain NaN values for AABB's
in shapes which rely on an AABB for a disk.

## Solution

Add an additional `.max(Vec3::ZERO)` clamp to get rid of negative values
arising due to numerical errors.
Fixup some unnecessary calculations and improve variable names in
relevant code, aiming for consistency.

## Discussion

These two (nontrivial) lines of code are repeated at least 5 times,
maybe they could be their own method.
This commit is contained in:
IQuick 143 2024-07-10 18:00:19 +02:00 committed by François
parent 1bc5ecda9b
commit 0e1858bc4f
No known key found for this signature in database
2 changed files with 9 additions and 9 deletions

View file

@ -20,7 +20,7 @@ impl BoundedExtrusion for Circle {
let segment_dir = rotation * Vec3::Z;
let top = (segment_dir * half_depth).abs();
let e = Vec3::ONE - segment_dir * segment_dir;
let e = (Vec3::ONE - segment_dir * segment_dir).max(Vec3::ZERO);
let half_size = self.radius * Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt());
Aabb3d {

View file

@ -125,7 +125,7 @@ impl Bounded3d for Cylinder {
let top = segment_dir * self.half_height;
let bottom = -top;
let e = Vec3::ONE - segment_dir * segment_dir;
let e = (Vec3::ONE - segment_dir * segment_dir).max(Vec3::ZERO);
let half_size = self.radius * Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt());
Aabb3d {
@ -169,11 +169,11 @@ impl Bounded3d for Cone {
fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d {
// Reference: http://iquilezles.org/articles/diskbbox/
let top = rotation * Vec3::Y * 0.5 * self.height;
let segment_dir = rotation * Vec3::Y;
let top = segment_dir * 0.5 * self.height;
let bottom = -top;
let segment = bottom - top;
let e = 1.0 - segment * segment / segment.length_squared();
let e = (Vec3::ONE - segment_dir * segment_dir).max(Vec3::ZERO);
let half_extents = Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt());
Aabb3d {
@ -203,11 +203,11 @@ impl Bounded3d for ConicalFrustum {
fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d {
// Reference: http://iquilezles.org/articles/diskbbox/
let top = rotation * Vec3::Y * 0.5 * self.height;
let segment_dir = rotation * Vec3::Y;
let top = segment_dir * 0.5 * self.height;
let bottom = -top;
let segment = bottom - top;
let e = 1.0 - segment * segment / segment.length_squared();
let e = (Vec3::ONE - segment_dir * segment_dir).max(Vec3::ZERO);
let half_extents = Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt());
Aabb3d {
@ -286,7 +286,7 @@ impl Bounded3d for Torus {
// Compute the AABB of a flat disc with the major radius of the torus.
// Reference: http://iquilezles.org/articles/diskbbox/
let normal = rotation * Vec3::Y;
let e = 1.0 - normal * normal;
let e = (Vec3::ONE - normal * normal).max(Vec3::ZERO);
let disc_half_size = self.major_radius * Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt());
// Expand the disc by the minor radius to get the torus half-size