}
}
+#[inline(always)]
+pub fn min(x: f32, y: f32) -> f32 {
+ if x < y {
+ x
+ } else {
+ y
+ }
+}
+
+#[inline(always)]
+pub fn max(x: f32, y: f32) -> f32 {
+ if x > y {
+ x
+ } else {
+ y
+ }
+}
+
+#[inline(always)]
+pub fn clamp(x: f32, lo: f32, hi: f32) -> f32 {
+ debug_assert!(lo <= hi);
+ max(min(x, hi), lo)
+}
+
#[macro_export]
macro_rules! impl_shared {
($name:ty, $t:ty, $n:expr) => {
unsafe { std::mem::transmute([value; $n]) }
}
+ #[inline]
+ pub fn min(a: Self, b: Self) -> Self {
+ a.map2(b, |a, b| crate::min(a, b))
+ }
+
+ #[inline]
+ pub fn max(a: Self, b: Self) -> Self {
+ a.map2(b, |a, b| crate::max(a, b))
+ }
+
+ #[inline]
+ pub fn clamp(x: Self, lo: Self, hi: Self) -> Self {
+ Self::max(Self::min(x, hi), lo)
+ }
+
#[inline(always)]
pub fn ceil(self) -> Self {
self.map(|x| x.ceil())
impl $name {
#[inline]
pub fn distance(a: Self, b: Self) -> $t {
- (a - b).length()
+ (b - a).length()
}
#[inline]
pub fn distance_sq(a: Self, b: Self) -> $t {
- (a - b).length_sq()
+ (b - a).length_sq()
}
}
};
y: f(self.y),
}
}
+
+ /// Returns a new point in 2d space with the function `f` applied to each pair of components from `self` and `rhs` in order.
+ #[inline(always)]
+ pub fn map2<F>(self, rhs: Self, mut f: F) -> Self
+ where
+ F: FnMut(f32, f32) -> f32,
+ {
+ Self {
+ x: f(self.x, rhs.x),
+ y: f(self.y, rhs.y),
+ }
+ }
}
impl std::ops::Sub for Point2 {
z: f(self.z),
}
}
+
+ /// Returns a new point in 3d space with the function `f` applied to each pair of components from `self` and `rhs` in order.
+ #[inline(always)]
+ pub fn map2<F>(self, rhs: Self, mut f: F) -> Self
+ where
+ F: FnMut(f32, f32) -> f32,
+ {
+ Self {
+ x: f(self.x, rhs.x),
+ y: f(self.y, rhs.y),
+ z: f(self.z, rhs.z),
+ }
+ }
}
impl std::ops::Sub for Point3 {
}
}
+ /// Returns a new 2d vector with the function `f` applied to each pair of components from `self` and `rhs` in order.
+ #[inline(always)]
+ pub fn map2<F>(self, rhs: Self, mut f: F) -> Self
+ where
+ F: FnMut(f32, f32) -> f32,
+ {
+ Self {
+ x: f(self.x, rhs.x),
+ y: f(self.y, rhs.y),
+ }
+ }
+
#[inline]
pub fn dot(a: Self, b: Self) -> f32 {
a.x * b.x + a.y * b.y
}
}
+ /// Returns a new 3d vector with the function `f` applied to each pair of components from `self` and `rhs` in order.
+ #[inline(always)]
+ pub fn map2<F>(self, rhs: Self, mut f: F) -> Self
+ where
+ F: FnMut(f32, f32) -> f32,
+ {
+ Self {
+ x: f(self.x, rhs.x),
+ y: f(self.y, rhs.y),
+ z: f(self.z, rhs.z),
+ }
+ }
+
#[inline]
pub fn dot(a: Self, b: Self) -> f32 {
a.x * b.x + a.y * b.y + a.z * b.z
}
}
+ /// Returns a new 3d vector with the function `f` applied to each pair of components from `self` and `rhs` in order.
+ #[inline(always)]
+ pub fn map2<F>(self, rhs: Self, mut f: F) -> Self
+ where
+ F: FnMut(f32, f32) -> f32,
+ {
+ Self {
+ x: f(self.x, rhs.x),
+ y: f(self.y, rhs.y),
+ z: f(self.z, rhs.z),
+ w: f(self.w, rhs.w),
+ }
+ }
+
#[inline]
pub fn dot(a: Self, b: Self) -> f32 {
a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
assert_eq!(Vec4::new(2.0, 2.0, 2.0, 2.0).length_sq(), 16.0);
assert_eq!(Vec4::new(2.0, 2.0, 2.0, 2.0).length(), 4.0);
+
+ assert_eq!(
+ Vec4::clamp(Vec4::ONE * 5.0, Vec4::ZERO, Vec4::ONE),
+ Vec4::ONE
+ );
}
}