fix(scene): normalize inverted AABBs in spatial index and add warm cache timers

This commit is contained in:
Karim Jerbi committed 2026-10-09 14:20:13 +01:00
1 parent 2a2d9b55d9
commit 237d3afd2f
2 files changed
+72 -1

No files matched your search

+40 -1
View File
@@ -97,7 +97,8 @@ impl QuadTree {
}
pub fn insert(&mut self, handle: Handle, aabb: Aabb) {
if !aabb_contained(self.nodes[0].bounds, aabb) {
let aabb = normalize_aabb(aabb);
if !aabb.iter().all(|x| x.is_finite()) || !aabb_contained(self.nodes[0].bounds, aabb) {
self.overflow.push(Item { handle, aabb });
return;
}
@@ -256,6 +257,16 @@ impl QuadTree {
// ── AABB helpers ────────────────────────────────────────────────────
pub fn normalize_aabb(mut aabb: Aabb) -> Aabb {
if aabb[0] > aabb[2] {
aabb.swap(0, 2);
}
if aabb[1] > aabb[3] {
aabb.swap(1, 3);
}
aabb
}
fn aabb_contained(outer: Aabb, inner: Aabb) -> bool {
inner[0] >= outer[0]
&& inner[1] >= outer[1]
@@ -391,4 +402,32 @@ mod tests {
let se_hits = t.query_rect([50.0, 0.0, 100.0, 50.0]);
assert!(se_hits.contains(&h(1)));
}
#[test]
fn insert_handles_nan_and_infinite_bounds_safely() {
let root = [0.0, 0.0, 100.0, 100.0];
let mut tree = QuadTree::new(root);
tree.insert(h(1), [10.0, 10.0, 20.0, 20.0]);
tree.insert(h(2), [f64::NAN, 10.0, 20.0, 20.0]);
tree.insert(h(3), [10.0, f64::INFINITY, 20.0, 20.0]);
tree.insert(h(4), [20.0, 20.0, 10.0, 10.0]); // inverted bounds: normalized
assert_eq!(tree.len(), 4);
// Handles 2 & 3 have non-finite coords so they land in overflow
// Handle 4 has inverted coords which normalize and fit inside root
assert_eq!(tree.overflow.len(), 2);
let normal_hits = tree.query_rect([5.0, 5.0, 25.0, 25.0]);
assert!(normal_hits.contains(&h(1)));
assert!(normal_hits.contains(&h(4))); // normalized [10.0, 10.0, 20.0, 20.0]
}
#[test]
fn normalize_aabb_flips_inverted_extents() {
let inverted = [50.0, 60.0, 10.0, 20.0];
let normalized = normalize_aabb(inverted);
assert_eq!(normalized, [10.0, 20.0, 50.0, 60.0]);
}
}