thimni 0.3.2

efficient SDF collision without discretizatio, neural nets, or interval arithmetic
Documentation
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;
}

/// Used for implementing the Vector trait for glam::Vec3-esque types (e.g. Vec3, Vec3A,
/// macroquad::math::Vec3, etc)
#[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()
            }
        }
    };
}

/// Used for implementing the Vector trait for glam::Vec2-esque types (e.g. Vec2,
/// macroquad::math::Vec2, etc)
#[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()
    }
}