diff --git a/_release-content/migration-guides/Bounded2d-and-Bounded3d-signature-change.md b/_release-content/migration-guides/Bounded2d-and-Bounded3d-signature-change.md new file mode 100644 index 0000000000000..db4eb3fa310b4 --- /dev/null +++ b/_release-content/migration-guides/Bounded2d-and-Bounded3d-signature-change.md @@ -0,0 +1,22 @@ +--- +title: Bounded2d and Bounded3d signature change +pull_requests: [23623] +--- + +The signature of `Bounded2d` and `Bounded3d` has changed. All methods now +accept `Isometry2d` and `Isometry3d` objects, rather than `impl Into` +type argument. + +The new signatures allow `Bounded2d` and `Bounded3d` to be dyn-compatible. + +When calling `Bounded2d::aabb_2d`, `Bounded2d::bounding_circle`, +`Bounded3d::aabb_3d`, and `Bounded3d::bounding_sphere`, you may need to call +`into()` on the object sent to the function. e.g., + +```diff +- let aabb2d = self.aabb_2d(Rot2::radians(angle)); ++ let aabb2d = self.aabb_2d(Rot2::radians(angle).into()); +``` + +When implementing these traits for an object, you will need to update the signature. +You may also be able to remove `let isometry = isometry.into();` lines. diff --git a/crates/bevy_math/src/bounding/bounded2d/mod.rs b/crates/bevy_math/src/bounding/bounded2d/mod.rs index 79def679f9ad3..fd99c64dd7f38 100644 --- a/crates/bevy_math/src/bounding/bounded2d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded2d/mod.rs @@ -29,9 +29,9 @@ fn point_cloud_2d_center(points: &[Vec2]) -> Vec2 { /// A trait with methods that return 2D bounding volumes for a shape. pub trait Bounded2d { /// Get an axis-aligned bounding box for the shape translated and rotated by the given isometry. - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d; + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d; /// Get a bounding circle for the shape translated and rotated by the given isometry. - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle; + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle; } /// A 2D axis-aligned bounding box, or bounding rectangle diff --git a/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs b/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs index 8e45e645bfeb5..c97386a6fd47e 100644 --- a/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs +++ b/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs @@ -19,13 +19,11 @@ use arrayvec::ArrayVec; use super::{Aabb2d, Bounded2d, BoundingCircle}; impl Bounded2d for Circle { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { Aabb2d::new(isometry.translation, Vec2::splat(self.radius)) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, self.radius) } } @@ -65,23 +63,19 @@ fn arc_bounding_points(arc: Arc2d, rotation: impl Into) -> ArrayVec) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { // If our arc covers more than a circle, just return the bounding box of the circle. if self.half_angle >= PI { return Circle::new(self.radius).aabb_2d(isometry); } - let isometry = isometry.into(); - Aabb2d::from_point_cloud( Isometry2d::from_translation(isometry.translation), &arc_bounding_points(*self, isometry.rotation), ) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); - + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { // There are two possibilities for the bounding circle. if self.is_major() { // If the arc is major, then the widest distance between two points is a diameter of the arc's circle; @@ -97,9 +91,7 @@ impl Bounded2d for Arc2d { } impl Bounded2d for CircularSector { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { // If our sector covers more than a circle, just return the bounding box of the circle. if self.half_angle() >= PI { return Circle::new(self.radius()).aabb_2d(isometry); @@ -112,10 +104,8 @@ impl Bounded2d for CircularSector { Aabb2d::from_point_cloud(Isometry2d::from_translation(isometry.translation), &bounds) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { if self.arc.is_major() { - let isometry = isometry.into(); - // If the arc is major, that is, greater than a semicircle, // then bounding circle is just the circle defining the sector. BoundingCircle::new(isometry.translation, self.arc.radius) @@ -136,19 +126,17 @@ impl Bounded2d for CircularSector { } impl Bounded2d for CircularSegment { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { self.arc.aabb_2d(isometry) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { self.arc.bounding_circle(isometry) } } impl Bounded2d for Ellipse { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { // V = (hh * cos(beta), hh * sin(beta)) // #####*##### // ### | ### @@ -177,28 +165,23 @@ impl Bounded2d for Ellipse { Aabb2d::new(isometry.translation, half_size) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, self.semi_major()) } } impl Bounded2d for Annulus { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { Aabb2d::new(isometry.translation, Vec2::splat(self.outer_circle.radius)) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, self.outer_circle.radius) } } impl Bounded2d for Rhombus { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { let [rotated_x_half_diagonal, rotated_y_half_diagonal] = [ isometry.rotation * Vec2::new(self.half_diagonals.x, 0.0), isometry.rotation * Vec2::new(0.0, self.half_diagonals.y), @@ -213,16 +196,13 @@ impl Bounded2d for Rhombus { } } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, self.circumradius()) } } impl Bounded2d for Plane2d { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { let normal = isometry.rotation * *self.normal; let facing_x = normal == Vec2::X || normal == Vec2::NEG_X; let facing_y = normal == Vec2::Y || normal == Vec2::NEG_Y; @@ -236,16 +216,13 @@ impl Bounded2d for Plane2d { Aabb2d::new(isometry.translation, half_size) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, f32::MAX / 2.0) } } impl Bounded2d for Line2d { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { let direction = isometry.rotation * *self.direction; // Dividing `f32::MAX` by 2.0 is helpful so that we can do operations @@ -258,19 +235,17 @@ impl Bounded2d for Line2d { Aabb2d::new(isometry.translation, half_size) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, f32::MAX / 2.0) } } impl Bounded2d for Segment2d { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { Aabb2d::from_point_cloud(isometry, &[self.point1(), self.point2()]) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry: Isometry2d = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { let local_center = self.center(); let radius = local_center.distance(self.point1()); let local_circle = BoundingCircle::new(local_center, radius); @@ -280,18 +255,17 @@ impl Bounded2d for Segment2d { #[cfg(feature = "alloc")] impl Bounded2d for Polyline2d { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { Aabb2d::from_point_cloud(isometry, &self.vertices) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::from_point_cloud(isometry, &self.vertices) } } impl Bounded2d for Triangle2d { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { let [a, b, c] = self.vertices.map(|vtx| isometry.rotation * vtx); let min = Vec2::new(a.x.min(b.x).min(c.x), a.y.min(b.y).min(c.y)); @@ -303,8 +277,7 @@ impl Bounded2d for Triangle2d { } } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { let [a, b, c] = self.vertices; // The points of the segment opposite to the obtuse or right angle if one exists @@ -335,9 +308,7 @@ impl Bounded2d for Triangle2d { } impl Bounded2d for Rectangle { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { // Compute the AABB of the rotated rectangle by transforming the half-extents // by an absolute rotation matrix. let (sin, cos) = isometry.rotation.sin_cos(); @@ -348,8 +319,7 @@ impl Bounded2d for Rectangle { Aabb2d::new(isometry.translation, half_size) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { let radius = self.half_size.length(); BoundingCircle::new(isometry.translation, radius) } @@ -357,30 +327,28 @@ impl Bounded2d for Rectangle { #[cfg(feature = "alloc")] impl Bounded2d for Polygon { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { Aabb2d::from_point_cloud(isometry, &self.vertices) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::from_point_cloud(isometry, &self.vertices) } } #[cfg(feature = "alloc")] impl Bounded2d for ConvexPolygon { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { Aabb2d::from_point_cloud(isometry, self.vertices()) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::from_point_cloud(isometry, self.vertices()) } } impl Bounded2d for RegularPolygon { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { let mut min = Vec2::ZERO; let mut max = Vec2::ZERO; @@ -395,16 +363,13 @@ impl Bounded2d for RegularPolygon { } } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, self.circumcircle.radius) } } impl Bounded2d for Capsule2d { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { // Get the line segment between the semicircles of the rotated capsule let segment = Segment2d::from_direction_and_length( isometry.rotation * Dir2::Y, @@ -422,18 +387,17 @@ impl Bounded2d for Capsule2d { } } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { BoundingCircle::new(isometry.translation, self.radius + self.half_length) } } impl Bounded2d for Ring

{ - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { self.outer_shape.aabb_2d(isometry) } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { self.outer_shape.bounding_circle(isometry) } } diff --git a/crates/bevy_math/src/bounding/bounded3d/extrusion.rs b/crates/bevy_math/src/bounding/bounded3d/extrusion.rs index e37783576caac..1dbcb01d8e26e 100644 --- a/crates/bevy_math/src/bounding/bounded3d/extrusion.rs +++ b/crates/bevy_math/src/bounding/bounded3d/extrusion.rs @@ -122,7 +122,7 @@ impl BoundedExtrusion for Rectangle { Cuboid { half_size: self.half_size.extend(half_depth), } - .aabb_3d(isometry) + .aabb_3d(isometry.into()) } } @@ -157,7 +157,7 @@ impl BoundedExtrusion for Capsule2d { half_height: half_depth, radius: self.radius, } - .aabb_3d(isometry.rotation * Quat::from_rotation_x(FRAC_PI_2)); + .aabb_3d((isometry.rotation * Quat::from_rotation_x(FRAC_PI_2)).into()); let up = isometry.rotation * Vec3A::new(0., self.half_length, 0.); let half_size = aabb.max + up.abs(); @@ -181,11 +181,11 @@ impl BoundedExtrusion for Ring { } impl Bounded3d for Extrusion { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { self.base_shape.extrusion_aabb_3d(self.half_depth, isometry) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { self.base_shape .extrusion_bounding_sphere(self.half_depth, isometry) } @@ -222,7 +222,7 @@ pub trait BoundedExtrusion: Primitive2d + Bounded2d { // Calculate the `Aabb2d` of the base shape. The shape is rotated so that the line of intersection is parallel to the Y axis in the `Aabb2d` calculations. // This guarantees that the X value of the `Aabb2d` is closest to the `ax` plane - let aabb2d = self.aabb_2d(Rot2::radians(angle)); + let aabb2d = self.aabb_2d(Rot2::radians(angle).into()); (aabb2d.half_size().x * scale, aabb2d.center().x * scale) }); @@ -277,11 +277,11 @@ mod tests { let cylinder = Extrusion::new(Circle::new(0.5), 2.0); let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = cylinder.aabb_3d(translation); + let aabb = cylinder.aabb_3d(translation.into()); assert_eq!(aabb.center(), Vec3A::from(translation)); assert_eq!(aabb.half_size(), Vec3A::new(0.5, 0.5, 1.0)); - let bounding_sphere = cylinder.bounding_sphere(translation); + let bounding_sphere = cylinder.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), ops::hypot(1.0, 0.5)); } diff --git a/crates/bevy_math/src/bounding/bounded3d/mod.rs b/crates/bevy_math/src/bounding/bounded3d/mod.rs index cbfdb1d4f3909..384ae68e9f82a 100644 --- a/crates/bevy_math/src/bounding/bounded3d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded3d/mod.rs @@ -36,9 +36,9 @@ fn point_cloud_3d_center(points: impl Iterator>) -> Vec3 /// A trait with methods that return 3D bounding volumes for a shape. pub trait Bounded3d { /// Get an axis-aligned bounding box for the shape translated and rotated by the given isometry. - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d; + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d; /// Get a bounding sphere for the shape translated and rotated by the given isometry. - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere; + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere; } /// A 3D axis-aligned bounding box diff --git a/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs b/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs index 7cf118e4d97e8..0a63a153908f8 100644 --- a/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs +++ b/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs @@ -16,21 +16,17 @@ use crate::primitives::Polyline3d; use super::{Aabb3d, Bounded3d, BoundingSphere}; impl Bounded3d for Sphere { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { Aabb3d::new(isometry.translation, Vec3::splat(self.radius)) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::new(isometry.translation, self.radius) } } impl Bounded3d for InfinitePlane3d { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); - + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { let normal = isometry.rotation * *self.normal; let facing_x = normal == Vec3::X || normal == Vec3::NEG_X; let facing_y = normal == Vec3::Y || normal == Vec3::NEG_Y; @@ -46,15 +42,13 @@ impl Bounded3d for InfinitePlane3d { Aabb3d::new(isometry.translation, half_size) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::new(isometry.translation, f32::MAX / 2.0) } } impl Bounded3d for Line3d { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { let direction = isometry.rotation * *self.direction; // Dividing `f32::MAX` by 2.0 is helpful so that we can do operations @@ -68,19 +62,17 @@ impl Bounded3d for Line3d { Aabb3d::new(isometry.translation, half_size) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::new(isometry.translation, f32::MAX / 2.0) } } impl Bounded3d for Segment3d { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { Aabb3d::from_point_cloud(isometry, [self.point1(), self.point2()].iter().copied()) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { let local_sphere = BoundingSphere::new(self.center(), self.length() / 2.); local_sphere.transformed_by(isometry.translation, isometry.rotation) } @@ -88,19 +80,17 @@ impl Bounded3d for Segment3d { #[cfg(feature = "alloc")] impl Bounded3d for Polyline3d { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { Aabb3d::from_point_cloud(isometry, self.vertices.iter().copied()) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::from_point_cloud(isometry, &self.vertices) } } impl Bounded3d for Cuboid { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); - + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { // Compute the AABB of the rotated cuboid by transforming the half-size // by an absolute rotation matrix. let rot_mat = Mat3::from_quat(isometry.rotation); @@ -114,18 +104,15 @@ impl Bounded3d for Cuboid { Aabb3d::new(isometry.translation, half_size) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::new(isometry.translation, self.half_size.length()) } } impl Bounded3d for Cylinder { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { // Reference: http://iquilezles.org/articles/diskbbox/ - let isometry = isometry.into(); - let segment_dir = isometry.rotation * Vec3A::Y; let top = segment_dir * self.half_height; let bottom = -top; @@ -139,17 +126,14 @@ impl Bounded3d for Cylinder { } } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { let radius = ops::hypot(self.radius, self.half_height); BoundingSphere::new(isometry.translation, radius) } } impl Bounded3d for Capsule3d { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); - + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { // Get the line segment between the hemispheres of the rotated capsule let segment_dir = isometry.rotation * Vec3A::Y; let top = segment_dir * self.half_length; @@ -165,18 +149,15 @@ impl Bounded3d for Capsule3d { } } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::new(isometry.translation, self.radius + self.half_length) } } impl Bounded3d for Cone { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { // Reference: http://iquilezles.org/articles/diskbbox/ - let isometry = isometry.into(); - let segment_dir = isometry.rotation * Vec3A::Y; let top = segment_dir * 0.5 * self.height; let bottom = -top; @@ -190,9 +171,7 @@ impl Bounded3d for Cone { } } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); - + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { // Get the triangular cross-section of the cone. let half_height = 0.5 * self.height; let triangle = Triangle2d::new( @@ -213,11 +192,9 @@ impl Bounded3d for Cone { } impl Bounded3d for ConicalFrustum { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { // Reference: http://iquilezles.org/articles/diskbbox/ - let isometry = isometry.into(); - let segment_dir = isometry.rotation * Vec3A::Y; let top = segment_dir * 0.5 * self.height; let bottom = -top; @@ -235,8 +212,7 @@ impl Bounded3d for ConicalFrustum { } } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { let half_height = 0.5 * self.height; // To compute the bounding sphere, we'll get the center and radius of the circumcircle @@ -299,9 +275,7 @@ impl Bounded3d for ConicalFrustum { } impl Bounded3d for Torus { - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); - + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { // Compute the AABB of a flat disc with the major radius of the torus. // Reference: http://iquilezles.org/articles/diskbbox/ let normal = isometry.rotation * Vec3A::Y; @@ -315,16 +289,14 @@ impl Bounded3d for Torus { Aabb3d::new(isometry.translation, half_size) } - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { BoundingSphere::new(isometry.translation, self.outer_radius()) } } impl Bounded3d for Triangle3d { /// Get the bounding box of the triangle. - fn aabb_3d(&self, isometry: impl Into) -> Aabb3d { - let isometry = isometry.into(); + fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d { let [a, b, c] = self.vertices; let a = isometry.rotation * a; @@ -345,9 +317,7 @@ impl Bounded3d for Triangle3d { /// The [`Triangle3d`] implements the minimal bounding sphere calculation. For acute triangles, the circumcenter is used as /// the center of the sphere. For the others, the bounding sphere is the minimal sphere /// that contains the largest side of the triangle. - fn bounding_sphere(&self, isometry: impl Into) -> BoundingSphere { - let isometry = isometry.into(); - + fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere { if self.is_degenerate() || self.is_obtuse() { let (p1, p2) = self.largest_side(); let (p1, p2) = (Vec3A::from(p1), Vec3A::from(p2)); @@ -383,11 +353,11 @@ mod tests { let sphere = Sphere { radius: 1.0 }; let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = sphere.aabb_3d(translation); + let aabb = sphere.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(1.0, 0.0, -1.0)); assert_eq!(aabb.max, Vec3A::new(3.0, 2.0, 1.0)); - let bounding_sphere = sphere.bounding_sphere(translation); + let bounding_sphere = sphere.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), 1.0); } @@ -396,23 +366,23 @@ mod tests { fn plane() { let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb1 = InfinitePlane3d::new(Vec3::X).aabb_3d(translation); + let aabb1 = InfinitePlane3d::new(Vec3::X).aabb_3d(translation.into()); assert_eq!(aabb1.min, Vec3A::new(2.0, -f32::MAX / 2.0, -f32::MAX / 2.0)); assert_eq!(aabb1.max, Vec3A::new(2.0, f32::MAX / 2.0, f32::MAX / 2.0)); - let aabb2 = InfinitePlane3d::new(Vec3::Y).aabb_3d(translation); + let aabb2 = InfinitePlane3d::new(Vec3::Y).aabb_3d(translation.into()); assert_eq!(aabb2.min, Vec3A::new(-f32::MAX / 2.0, 1.0, -f32::MAX / 2.0)); assert_eq!(aabb2.max, Vec3A::new(f32::MAX / 2.0, 1.0, f32::MAX / 2.0)); - let aabb3 = InfinitePlane3d::new(Vec3::Z).aabb_3d(translation); + let aabb3 = InfinitePlane3d::new(Vec3::Z).aabb_3d(translation.into()); assert_eq!(aabb3.min, Vec3A::new(-f32::MAX / 2.0, -f32::MAX / 2.0, 0.0)); assert_eq!(aabb3.max, Vec3A::new(f32::MAX / 2.0, f32::MAX / 2.0, 0.0)); - let aabb4 = InfinitePlane3d::new(Vec3::ONE).aabb_3d(translation); + let aabb4 = InfinitePlane3d::new(Vec3::ONE).aabb_3d(translation.into()); assert_eq!(aabb4.min, Vec3A::splat(-f32::MAX / 2.0)); assert_eq!(aabb4.max, Vec3A::splat(f32::MAX / 2.0)); - let bounding_sphere = InfinitePlane3d::new(Vec3::Y).bounding_sphere(translation); + let bounding_sphere = InfinitePlane3d::new(Vec3::Y).bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), f32::MAX / 2.0); } @@ -421,26 +391,26 @@ mod tests { fn line() { let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb1 = Line3d { direction: Dir3::Y }.aabb_3d(translation); + let aabb1 = Line3d { direction: Dir3::Y }.aabb_3d(translation.into()); assert_eq!(aabb1.min, Vec3A::new(2.0, -f32::MAX / 2.0, 0.0)); assert_eq!(aabb1.max, Vec3A::new(2.0, f32::MAX / 2.0, 0.0)); - let aabb2 = Line3d { direction: Dir3::X }.aabb_3d(translation); + let aabb2 = Line3d { direction: Dir3::X }.aabb_3d(translation.into()); assert_eq!(aabb2.min, Vec3A::new(-f32::MAX / 2.0, 1.0, 0.0)); assert_eq!(aabb2.max, Vec3A::new(f32::MAX / 2.0, 1.0, 0.0)); - let aabb3 = Line3d { direction: Dir3::Z }.aabb_3d(translation); + let aabb3 = Line3d { direction: Dir3::Z }.aabb_3d(translation.into()); assert_eq!(aabb3.min, Vec3A::new(2.0, 1.0, -f32::MAX / 2.0)); assert_eq!(aabb3.max, Vec3A::new(2.0, 1.0, f32::MAX / 2.0)); let aabb4 = Line3d { direction: Dir3::from_xyz(1.0, 1.0, 1.0).unwrap(), } - .aabb_3d(translation); + .aabb_3d(translation.into()); assert_eq!(aabb4.min, Vec3A::splat(-f32::MAX / 2.0)); assert_eq!(aabb4.max, Vec3A::splat(f32::MAX / 2.0)); - let bounding_sphere = Line3d { direction: Dir3::Y }.bounding_sphere(translation); + let bounding_sphere = Line3d { direction: Dir3::Y }.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), f32::MAX / 2.0); } @@ -450,11 +420,11 @@ mod tests { let segment = Segment3d::new(Vec3::new(-1.0, -0.5, 0.0), Vec3::new(1.0, 0.5, 0.0)); let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = segment.aabb_3d(translation); + let aabb = segment.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(1.0, 0.5, 0.0)); assert_eq!(aabb.max, Vec3A::new(3.0, 1.5, 0.0)); - let bounding_sphere = segment.bounding_sphere(translation); + let bounding_sphere = segment.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), ops::hypot(1.0, 0.5)); } @@ -469,11 +439,11 @@ mod tests { ]); let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = polyline.aabb_3d(translation); + let aabb = polyline.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(1.0, 0.0, -1.0)); assert_eq!(aabb.max, Vec3A::new(3.0, 2.0, 1.0)); - let bounding_sphere = polyline.bounding_sphere(translation); + let bounding_sphere = polyline.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!( bounding_sphere.radius(), @@ -494,7 +464,7 @@ mod tests { assert_eq!(aabb.min, Vec3A::from(translation) - expected_half_size); assert_eq!(aabb.max, Vec3A::from(translation) + expected_half_size); - let bounding_sphere = cuboid.bounding_sphere(translation); + let bounding_sphere = cuboid.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!( bounding_sphere.radius(), @@ -507,7 +477,7 @@ mod tests { let cylinder = Cylinder::new(0.5, 2.0); let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = cylinder.aabb_3d(translation); + let aabb = cylinder.aabb_3d(translation.into()); assert_eq!( aabb.min, Vec3A::from(translation) - Vec3A::new(0.5, 1.0, 0.5) @@ -517,7 +487,7 @@ mod tests { Vec3A::from(translation) + Vec3A::new(0.5, 1.0, 0.5) ); - let bounding_sphere = cylinder.bounding_sphere(translation); + let bounding_sphere = cylinder.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), ops::hypot(1.0, 0.5)); } @@ -527,7 +497,7 @@ mod tests { let capsule = Capsule3d::new(0.5, 2.0); let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = capsule.aabb_3d(translation); + let aabb = capsule.aabb_3d(translation.into()); assert_eq!( aabb.min, Vec3A::from(translation) - Vec3A::new(0.5, 1.5, 0.5) @@ -537,7 +507,7 @@ mod tests { Vec3A::from(translation) + Vec3A::new(0.5, 1.5, 0.5) ); - let bounding_sphere = capsule.bounding_sphere(translation); + let bounding_sphere = capsule.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), 1.5); } @@ -550,11 +520,11 @@ mod tests { }; let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = cone.aabb_3d(translation); + let aabb = cone.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(1.0, 0.0, -1.0)); assert_eq!(aabb.max, Vec3A::new(3.0, 2.0, 1.0)); - let bounding_sphere = cone.bounding_sphere(translation); + let bounding_sphere = cone.bounding_sphere(translation.into()); assert_eq!( bounding_sphere.center, Vec3A::from(translation) + Vec3A::NEG_Y * 0.25 @@ -571,11 +541,11 @@ mod tests { }; let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = conical_frustum.aabb_3d(translation); + let aabb = conical_frustum.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(1.0, 0.0, -1.0)); assert_eq!(aabb.max, Vec3A::new(3.0, 2.0, 1.0)); - let bounding_sphere = conical_frustum.bounding_sphere(translation); + let bounding_sphere = conical_frustum.bounding_sphere(translation.into()); assert_eq!( bounding_sphere.center, Vec3A::from(translation) + Vec3A::NEG_Y * 0.1875 @@ -592,13 +562,13 @@ mod tests { }; let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = conical_frustum.aabb_3d(translation); + let aabb = conical_frustum.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(-3.0, 0.5, -5.0)); assert_eq!(aabb.max, Vec3A::new(7.0, 1.5, 5.0)); // For wide conical frusta like this, the circumcenter can be outside the frustum, // so the center and radius should be clamped to the longest side. - let bounding_sphere = conical_frustum.bounding_sphere(translation); + let bounding_sphere = conical_frustum.bounding_sphere(translation.into()); assert_eq!( bounding_sphere.center, Vec3A::from(translation) + Vec3A::NEG_Y * 0.5 @@ -614,11 +584,11 @@ mod tests { }; let translation = Vec3::new(2.0, 1.0, 0.0); - let aabb = torus.aabb_3d(translation); + let aabb = torus.aabb_3d(translation.into()); assert_eq!(aabb.min, Vec3A::new(0.5, 0.5, -1.5)); assert_eq!(aabb.max, Vec3A::new(3.5, 1.5, 1.5)); - let bounding_sphere = torus.bounding_sphere(translation); + let bounding_sphere = torus.bounding_sphere(translation.into()); assert_eq!(bounding_sphere.center, translation.into()); assert_eq!(bounding_sphere.radius(), 1.5); } diff --git a/examples/math/custom_primitives.rs b/examples/math/custom_primitives.rs index 5db89f0be85f5..47b3e317308f8 100644 --- a/examples/math/custom_primitives.rs +++ b/examples/math/custom_primitives.rs @@ -432,9 +432,7 @@ impl Measured2d for Heart { // The `Bounded2d` or `Bounded3d` traits are used to compute the Axis Aligned Bounding Boxes or bounding circles / spheres for primitives. impl Bounded2d for Heart { - fn aabb_2d(&self, isometry: impl Into) -> Aabb2d { - let isometry = isometry.into(); - + fn aabb_2d(&self, isometry: Isometry2d) -> Aabb2d { // The center of the circle at the center of the right wing of the heart let circle_center = isometry.rotation * Vec2::new(self.radius, 0.0); // The maximum X and Y positions of the two circles of the wings of the heart. @@ -451,9 +449,7 @@ impl Bounded2d for Heart { } } - fn bounding_circle(&self, isometry: impl Into) -> BoundingCircle { - let isometry = isometry.into(); - + fn bounding_circle(&self, isometry: Isometry2d) -> BoundingCircle { // The bounding circle of the heart is not at its origin. This `offset` is the offset between the center of the bounding circle and its translation. let offset = self.radius / ops::powf(2f32, 1.5); // The center of the bounding circle