Add Aabb2d::new and Aabb3d::new constructors (#11433)
				
					
				
			# Objective
Currently, the only way to create an AABB is to specify its `min` and
`max` coordinates. However, it's often more useful to use the center and
half-size instead.
## Solution
Add `new` constructors for `Aabb2d` and `Aabb3d`.
This:
```rust
let aabb = Aabb3d {
    min: center - half_size,
    max: center + half_size,
}
```
becomes this:
```rust
let aabb = Aabb3d::new(center, half_size);
```
I also made the usage of "half-extents" vs. "half-size" a bit more
consistent.
			
			
This commit is contained in:
		
							parent
							
								
									440bba80c4
								
							
						
					
					
						commit
						c31f3aa128
					
				| @ -38,6 +38,16 @@ pub struct Aabb2d { | ||||
| } | ||||
| 
 | ||||
| impl Aabb2d { | ||||
|     /// Constructs an AABB from its center and half-size.
 | ||||
|     #[inline(always)] | ||||
|     pub fn new(center: Vec2, half_size: Vec2) -> Self { | ||||
|         debug_assert!(half_size.x >= 0.0 && half_size.y >= 0.0); | ||||
|         Self { | ||||
|             min: center - half_size, | ||||
|             max: center + half_size, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Computes the smallest [`Aabb2d`] containing the given set of points,
 | ||||
|     /// transformed by `translation` and `rotation`.
 | ||||
|     ///
 | ||||
| @ -248,7 +258,7 @@ pub struct BoundingCircle { | ||||
| } | ||||
| 
 | ||||
| impl BoundingCircle { | ||||
|     /// Construct a bounding circle from its center and radius
 | ||||
|     /// Constructs a bounding circle from its center and radius.
 | ||||
|     #[inline(always)] | ||||
|     pub fn new(center: Vec2, radius: f32) -> Self { | ||||
|         debug_assert!(radius >= 0.); | ||||
|  | ||||
| @ -11,10 +11,7 @@ use super::{Aabb2d, Bounded2d, BoundingCircle}; | ||||
| 
 | ||||
| impl Bounded2d for Circle { | ||||
|     fn aabb_2d(&self, translation: Vec2, _rotation: f32) -> Aabb2d { | ||||
|         Aabb2d { | ||||
|             min: translation - Vec2::splat(self.radius), | ||||
|             max: translation + Vec2::splat(self.radius), | ||||
|         } | ||||
|         Aabb2d::new(translation, Vec2::splat(self.radius)) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_circle(&self, translation: Vec2, _rotation: f32) -> BoundingCircle { | ||||
| @ -47,12 +44,9 @@ impl Bounded2d for Ellipse { | ||||
|         let (ux, uy) = (hw * alpha_cos, hw * alpha_sin); | ||||
|         let (vx, vy) = (hh * beta_cos, hh * beta_sin); | ||||
| 
 | ||||
|         let half_extents = Vec2::new(ux.hypot(vx), uy.hypot(vy)); | ||||
|         let half_size = Vec2::new(ux.hypot(vx), uy.hypot(vy)); | ||||
| 
 | ||||
|         Aabb2d { | ||||
|             min: translation - half_extents, | ||||
|             max: translation + half_extents, | ||||
|         } | ||||
|         Aabb2d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_circle(&self, translation: Vec2, _rotation: f32) -> BoundingCircle { | ||||
| @ -72,10 +66,7 @@ impl Bounded2d for Plane2d { | ||||
|         let half_height = if facing_y { 0.0 } else { f32::MAX / 2.0 }; | ||||
|         let half_size = Vec2::new(half_width, half_height); | ||||
| 
 | ||||
|         Aabb2d { | ||||
|             min: translation - half_size, | ||||
|             max: translation + half_size, | ||||
|         } | ||||
|         Aabb2d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_circle(&self, translation: Vec2, _rotation: f32) -> BoundingCircle { | ||||
| @ -94,10 +85,7 @@ impl Bounded2d for Line2d { | ||||
|         let half_height = if direction.y == 0.0 { 0.0 } else { max }; | ||||
|         let half_size = Vec2::new(half_width, half_height); | ||||
| 
 | ||||
|         Aabb2d { | ||||
|             min: translation - half_size, | ||||
|             max: translation + half_size, | ||||
|         } | ||||
|         Aabb2d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_circle(&self, translation: Vec2, _rotation: f32) -> BoundingCircle { | ||||
| @ -109,12 +97,9 @@ impl Bounded2d for Segment2d { | ||||
|     fn aabb_2d(&self, translation: Vec2, rotation: f32) -> Aabb2d { | ||||
|         // Rotate the segment by `rotation`
 | ||||
|         let direction = Mat2::from_angle(rotation) * *self.direction; | ||||
|         let half_extent = (self.half_length * direction).abs(); | ||||
|         let half_size = (self.half_length * direction).abs(); | ||||
| 
 | ||||
|         Aabb2d { | ||||
|             min: translation - half_extent, | ||||
|             max: translation + half_extent, | ||||
|         } | ||||
|         Aabb2d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_circle(&self, translation: Vec2, _rotation: f32) -> BoundingCircle { | ||||
| @ -195,10 +180,7 @@ impl Bounded2d for Rectangle { | ||||
|         let abs_rot_mat = Mat2::from_cols_array(&[cos.abs(), sin.abs(), sin.abs(), cos.abs()]); | ||||
|         let half_size = abs_rot_mat * self.half_size; | ||||
| 
 | ||||
|         Aabb2d { | ||||
|             min: translation - half_size, | ||||
|             max: translation + half_size, | ||||
|         } | ||||
|         Aabb2d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_circle(&self, translation: Vec2, _rotation: f32) -> BoundingCircle { | ||||
|  | ||||
| @ -33,6 +33,16 @@ pub struct Aabb3d { | ||||
| } | ||||
| 
 | ||||
| impl Aabb3d { | ||||
|     /// Constructs an AABB from its center and half-size.
 | ||||
|     #[inline(always)] | ||||
|     pub fn new(center: Vec3, half_size: Vec3) -> Self { | ||||
|         debug_assert!(half_size.x >= 0.0 && half_size.y >= 0.0 && half_size.z >= 0.0); | ||||
|         Self { | ||||
|             min: center - half_size, | ||||
|             max: center + half_size, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Computes the smallest [`Aabb3d`] containing the given set of points,
 | ||||
|     /// transformed by `translation` and `rotation`.
 | ||||
|     ///
 | ||||
| @ -243,7 +253,7 @@ pub struct BoundingSphere { | ||||
| } | ||||
| 
 | ||||
| impl BoundingSphere { | ||||
|     /// Construct a bounding sphere from its center and radius.
 | ||||
|     /// Constructs a bounding sphere from its center and radius.
 | ||||
|     pub fn new(center: Vec3, radius: f32) -> Self { | ||||
|         debug_assert!(radius >= 0.); | ||||
|         Self { | ||||
|  | ||||
| @ -14,10 +14,7 @@ use super::{Aabb3d, Bounded3d, BoundingSphere}; | ||||
| 
 | ||||
| impl Bounded3d for Sphere { | ||||
|     fn aabb_3d(&self, translation: Vec3, _rotation: Quat) -> Aabb3d { | ||||
|         Aabb3d { | ||||
|             min: translation - Vec3::splat(self.radius), | ||||
|             max: translation + Vec3::splat(self.radius), | ||||
|         } | ||||
|         Aabb3d::new(translation, Vec3::splat(self.radius)) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_sphere(&self, translation: Vec3, _rotation: Quat) -> BoundingSphere { | ||||
| @ -39,10 +36,7 @@ impl Bounded3d for Plane3d { | ||||
|         let half_depth = if facing_z { 0.0 } else { f32::MAX / 2.0 }; | ||||
|         let half_size = Vec3::new(half_width, half_height, half_depth); | ||||
| 
 | ||||
|         Aabb3d { | ||||
|             min: translation - half_size, | ||||
|             max: translation + half_size, | ||||
|         } | ||||
|         Aabb3d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_sphere(&self, translation: Vec3, _rotation: Quat) -> BoundingSphere { | ||||
| @ -62,10 +56,7 @@ impl Bounded3d for Line3d { | ||||
|         let half_depth = if direction.z == 0.0 { 0.0 } else { max }; | ||||
|         let half_size = Vec3::new(half_width, half_height, half_depth); | ||||
| 
 | ||||
|         Aabb3d { | ||||
|             min: translation - half_size, | ||||
|             max: translation + half_size, | ||||
|         } | ||||
|         Aabb3d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_sphere(&self, translation: Vec3, _rotation: Quat) -> BoundingSphere { | ||||
| @ -77,12 +68,9 @@ impl Bounded3d for Segment3d { | ||||
|     fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d { | ||||
|         // Rotate the segment by `rotation`
 | ||||
|         let direction = rotation * *self.direction; | ||||
|         let half_extent = (self.half_length * direction).abs(); | ||||
|         let half_size = (self.half_length * direction).abs(); | ||||
| 
 | ||||
|         Aabb3d { | ||||
|             min: translation - half_extent, | ||||
|             max: translation + half_extent, | ||||
|         } | ||||
|         Aabb3d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_sphere(&self, translation: Vec3, _rotation: Quat) -> BoundingSphere { | ||||
| @ -112,7 +100,7 @@ impl Bounded3d for BoxedPolyline3d { | ||||
| 
 | ||||
| impl Bounded3d for Cuboid { | ||||
|     fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d { | ||||
|         // Compute the AABB of the rotated cuboid by transforming the half-extents
 | ||||
|         // Compute the AABB of the rotated cuboid by transforming the half-size
 | ||||
|         // by an absolute rotation matrix.
 | ||||
|         let rot_mat = Mat3::from_quat(rotation); | ||||
|         let abs_rot_mat = Mat3::from_cols( | ||||
| @ -122,10 +110,7 @@ impl Bounded3d for Cuboid { | ||||
|         ); | ||||
|         let half_size = abs_rot_mat * self.half_size; | ||||
| 
 | ||||
|         Aabb3d { | ||||
|             min: translation - half_size, | ||||
|             max: translation + half_size, | ||||
|         } | ||||
|         Aabb3d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_sphere(&self, translation: Vec3, _rotation: Quat) -> BoundingSphere { | ||||
| @ -147,11 +132,11 @@ impl Bounded3d for Cylinder { | ||||
|         let bottom = -top; | ||||
| 
 | ||||
|         let e = Vec3::ONE - segment_dir * segment_dir; | ||||
|         let half_extents = self.radius * Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt()); | ||||
|         let half_size = self.radius * Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt()); | ||||
| 
 | ||||
|         Aabb3d { | ||||
|             min: translation + (top - half_extents).min(bottom - half_extents), | ||||
|             max: translation + (top + half_extents).max(bottom + half_extents), | ||||
|             min: translation + (top - half_size).min(bottom - half_size), | ||||
|             max: translation + (top + half_size).max(bottom + half_size), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -305,15 +290,12 @@ impl Bounded3d for Torus { | ||||
|         // Reference: http://iquilezles.org/articles/diskbbox/
 | ||||
|         let normal = rotation * Vec3::Y; | ||||
|         let e = 1.0 - normal * normal; | ||||
|         let disc_half_extents = self.major_radius * Vec3::new(e.x.sqrt(), e.y.sqrt(), e.z.sqrt()); | ||||
|         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 extents
 | ||||
|         let half_extents = disc_half_extents + Vec3::splat(self.minor_radius); | ||||
|         // Expand the disc by the minor radius to get the torus half-size
 | ||||
|         let half_size = disc_half_size + Vec3::splat(self.minor_radius); | ||||
| 
 | ||||
|         Aabb3d { | ||||
|             min: translation - half_extents, | ||||
|             max: translation + half_extents, | ||||
|         } | ||||
|         Aabb3d::new(translation, half_size) | ||||
|     } | ||||
| 
 | ||||
|     fn bounding_sphere(&self, translation: Vec3, _rotation: Quat) -> BoundingSphere { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Joona Aalto
						Joona Aalto