diff --git a/src/partitioning/bvh/bvh_tree.rs b/src/partitioning/bvh/bvh_tree.rs index 35baba88..6fa95e64 100644 --- a/src/partitioning/bvh/bvh_tree.rs +++ b/src/partitioning/bvh/bvh_tree.rs @@ -811,8 +811,12 @@ impl BvhNode { /// - [`Bvh::scale`] - Scale an entire BVH tree #[inline] pub fn scale(&mut self, scale: Vector) { - self.mins *= scale; - self.maxs *= scale; + let new_mins = self.mins * scale; + let new_maxs = self.maxs * scale; + // When scale has negative components, mins/maxs swap on those axes. + // Use component-wise min/max to maintain the AABB invariant (mins <= maxs). + self.mins = new_mins.min(new_maxs); + self.maxs = new_mins.max(new_maxs); } /// Calculates the volume of this node's AABB. @@ -1995,18 +1999,18 @@ impl Bvh { /// Scales all AABBs in the tree by the given factors. /// - /// This multiplies all AABB coordinates (mins and maxs) by the corresponding components - /// of the scale vector. This is useful when scaling an entire scene or changing coordinate - /// systems. + /// Each AABB's coordinates are multiplied by the corresponding scale components, with + /// mins and maxs swapped on any axis where the scale is negative to preserve the + /// AABB invariant. This is useful when scaling an entire scene or changing coordinate + /// systems, including reflections. /// /// # Arguments /// - /// * `scale` - Per-axis scale factors (must all be positive) + /// * `scale` - Per-axis scale factors. Each component must be non-zero. /// /// # Panics /// - /// This function has undefined behavior if any scale component is negative or zero. - /// Always use positive scale values. + /// Undefined behavior if any scale component is zero (degenerate AABB). /// /// # Example ///