diff --git a/crates/bevy_math/src/primitives/dim2.rs b/crates/bevy_math/src/primitives/dim2.rs index 9cb379706c18b..8ad343c580e76 100644 --- a/crates/bevy_math/src/primitives/dim2.rs +++ b/crates/bevy_math/src/primitives/dim2.rs @@ -5,6 +5,7 @@ use thiserror::Error; use super::{Measured2d, Primitive2d, WindingOrder}; use crate::{ ops::{self, FloatPow}, + prelude::{ScaleNonUniform2d, ScaleUniform}, Dir2, InvalidDirectionError, Isometry2d, Ray2d, Rot2, Vec2, }; @@ -93,6 +94,22 @@ impl Measured2d for Circle { } } +impl ScaleUniform for Circle { + fn scale_uniform(&self, scale: f32) -> Self { + Self::new(scale * self.radius) + } +} + +impl ScaleNonUniform2d for Circle { + type Output = Ellipse; + + fn scale(&self, scale: Vec2) -> Self::Output { + Ellipse { + half_size: scale * self.radius, + } + } +} + /// A primitive representing an arc between two points on a circle. /// /// An arc has no area. @@ -1833,6 +1850,24 @@ impl Measured2d for Rectangle { } } +impl ScaleUniform for Rectangle { + fn scale_uniform(&self, scale: f32) -> Self { + Self { + half_size: scale * self.half_size, + } + } +} + +impl ScaleNonUniform2d for Rectangle { + type Output = Self; + + fn scale(&self, scale: Vec2) -> Self::Output { + Self { + half_size: scale * self.half_size, + } + } +} + /// A polygon with N vertices. /// /// For a version without generics: [`BoxedPolygon`] diff --git a/crates/bevy_math/src/primitives/dim3.rs b/crates/bevy_math/src/primitives/dim3.rs index 86aa6c5bdf068..c56089ae44330 100644 --- a/crates/bevy_math/src/primitives/dim3.rs +++ b/crates/bevy_math/src/primitives/dim3.rs @@ -3,6 +3,7 @@ use core::f32::consts::{FRAC_PI_3, PI}; use super::{Circle, Measured2d, Measured3d, Primitive2d, Primitive3d}; use crate::{ ops::{self, FloatPow}, + prelude::{ScaleNonUniform3d, ScaleUniform}, Dir3, InvalidDirectionError, Isometry3d, Mat3, Ray3d, Vec2, Vec3, }; @@ -88,6 +89,12 @@ impl Measured3d for Sphere { } } +impl ScaleUniform for Sphere { + fn scale_uniform(&self, scale: f32) -> Self { + Self::new(scale * self.radius) + } +} + /// A bounded plane in 3D space. It forms a surface starting from the origin with a defined height and width. #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] @@ -731,6 +738,24 @@ impl Measured3d for Cuboid { } } +impl ScaleUniform for Cuboid { + fn scale_uniform(&self, scale: f32) -> Self { + Self { + half_size: scale * self.half_size, + } + } +} + +impl ScaleNonUniform3d for Cuboid { + type Output = Self; + + fn scale(&self, scale: Vec3) -> Self::Output { + Self { + half_size: scale * self.half_size, + } + } +} + /// A cylinder primitive centered on the origin #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/bevy_math/src/primitives/mod.rs b/crates/bevy_math/src/primitives/mod.rs index b5c6644b13cc0..1fb2e409eed8e 100644 --- a/crates/bevy_math/src/primitives/mod.rs +++ b/crates/bevy_math/src/primitives/mod.rs @@ -6,6 +6,7 @@ mod dim2; pub use dim2::*; mod dim3; pub use dim3::*; +use glam::{Vec2, Vec3}; mod polygon; #[cfg(feature = "serialize")] mod serde; @@ -48,3 +49,29 @@ pub trait Measured3d { /// Get the volume of the shape fn volume(&self) -> f32; } + +/// A trait for uniformly scaling shapes +pub trait ScaleUniform { + /// Scale this primitive by the provided factor. + fn scale_uniform(&self, scale: f32) -> Self; +} + +/// A trait for scaling 2D shapes non-uniformly +pub trait ScaleNonUniform2d: ScaleUniform { + /// The type of the scaled primitive. + /// Most shapes will be the same when scaled but i.e. a [`Circle`] may become an [`Ellipse`] when scaled. + type Output; + + /// Scale the primitive along the X- and Y-axis + fn scale(&self, scale: Vec2) -> Self::Output; +} + +/// A trait for scaling 3D shapes non-uniformly +pub trait ScaleNonUniform3d: ScaleUniform { + /// The type of the scaled primitive. + /// Most shapes will be the same when scaled but i.e. a [`Sphere`] may become an `Ellipsoid` when scaled. + type Output; + + /// Scale the primitive along the X-, Y- and Z-axis + fn scale(&self, scale: Vec3) -> Self::Output; +}