use super::prelude::*;
use super::vec3;
use super::Vec3;
#[cfg(target_arch = "spirv")]
use num_traits::Float;
pub trait Vec3Ext {
#[must_use]
fn trunc(self) -> Self;
#[must_use]
fn step(self, value: Self) -> Self;
#[must_use]
fn step_select(self, value: Self, tru: Self, fals: Self) -> Self;
#[must_use]
fn fract(self) -> Self;
#[must_use]
fn saturate(self) -> Self;
#[must_use]
fn sqrt(self) -> Self;
#[must_use]
fn ln(self) -> Self;
#[must_use]
fn reflect(self, normal: Self) -> Self;
#[must_use]
fn mean(self) -> f32;
#[must_use]
fn has_equal_components(self, max_abs_diff: f32) -> bool;
}
impl Vec3Ext for Vec3 {
#[inline]
fn trunc(self) -> Self {
vec3(self.x.trunc(), self.y.trunc(), self.z.trunc())
}
fn step(self, value: Self) -> Self {
vec3(
self.x.step(value.x),
self.y.step(value.y),
self.z.step(value.z),
)
}
fn step_select(self, value: Self, less: Self, greater_or_equal: Self) -> Self {
vec3(
self.x.step_select(value.x, less.x, greater_or_equal.x),
self.y.step_select(value.y, less.y, greater_or_equal.y),
self.z.step_select(value.z, less.z, greater_or_equal.z),
)
}
fn fract(self) -> Self {
vec3(self.x.fract(), self.y.fract(), self.z.fract())
}
fn saturate(self) -> Self {
vec3(self.x.saturate(), self.y.saturate(), self.z.saturate())
}
fn sqrt(self) -> Self {
vec3(self.x.sqrt(), self.y.sqrt(), self.z.sqrt())
}
fn ln(self) -> Self {
vec3(self.x.ln(), self.y.ln(), self.z.ln())
}
fn reflect(self, normal: Self) -> Self {
self - 2.0 * normal * self.dot(normal)
}
fn mean(self) -> f32 {
(self.x + self.y + self.z) / 3.0
}
fn has_equal_components(self, max_abs_diff: f32) -> bool {
(self.x - self.y).abs() < max_abs_diff
&& (self.y - self.z).abs() < max_abs_diff
&& (self.x - self.z).abs() < max_abs_diff
}
}
pub trait CoordinateSystem {
fn up() -> Self;
fn down() -> Self;
fn right() -> Self;
fn left() -> Self;
fn forward() -> Self;
fn back() -> Self;
}
impl CoordinateSystem for Vec3 {
fn up() -> Self {
Self::new(0.0, 1.0, 0.0)
}
fn down() -> Self {
Self::new(0.0, -1.0, 0.0)
}
fn right() -> Self {
Self::new(1.0, 0.0, 0.0)
}
fn left() -> Self {
Self::new(-1.0, 0.0, 0.0)
}
fn forward() -> Self {
Self::new(0.0, 0.0, -1.0)
}
fn back() -> Self {
Self::new(0.0, 0.0, 1.0)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_mean() {
assert!((Vec3::ONE.mean() - 1.0).abs() < 0.0001);
}
#[test]
fn test_mean_2() {
assert!((vec3(1.0, 2.0, 3.0).mean() - 2.0).abs() < 0.0001);
}
#[test]
fn test_has_equal_components() {
assert!(Vec3::ONE.has_equal_components(0.001));
}
#[test]
fn test_has_equal_components_2() {
assert!(vec3(0.0, 0.00001, -0.00001).has_equal_components(0.001));
}
#[test]
fn test_has_equal_components_3() {
assert!(!vec3(1.0, 0.0, 0.0).has_equal_components(0.0001));
}
}