use glam::{Vec2, Vec3, Vec3A};
pub trait Vector<const N: usize>: Sized + Copy + Clone {
fn get(&self, i: usize) -> f32;
fn set(&mut self, i: usize, v: f32);
fn add_self(&self, other: &Self) -> Self;
fn sub_self(&self, other: &Self) -> Self;
fn div_self(&self, other: &Self) -> Self;
fn mul_self(&self, other: &Self) -> Self;
fn scale(&self, s: f32) -> Self;
fn less_than(&self, other: &Self) -> bool;
fn greater_than(&self, other: &Self) -> bool;
fn cmin(&self, other: Self) -> Self;
fn cmax(&self, other: Self) -> Self;
fn mid_point(&self, other: Self) -> Self;
fn dot_self(&self, other: &Self) -> f32;
fn cprod(&self) -> f32;
fn cmap<F: Fn(f32) -> f32>(&self, f: F) -> Self;
fn cmap_mut<F: FnMut(f32) -> f32>(&self, f: F) -> Self;
fn min_elem(&self) -> f32;
fn max_elem(&self) -> f32;
fn to_arr(&self) -> [f32; N];
fn from_arr(a: [f32; N]) -> Self;
fn normalized(&self) -> Self;
fn mag(&self) -> f32;
}
#[macro_export]
macro_rules! impl_vector_glam_vec3 {
($a: ident) => {
impl Vector<3> for $a {
fn add_self(&self, other: &Self) -> Self {
self + other
}
fn sub_self(&self, other: &Self) -> Self {
self - other
}
fn dot_self(&self, other: &Self) -> f32 {
self.dot(*other)
}
fn mul_self(&self, other: &Self) -> Self {
self * other
}
fn div_self(&self, other: &Self) -> Self {
self / other
}
fn scale(&self, s: f32) -> Self {
self * s
}
fn less_than(&self, other: &Self) -> bool {
self.x < other.x && self.y < other.y
}
fn greater_than(&self, other: &Self) -> bool {
!self.less_than(other)
}
fn cmin(&self, other: Self) -> Self {
self.min(other)
}
fn cmax(&self, other: Self) -> Self {
self.max(other)
}
fn mid_point(&self, other: Self) -> Self {
self.midpoint(other)
}
fn cprod(&self) -> f32 {
self.x * self.y
}
fn cmap<F: Fn(f32) -> f32>(&self, f: F) -> Self {
self.map(f)
}
fn cmap_mut<F: FnMut(f32) -> f32>(&self, mut f: F) -> Self {
Self::new(f(self.x), f(self.y), f(self.z))
}
fn min_elem(&self) -> f32 {
self.min_element()
}
fn max_elem(&self) -> f32 {
self.max_element()
}
fn to_arr(&self) -> [f32; 3] {
self.to_array()
}
fn from_arr(a: [f32; 3]) -> Self {
a.into()
}
fn normalized(&self) -> Self {
self.normalize_or_zero()
}
fn get(&self, i: usize) -> f32 {
match i {
0 => self.x,
1 => self.y,
2 => self.z,
_ => panic!(),
}
}
fn set(&mut self, i: usize, v: f32) {
match i {
0 => self.x = v,
1 => self.y = v,
2 => self.z = v,
_ => panic!(),
}
}
fn mag(&self) -> f32 {
self.length()
}
}
};
}
#[macro_export]
macro_rules! impl_vector_glam_vec2 {
($a: ident) => {
impl Vector<2> for $a {
fn add_self(&self, other: &Self) -> Self {
self + other
}
fn sub_self(&self, other: &Self) -> Self {
self - other
}
fn mul_self(&self, other: &Self) -> Self {
self * other
}
fn div_self(&self, other: &Self) -> Self {
self / other
}
fn dot_self(&self, other: &Self) -> f32 {
self.dot(*other)
}
fn scale(&self, s: f32) -> Self {
self * s
}
fn less_than(&self, other: &Self) -> bool {
self.x < other.x && self.y < other.y
}
fn greater_than(&self, other: &Self) -> bool {
!self.less_than(other)
}
fn cmin(&self, other: Self) -> Self {
self.min(other)
}
fn cmax(&self, other: Self) -> Self {
self.max(other)
}
fn mid_point(&self, other: Self) -> Self {
self.midpoint(other)
}
fn cprod(&self) -> f32 {
self.x * self.y
}
fn cmap<F: Fn(f32) -> f32>(&self, f: F) -> Self {
self.map(f)
}
fn cmap_mut<F: FnMut(f32) -> f32>(&self, mut f: F) -> Self {
Self::new(f(self.x), f(self.y))
}
fn min_elem(&self) -> f32 {
self.min_element()
}
fn max_elem(&self) -> f32 {
self.max_element()
}
fn to_arr(&self) -> [f32; 2] {
self.to_array()
}
fn from_arr(a: [f32; 2]) -> Self {
a.into()
}
fn normalized(&self) -> Self {
self.normalize_or_zero()
}
fn get(&self, i: usize) -> f32 {
match i {
0 => self.x,
1 => self.y,
_ => panic!(),
}
}
fn set(&mut self, i: usize, v: f32) {
match i {
0 => self.x = v,
1 => self.y = v,
_ => panic!(),
}
}
fn mag(&self) -> f32 {
self.length()
}
}
};
}
impl_vector_glam_vec2!(Vec2);
impl_vector_glam_vec3!(Vec3);
impl_vector_glam_vec3!(Vec3A);
impl<const N: usize> Vector<N> for [f32; N] {
fn add_self(&self, other: &Self) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i] + other[i];
}
res
}
fn sub_self(&self, other: &Self) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i] - other[i];
}
res
}
fn mul_self(&self, other: &Self) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i] * other[i];
}
res
}
fn div_self(&self, other: &Self) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i] / other[i];
}
res
}
fn dot_self(&self, other: &Self) -> f32 {
self.mul_self(other).iter().sum::<f32>()
}
fn scale(&self, s: f32) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i] * s;
}
res
}
fn less_than(&self, other: &Self) -> bool {
for i in 0..N {
if self[i] > other[i] {
return false;
}
}
return true;
}
fn greater_than(&self, other: &Self) -> bool {
!self.less_than(other)
}
fn cmin(&self, other: Self) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i].min(other[i]);
}
res
}
fn cmax(&self, other: Self) -> Self {
let mut res = [0.0; N];
for i in 0..N {
res[i] = self[i].max(other[i]);
}
res
}
fn mid_point(&self, other: Self) -> Self {
self.add_self(&other).scale(0.5)
}
fn cprod(&self) -> f32 {
self.iter().product()
}
fn cmap<F: Fn(f32) -> f32>(&self, f: F) -> Self {
let mut result = [0.0; N];
for i in 0..N {
result[i] = f(self[i]);
}
result
}
fn cmap_mut<F: FnMut(f32) -> f32>(&self, mut f: F) -> Self {
let mut result = [0.0; N];
for i in 0..N {
result[i] = f(self[i]);
}
result
}
fn min_elem(&self) -> f32 {
*self.iter().min_by(|a, b| a.total_cmp(&b)).unwrap()
}
fn max_elem(&self) -> f32 {
*self.iter().max_by(|a, b| a.total_cmp(&b)).unwrap()
}
fn to_arr(&self) -> [f32; N] {
*self
}
fn from_arr(a: [f32; N]) -> Self {
a
}
fn normalized(&self) -> Self {
self.scale(self.mag().recip())
}
fn get(&self, i: usize) -> f32 {
self[i]
}
fn set(&mut self, i: usize, v: f32) {
self[i] = v;
}
fn mag(&self) -> f32 {
self.iter().map(|x| x * x).sum::<f32>().sqrt()
}
}