use std::ops::{Add, Div, Mul, Sub};
use glam::{Vec2, Vec3, Vec3A};
pub trait Vector<const N: usize>:
Sized
+ Copy
+ Clone
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
+ Mul<f32, Output = 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 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 to_arr(&self) -> [f32; N];
fn from_arr(a: [f32; N]) -> Self;
fn normalized(&self) -> Self;
fn get(&self, i: usize) -> f32;
fn set(&mut self, i: usize, v: f32);
fn mag(&self) -> f32;
}
#[macro_export]
macro_rules! impl_vector_glam_vec3 {
($a: ident) => {
impl Vector<3> for $a {
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 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 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 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);