1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use core::ops::*; use crate::util::QuickInverseSQRT; pub trait Vector : Add + Sub + Mul<f32> + AddAssign + SubAssign + MulAssign<f32> + Copy + Clone { const ZERO:Self; fn dot_product(v1:&Self, v2:&Self) -> f32; fn len(&self) -> f32; fn inv_len(&self) -> f32; } macro_rules! impl_vec { ( $($vec:ident; ( $($var:ident),+ ));+ ) => { $( #[derive(Copy, Clone)] pub struct $vec { $(pub $var: f32),+ } impl $vec { pub const fn new($($var: f32),+) -> $vec { $vec { $($var),+ } } } impl Vector for $vec { const ZERO:$vec = $vec{ $($var: 0f32),+ }; fn dot_product(v1:&$vec, v2:&$vec) -> f32 { 0f32 $( + (v1.$var * v2.$var) )+ } fn len(&self) -> f32 { (0f32 $( + (self.$var * self.$var) )+).sqrt() } fn inv_len(&self) -> f32 { (0f32 $( + (self.$var * self.$var) )+).quick_inverse_sqrt() } } impl Add for $vec { type Output = $vec; #[inline] fn add(self, rhs: $vec) -> $vec { $vec { $($var: self.$var + rhs.$var),+ } } } impl Sub for $vec { type Output = $vec; #[inline] fn sub(self, rhs: $vec) -> $vec { $vec { $($var: self.$var - rhs.$var),+ } } } impl Mul<f32> for $vec { type Output = $vec; #[inline] fn mul(self, rhs: f32) -> $vec { $vec { $($var: self.$var * rhs),+ } } } impl AddAssign for $vec { #[inline] fn add_assign(&mut self, rhs: $vec) { $(self.$var += rhs.$var;)+ } } impl SubAssign for $vec { #[inline] fn sub_assign(&mut self, rhs: $vec) { $(self.$var -= rhs.$var;)+ } } impl MulAssign<f32> for $vec { #[inline] fn mul_assign(&mut self, rhs: f32) { $(self.$var *= rhs;)+ } } )+ } } impl_vec!( Vector1D; (x); Vector2D; (x,y); Vector3D; (x,y,z) );