Skip to content

Commit

Permalink
Add scale_around_center method to BoundingVolume trait (#12142)
Browse files Browse the repository at this point in the history
# Objective

Add a `scale_around_center` method to the `BoundingVolume` trait, as per
#12130.

## Solution

Added `scale_around_center` to the `BoundingVolume` trait, implemented
in `Aabb2d`, `Aabb3d`, `BoundingCircle`, and `BoundingSphere` (with
tests).
  • Loading branch information
chompaa authored Mar 11, 2024
1 parent d0f24aa commit 686d354
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
38 changes: 38 additions & 0 deletions crates/bevy_math/src/bounding/bounded2d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ impl BoundingVolume for Aabb2d {
b
}

#[inline(always)]
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
let b = Self {
min: self.center() - (self.half_size() * scale),
max: self.center() + (self.half_size() * scale),
};
debug_assert!(b.min.x <= b.max.x && b.min.y <= b.max.y);
b
}

/// Transforms the bounding volume by first rotating it around the origin and then applying a translation.
///
/// The result is an Axis-Aligned Bounding Box that encompasses the rotated shape.
Expand Down Expand Up @@ -352,6 +362,19 @@ mod aabb2d_tests {
assert!(!shrunk.contains(&a));
}

#[test]
fn scale_around_center() {
let a = Aabb2d {
min: Vec2::NEG_ONE,
max: Vec2::ONE,
};
let scaled = a.scale_around_center(Vec2::splat(2.));
assert!((scaled.min - Vec2::splat(-2.)).length() < std::f32::EPSILON);
assert!((scaled.max - Vec2::splat(2.)).length() < std::f32::EPSILON);
assert!(!a.contains(&scaled));
assert!(scaled.contains(&a));
}

#[test]
fn transform() {
let a = Aabb2d {
Expand Down Expand Up @@ -546,6 +569,12 @@ impl BoundingVolume for BoundingCircle {
Self::new(self.center, self.radius() - amount)
}

#[inline(always)]
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
debug_assert!(scale >= 0.);
Self::new(self.center, self.radius() * scale)
}

#[inline(always)]
fn translate_by(&mut self, translation: Self::Translation) {
self.center += translation;
Expand Down Expand Up @@ -658,6 +687,15 @@ mod bounding_circle_tests {
assert!(!shrunk.contains(&a));
}

#[test]
fn scale_around_center() {
let a = BoundingCircle::new(Vec2::ONE, 5.);
let scaled = a.scale_around_center(2.);
assert!((scaled.radius() - 10.).abs() < std::f32::EPSILON);
assert!(!a.contains(&scaled));
assert!(scaled.contains(&a));
}

#[test]
fn transform() {
let a = BoundingCircle::new(Vec2::ONE, 5.0);
Expand Down
38 changes: 38 additions & 0 deletions crates/bevy_math/src/bounding/bounded3d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ impl BoundingVolume for Aabb3d {
b
}

#[inline(always)]
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
let b = Self {
min: self.center() - (self.half_size() * scale),
max: self.center() + (self.half_size() * scale),
};
debug_assert!(b.min.x <= b.max.x && b.min.y <= b.max.y);
b
}

/// Transforms the bounding volume by first rotating it around the origin and then applying a translation.
///
/// The result is an Axis-Aligned Bounding Box that encompasses the rotated shape.
Expand Down Expand Up @@ -348,6 +358,19 @@ mod aabb3d_tests {
assert!(!shrunk.contains(&a));
}

#[test]
fn scale_around_center() {
let a = Aabb3d {
min: Vec3::NEG_ONE,
max: Vec3::ONE,
};
let scaled = a.scale_around_center(Vec3::splat(2.));
assert!((scaled.min - Vec3::splat(-2.)).length() < std::f32::EPSILON);
assert!((scaled.max - Vec3::splat(2.)).length() < std::f32::EPSILON);
assert!(!a.contains(&scaled));
assert!(scaled.contains(&a));
}

#[test]
fn transform() {
let a = Aabb3d {
Expand Down Expand Up @@ -549,6 +572,12 @@ impl BoundingVolume for BoundingSphere {
}
}

#[inline(always)]
fn scale_around_center(&self, scale: Self::HalfSize) -> Self {
debug_assert!(scale >= 0.);
Self::new(self.center, self.radius() * scale)
}

#[inline(always)]
fn translate_by(&mut self, translation: Self::Translation) {
self.center += translation;
Expand Down Expand Up @@ -663,6 +692,15 @@ mod bounding_sphere_tests {
assert!(!shrunk.contains(&a));
}

#[test]
fn scale_around_center() {
let a = BoundingSphere::new(Vec3::ONE, 5.);
let scaled = a.scale_around_center(2.);
assert!((scaled.radius() - 10.).abs() < std::f32::EPSILON);
assert!(!a.contains(&scaled));
assert!(scaled.contains(&a));
}

#[test]
fn transform() {
let a = BoundingSphere::new(Vec3::ONE, 5.0);
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_math/src/bounding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub trait BoundingVolume: Sized {
/// Decreases the size of the bounding volume in each direction by the given amount.
fn shrink(&self, amount: Self::HalfSize) -> Self;

/// Scale the size of the bounding volume around its center by the given amount
fn scale_around_center(&self, scale: Self::HalfSize) -> Self;

/// Transforms the bounding volume by first rotating it around the origin and then applying a translation.
fn transformed_by(
mut self,
Expand Down

0 comments on commit 686d354

Please sign in to comment.