From 288afe089892ff7f6860efd33ad791eda8c19420 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 7 Jul 2013 16:00:35 +1000 Subject: [PATCH] Remove dimensional HOFs --- src/dim_macros.rs | 191 +++------- src/mat.rs | 211 +++++++---- src/plane.rs | 3 +- src/point.rs | 6 +- src/quat.rs | 46 +-- src/vec.rs | 945 ++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 998 insertions(+), 404 deletions(-) diff --git a/src/dim_macros.rs b/src/dim_macros.rs index fc62507..eb46ea1 100644 --- a/src/dim_macros.rs +++ b/src/dim_macros.rs @@ -43,150 +43,6 @@ macro_rules! impl_dimensional( ) ) -macro_rules! impl_dimensional_fns( - ($Self:ident, $T:ty, 2) => ( - impl $Self { - #[inline] - pub fn from_slice<'a>(slice: [$T,..2]) -> $Self { - use std::cast::transmute; - unsafe { transmute(slice) } - } - - #[inline(always)] - pub fn map(&self, f: &fn(&$T) -> U) -> [U,..2] { - [f(self.index(0)), - f(self.index(1))] - } - - #[inline(always)] - pub fn map_mut(&mut self, f: &fn(&mut $T)) { - f(self.index_mut(0)); - f(self.index_mut(1)); - } - - #[inline(always)] - pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..2] { - [f(self.index(0), other.index(0)), - f(self.index(1), other.index(1))] - } - - #[inline(always)] - pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { - f(self.index_mut(0), other.index(0)); - f(self.index_mut(1), other.index(1)); - } - - #[inline(always)] - pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(0), &f(self.index(1), init)) - } - - #[inline(always)] - pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(1), &f(self.index(0), init)) - } - } - ); - ($Self:ident, $T:ty, 3) => ( - impl $Self { - #[inline] - pub fn from_slice<'a>(slice: [$T,..3]) -> $Self { - use std::cast::transmute; - unsafe { transmute(slice) } - } - - #[inline(always)] - pub fn map(&self, f: &fn(&$T) -> U) -> [U,..3] { - [f(self.index(0)), - f(self.index(1)), - f(self.index(2))] - } - - #[inline(always)] - pub fn map_mut(&mut self, f: &fn(&mut $T)) { - f(self.index_mut(0)); - f(self.index_mut(1)); - f(self.index_mut(2)); - } - - #[inline(always)] - pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..3] { - [f(self.index(0), other.index(0)), - f(self.index(1), other.index(1)), - f(self.index(2), other.index(2))] - } - - #[inline(always)] - pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { - f(self.index_mut(0), other.index(0)); - f(self.index_mut(1), other.index(1)); - f(self.index_mut(2), other.index(2)); - } - - #[inline(always)] - pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(0), &f(self.index(1), &f(self.index(2), init))) - } - - #[inline(always)] - pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(2), &f(self.index(1), &f(self.index(0), init))) - } - } - ); - ($Self:ident, $T:ty, 4) => ( - impl $Self { - #[inline] - pub fn from_slice<'a>(slice: [$T,..4]) -> $Self { - use std::cast::transmute; - unsafe { transmute(slice) } - } - - #[inline(always)] - pub fn map(&self, f: &fn(&$T) -> U) -> [U,..4] { - [f(self.index(0)), - f(self.index(1)), - f(self.index(2)), - f(self.index(3))] - } - - #[inline(always)] - pub fn map_mut(&mut self, f: &fn(&mut $T)) { - f(self.index_mut(0)); - f(self.index_mut(1)); - f(self.index_mut(2)); - f(self.index_mut(3)); - } - - #[inline(always)] - pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..4] { - [f(self.index(0), other.index(0)), - f(self.index(1), other.index(1)), - f(self.index(2), other.index(2)), - f(self.index(3), other.index(3))] - } - - #[inline(always)] - pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { - f(self.index_mut(0), other.index(0)); - f(self.index_mut(1), other.index(1)); - f(self.index_mut(2), other.index(2)); - f(self.index_mut(3), other.index(3)); - } - - #[inline(always)] - pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(0), &f(self.index(1), &f(self.index(2), &f(self.index(3), init)))) - } - - #[inline(always)] - pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(3), &f(self.index(2), &f(self.index(1), &f(self.index(0), init)))) - } - } - ) -) - macro_rules! impl_swap( ($Self:ident) => ( impl $Self { @@ -201,7 +57,7 @@ macro_rules! impl_swap( ) macro_rules! impl_approx( - ($Self:ident) => ( + ($Self:ident, 2) => ( impl> ApproxEq for $Self { #[inline] pub fn approx_epsilon() -> T { @@ -215,8 +71,49 @@ macro_rules! impl_approx( #[inline] pub fn approx_eq_eps(&self, other: &$Self, epsilon: &T) -> bool { - let tmp = self.zip(other, |a, b| a.approx_eq_eps(b, epsilon)); - tmp.iter().all(|&x| x) + self.index(0).approx_eq_eps(other.index(0), epsilon) && + self.index(1).approx_eq_eps(other.index(1), epsilon) + } + } + ); + ($Self:ident, 3) => ( + impl> ApproxEq for $Self { + #[inline] + pub fn approx_epsilon() -> T { + ApproxEq::approx_epsilon::() + } + + #[inline] + pub fn approx_eq(&self, other: &$Self) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + } + + #[inline] + pub fn approx_eq_eps(&self, other: &$Self, epsilon: &T) -> bool { + self.index(0).approx_eq_eps(other.index(0), epsilon) && + self.index(1).approx_eq_eps(other.index(1), epsilon) && + self.index(2).approx_eq_eps(other.index(2), epsilon) + } + } + ); + ($Self:ident, 4) => ( + impl> ApproxEq for $Self { + #[inline] + pub fn approx_epsilon() -> T { + ApproxEq::approx_epsilon::() + } + + #[inline] + pub fn approx_eq(&self, other: &$Self) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + } + + #[inline] + pub fn approx_eq_eps(&self, other: &$Self, epsilon: &T) -> bool { + self.index(0).approx_eq_eps(other.index(0), epsilon) && + self.index(1).approx_eq_eps(other.index(1), epsilon) && + self.index(2).approx_eq_eps(other.index(2), epsilon) && + self.index(3).approx_eq_eps(other.index(3), epsilon) } } ) diff --git a/src/mat.rs b/src/mat.rs index c91e8a2..3de6718 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -47,14 +47,9 @@ macro_rules! impl_mat( ) ) -macro_rules! impl_mat_clonable( +macro_rules! impl_mat_swap( ($Mat:ident, $Vec:ident) => ( impl $Mat { - #[inline] - pub fn row(&self, i: uint) -> $Vec { - $Vec::from_slice(self.map(|c| c.index(i).clone())) - } - #[inline] pub fn swap_cols(&mut self, a: uint, b: uint) { let tmp = self.col(a).clone(); @@ -62,11 +57,6 @@ macro_rules! impl_mat_clonable( *self.col_mut(b) = tmp; } - #[inline] - pub fn swap_rows(&mut self, a: uint, b: uint) { - self.map_mut(|x| x.swap(a, b)) - } - #[inline] pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), (col_b, row_b): (uint, uint)) { let tmp = self.elem(col_a, row_a).clone(); @@ -136,11 +126,10 @@ pub type Mat2f32 = Mat2; pub type Mat2f64 = Mat2; impl_dimensional!(Mat2, Vec2, 2) -impl_dimensional_fns!(Mat2, Vec2, 2) -impl_approx!(Mat2) +impl_approx!(Mat2, 2) impl_mat!(Mat2, Vec2) -impl_mat_clonable!(Mat2, Vec2) +impl_mat_swap!(Mat2, Vec2) pub trait ToMat2 { pub fn to_mat2(&self) -> Mat2; @@ -161,6 +150,20 @@ impl Mat2 { } } +impl Mat2 { + #[inline] + pub fn row(&self, i: uint) -> Vec2 { + Vec2::new(self.col(0).index(i).clone(), + self.col(1).index(i).clone()) + } + + #[inline] + pub fn swap_rows(&mut self, a: uint, b: uint) { + self.col_mut(0).swap(a, b); + self.col_mut(1).swap(a, b); + } +} + impl ToMat3 for Mat2 { #[inline] pub fn to_mat3(&self) -> Mat3 { @@ -195,7 +198,8 @@ impl Mat2 { #[inline] pub fn mul_t(&self, value: T) -> Mat2 { - Mat2::from_slice(self.map(|&c| c.mul_t(value.clone()))) + Mat2::from_cols(self.col(0).mul_t(value.clone()), + self.col(1).mul_t(value.clone())) } #[inline] @@ -204,6 +208,18 @@ impl Mat2 { self.row(1).dot(vec)) } + #[inline] + pub fn add_m(&self, other: &Mat2) -> Mat2 { + Mat2::from_cols(self.col(0).add_v(other.col(0)), + self.col(1).add_v(other.col(1))) + } + + #[inline] + pub fn sub_m(&self, other: &Mat2) -> Mat2 { + Mat2::from_cols(self.col(0).sub_v(other.col(0)), + self.col(1).sub_v(other.col(1))) + } + #[inline] pub fn mul_m(&self, other: &Mat2) -> Mat2 { Mat2::new(self.row(0).dot(other.col(0)), @@ -213,29 +229,22 @@ impl Mat2 { self.row(1).dot(other.col(1))) } - #[inline] - pub fn add_m(&self, other: &Mat2) -> Mat2 { - Mat2::from_slice(self.zip(other, |a, b| a.add_v(b))) - } - - #[inline] - pub fn sub_m(&self, other: &Mat2) -> Mat2 { - Mat2::from_slice(self.zip(other, |a, b| a.sub_v(b))) - } - #[inline] pub fn mul_self_t(&mut self, value: T) { - self.map_mut(|x| x.mul_self_t(value.clone())) + self.col_mut(0).mul_self_t(value.clone()); + self.col_mut(1).mul_self_t(value.clone()); } #[inline] pub fn add_self_m(&mut self, other: &Mat2) { - self.zip_mut(other, |a, b| a.add_self_v(b)) + self.col_mut(0).add_self_v(other.col(0)); + self.col_mut(1).add_self_v(other.col(1)); } #[inline] pub fn sub_self_m(&mut self, other: &Mat2) { - self.zip_mut(other, |a, b| a.sub_self_v(b)) + self.col_mut(0).sub_self_v(other.col(0)); + self.col_mut(1).sub_self_v(other.col(1)); } pub fn dot(&self, other: &Mat2) -> T { @@ -264,7 +273,8 @@ impl Mat2 { impl Neg> for Mat2 { #[inline] pub fn neg(&self) -> Mat2 { - Mat2::from_slice(self.map(|&x| -x)) + Mat2::from_cols(-*self.col(0), + -*self.col(1)) } } @@ -529,11 +539,10 @@ pub type Mat3f32 = Mat3; pub type Mat3f64 = Mat3; impl_dimensional!(Mat3, Vec3, 3) -impl_dimensional_fns!(Mat3, Vec3, 3) -impl_approx!(Mat3) +impl_approx!(Mat3, 3) impl_mat!(Mat3, Vec3) -impl_mat_clonable!(Mat3, Vec3) +impl_mat_swap!(Mat3, Vec3) pub trait ToMat3 { pub fn to_mat3(&self) -> Mat3; @@ -557,6 +566,22 @@ impl Mat3 { } } +impl Mat3 { + #[inline] + pub fn row(&self, i: uint) -> Vec3 { + Vec3::new(self.col(0).index(i).clone(), + self.col(1).index(i).clone(), + self.col(2).index(i).clone()) + } + + #[inline] + pub fn swap_rows(&mut self, a: uint, b: uint) { + self.col_mut(0).swap(a, b); + self.col_mut(1).swap(a, b); + self.col_mut(2).swap(a, b); + } +} + impl ToMat4 for Mat3 { #[inline] pub fn to_mat4(&self) -> Mat4 { @@ -583,7 +608,9 @@ impl Mat3 { #[inline] pub fn mul_t(&self, value: T) -> Mat3 { - Mat3::from_slice(self.map(|&c| c.mul_t(value.clone()))) + Mat3::from_cols(self.col(0).mul_t(value.clone()), + self.col(1).mul_t(value.clone()), + self.col(2).mul_t(value.clone())) } #[inline] @@ -593,6 +620,20 @@ impl Mat3 { self.row(2).dot(vec)) } + #[inline] + pub fn add_m(&self, other: &Mat3) -> Mat3 { + Mat3::from_cols(self.col(0).add_v(other.col(0)), + self.col(1).add_v(other.col(1)), + self.col(2).add_v(other.col(2))) + } + + #[inline] + pub fn sub_m(&self, other: &Mat3) -> Mat3 { + Mat3::from_cols(self.col(0).sub_v(other.col(0)), + self.col(1).sub_v(other.col(1)), + self.col(2).sub_v(other.col(2))) + } + #[inline] pub fn mul_m(&self, other: &Mat3) -> Mat3 { Mat3::new(self.row(0).dot(other.col(0)), @@ -608,29 +649,25 @@ impl Mat3 { self.row(2).dot(other.col(2))) } - #[inline] - pub fn add_m(&self, other: &Mat3) -> Mat3 { - Mat3::from_slice(self.zip(other, |a, b| a.add_v(b))) - } - - #[inline] - pub fn sub_m(&self, other: &Mat3) -> Mat3 { - Mat3::from_slice(self.zip(other, |a, b| a.sub_v(b))) - } - #[inline] pub fn mul_self_t(&mut self, value: T) { - self.map_mut(|x| x.mul_self_t(value.clone())) + self.col_mut(0).mul_self_t(value.clone()); + self.col_mut(1).mul_self_t(value.clone()); + self.col_mut(2).mul_self_t(value.clone()); } #[inline] pub fn add_self_m(&mut self, other: &Mat3) { - self.zip_mut(other, |a, b| a.add_self_v(b)) + self.col_mut(0).add_self_v(other.col(0)); + self.col_mut(1).add_self_v(other.col(1)); + self.col_mut(2).add_self_v(other.col(2)); } #[inline] pub fn sub_self_m(&mut self, other: &Mat3) { - self.zip_mut(other, |a, b| a.sub_self_v(b)) + self.col_mut(0).sub_self_v(other.col(0)); + self.col_mut(1).sub_self_v(other.col(1)); + self.col_mut(2).sub_self_v(other.col(2)); } pub fn dot(&self, other: &Mat3) -> T { @@ -661,7 +698,9 @@ impl Mat3 { impl Neg> for Mat3 { #[inline] pub fn neg(&self) -> Mat3 { - Mat3::from_slice(self.map(|&x| -x)) + Mat3::from_cols(-*self.col(0), + -*self.col(1), + -*self.col(2)) } } @@ -1065,8 +1104,8 @@ mod mat3_tests{ 0.000001, 0.000001, 0.000001) .approx_eq(&Mat3::zero::())); assert!(Mat3::new::(0.0000001, 0.0000001, 0.0000001, - 0.0000001, 0.0000001, 0.0000001, - 0.0000001, 0.0000001, 0.0000001) + 0.0000001, 0.0000001, 0.0000001, + 0.0000001, 0.0000001, 0.0000001) .approx_eq(&Mat3::zero::())); } } @@ -1089,11 +1128,10 @@ pub type Mat4f32 = Mat4; pub type Mat4f64 = Mat4; impl_dimensional!(Mat4, Vec4, 4) -impl_dimensional_fns!(Mat4, Vec4, 4) -impl_approx!(Mat4) +impl_approx!(Mat4, 4) impl_mat!(Mat4, Vec4) -impl_mat_clonable!(Mat4, Vec4) +impl_mat_swap!(Mat4, Vec4) pub trait ToMat4 { pub fn to_mat4(&self) -> Mat4; @@ -1120,6 +1158,24 @@ impl Mat4 { } } +impl Mat4 { + #[inline] + pub fn row(&self, i: uint) -> Vec4 { + Vec4::new(self.col(0).index(i).clone(), + self.col(1).index(i).clone(), + self.col(2).index(i).clone(), + self.col(3).index(i).clone()) + } + + #[inline] + pub fn swap_rows(&mut self, a: uint, b: uint) { + self.col_mut(0).swap(a, b); + self.col_mut(1).swap(a, b); + self.col_mut(2).swap(a, b); + self.col_mut(3).swap(a, b); + } +} + impl Mat4 { #[inline] pub fn from_value(value: T) -> Mat4 { @@ -1137,7 +1193,10 @@ impl Mat4 { #[inline] pub fn mul_t(&self, value: T) -> Mat4 { - Mat4::from_slice(self.map(|&c| c.mul_t(value.clone()))) + Mat4::from_cols(self.col(0).mul_t(value.clone()), + self.col(1).mul_t(value.clone()), + self.col(2).mul_t(value.clone()), + self.col(3).mul_t(value.clone())) } #[inline] @@ -1148,6 +1207,22 @@ impl Mat4 { self.row(3).dot(vec)) } + #[inline] + pub fn add_m(&self, other: &Mat4) -> Mat4 { + Mat4::from_cols(self.col(0).add_v(other.col(0)), + self.col(1).add_v(other.col(1)), + self.col(2).add_v(other.col(2)), + self.col(3).add_v(other.col(3))) + } + + #[inline] + pub fn sub_m(&self, other: &Mat4) -> Mat4 { + Mat4::from_cols(self.col(0).sub_v(other.col(0)), + self.col(1).sub_v(other.col(1)), + self.col(2).sub_v(other.col(2)), + self.col(3).sub_v(other.col(3))) + } + #[inline] pub fn mul_m(&self, other: &Mat4) -> Mat4 { Mat4::new(self.row(0).dot(other.col(0)), @@ -1171,29 +1246,28 @@ impl Mat4 { self.row(3).dot(other.col(3))) } - #[inline] - pub fn add_m(&self, other: &Mat4) -> Mat4 { - Mat4::from_slice(self.zip(other, |a, b| a.add_v(b))) - } - - #[inline] - pub fn sub_m(&self, other: &Mat4) -> Mat4 { - Mat4::from_slice(self.zip(other, |a, b| a.sub_v(b))) - } - #[inline] pub fn mul_self_t(&mut self, value: T) { - self.map_mut(|x| x.mul_self_t(value.clone())) + self.col_mut(0).mul_self_t(value.clone()); + self.col_mut(1).mul_self_t(value.clone()); + self.col_mut(2).mul_self_t(value.clone()); + self.col_mut(3).mul_self_t(value.clone()); } #[inline] pub fn add_self_m(&mut self, other: &Mat4) { - self.zip_mut(other, |a, b| a.add_self_v(b)) + self.col_mut(0).add_self_v(other.col(0)); + self.col_mut(1).add_self_v(other.col(1)); + self.col_mut(2).add_self_v(other.col(2)); + self.col_mut(3).add_self_v(other.col(3)); } #[inline] pub fn sub_self_m(&mut self, other: &Mat4) { - self.zip_mut(other, |a, b| a.sub_self_v(b)) + self.col_mut(0).sub_self_v(other.col(0)); + self.col_mut(1).sub_self_v(other.col(1)); + self.col_mut(2).sub_self_v(other.col(2)); + self.col_mut(3).sub_self_v(other.col(3)); } pub fn dot(&self, other: &Mat4) -> T { @@ -1238,7 +1312,10 @@ impl Mat4 { impl Neg> for Mat4 { #[inline] pub fn neg(&self) -> Mat4 { - Mat4::from_slice(self.map(|&x| -x)) + Mat4::from_cols(-*self.col(0), + -*self.col(1), + -*self.col(2), + -*self.col(3)) } } diff --git a/src/plane.rs b/src/plane.rs index eb45371..4a9367b 100644 --- a/src/plane.rs +++ b/src/plane.rs @@ -38,9 +38,8 @@ pub struct Plane { } impl_dimensional!(Plane, T, 4) -impl_dimensional_fns!(Plane, T, 4) +impl_approx!(Plane, 4) impl_swap!(Plane) -impl_approx!(Plane) impl Plane { /// # Arguments diff --git a/src/point.rs b/src/point.rs index b223b66..fc27dcf 100644 --- a/src/point.rs +++ b/src/point.rs @@ -29,8 +29,7 @@ pub trait Point: Eq + ApproxEq + ToStr { pub struct Point2(Vec2); impl_dimensional!(Point2, T, 2) -impl_dimensional_fns!(Point2, T, 2) -impl_approx!(Point2) +impl_approx!(Point2, 2) impl Point2 { pub fn new(x: T, y: T) -> Point2 { @@ -59,8 +58,7 @@ impl ToStr for Point2 { pub struct Point3(Vec3); impl_dimensional!(Point3, T, 3) -impl_dimensional_fns!(Point3, T, 3) -impl_approx!(Point3) +impl_approx!(Point3, 3) impl Point3 { pub fn new(x: T, y: T, z: T) -> Point3 { diff --git a/src/quat.rs b/src/quat.rs index 320c6fa..ab4bb87 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -37,9 +37,8 @@ pub type Quatf64 = Quat; pub struct Quat { s: T, v: Vec3 } impl_dimensional!(Quat, T, 4) -impl_dimensional_fns!(Quat, T, 4) +impl_approx!(Quat, 4) impl_swap!(Quat) -impl_approx!(Quat) pub trait ToQuat { pub fn to_quat(&self) -> Quat; @@ -124,13 +123,13 @@ impl Quat { /// The result of multiplying the quaternion a scalar #[inline] pub fn mul_t(&self, value: T) -> Quat { - Quat::from_slice(self.map(|&x| x * value)) + Quat::from_sv(self.s * value, self.v.mul_t(value)) } /// The result of dividing the quaternion a scalar #[inline] pub fn div_t(&self, value: T) -> Quat { - Quat::from_slice(self.map(|&x| x / value)) + Quat::from_sv(self.s / value, self.v.div_t(value)) } /// The result of multiplying the quaternion by a vector @@ -250,7 +249,7 @@ impl ToMat3 for Quat { impl Neg> for Quat { #[inline] pub fn neg(&self) -> Quat { - Quat::from_slice(self.map(|&x| -x)) + Quat::from_sv(-self.s, -self.v) } } @@ -316,42 +315,21 @@ mod tests { use vec::*; #[test] - fn test_quat() { - let a = Quat { s: 1.0, v: Vec3 { x: 2.0, y: 3.0, z: 4.0 } }; + fn test_from_angle_axis() { + let v = Vec3::new(1f, 0f, 0f); - assert_eq!(a, Quat::from_sv::(1.0, Vec3::new::(2.0, 3.0, 4.0))); - assert_eq!(a, Quat::new::(1.0, 2.0, 3.0, 4.0)); - - assert_eq!(Quat::zero::(), Quat::new::(0.0, 0.0, 0.0, 0.0)); - assert_eq!(Quat::identity::(), Quat::new::(1.0, 0.0, 0.0, 0.0)); - - assert_eq!(a.s, 1.0); - assert_eq!(a.v.x, 2.0); - assert_eq!(a.v.y, 3.0); - assert_eq!(a.v.z, 4.0); - assert_eq!(*a.index(0), 1.0); - assert_eq!(*a.index(1), 2.0); - assert_eq!(*a.index(2), 3.0); - assert_eq!(*a.index(3), 4.0); - // TODO - } - - #[test] - fn test_quat_2() { - let v = Vec3::new(1f32, 0f32, 0f32); - - let q = Quat::from_angle_axis((-45f32).to_radians(), &Vec3::new(0f32, 0f32, -1f32)); + let q = Quat::from_angle_axis((-45f).to_radians(), &Vec3::new(0f, 0f, -1f)); // http://www.wolframalpha.com/input/?i={1,0}+rotate+-45+degrees - assert_approx_eq!(q.mul_v(&v), Vec3::new(1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32)); + assert_approx_eq!(q.mul_v(&v), Vec3::new(1f/2f.sqrt(), 1f/2f.sqrt(), 0f)); assert_eq!(q.mul_v(&v).length(), v.length()); - assert_approx_eq!(q.to_mat3(), Mat3::new( 1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32, - -1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32, - 0f32, 0f32, 1f32)); + assert_approx_eq!(q.to_mat3(), Mat3::new( 1f/2f.sqrt(), 1f/2f.sqrt(), 0f, + -1f/2f.sqrt(), 1f/2f.sqrt(), 0f, + 0f, 0f, 1f)); } #[test] - fn test_quat_approx_eq() { + fn test_approx_eq() { assert!(!Quat::new::(0.000001, 0.000001, 0.000001, 0.000001) .approx_eq(&Quat::new::(0.0, 0.0, 0.0, 0.0))); assert!(Quat::new::(0.0000001, 0.0000001, 0.0000001, 0.0000001) diff --git a/src/vec.rs b/src/vec.rs index e2ea289..aac6fd1 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -45,9 +45,8 @@ pub type Vec2u64 = Vec2; pub type Vec2b = Vec2; impl_dimensional!(Vec2, T, 2) -impl_dimensional_fns!(Vec2, T, 2) +impl_approx!(Vec2, 2) impl_swap!(Vec2) -impl_approx!(Vec2) impl Vec2 { #[inline] @@ -59,16 +58,31 @@ impl Vec2 { impl Vec2 { #[inline] pub fn from_value(value: T) -> Vec2 { - Vec2::new(value.clone(), value.clone()) + Vec2::new(value.clone(), + value.clone()) } } -impl Vec2 { - #[inline] pub fn identity() -> Vec2 { Vec2::from_value(one!(T)) } - #[inline] pub fn zero() -> Vec2 { Vec2::from_value(zero!(T)) } +impl Vec2 { + #[inline] + pub fn identity() -> Vec2 { + Vec2::new(one!(T), one!(T)) + } - #[inline] pub fn unit_x() -> Vec2 { Vec2::new(one!(T), zero!(T)) } - #[inline] pub fn unit_y() -> Vec2 { Vec2::new(zero!(T), one!(T)) } + #[inline] + pub fn zero() -> Vec2 { + Vec2::new(zero!(T), zero!(T)) + } + + #[inline] + pub fn unit_x() -> Vec2 { + Vec2::new(one!(T), zero!(T)) + } + + #[inline] + pub fn unit_y() -> Vec2 { + Vec2::new(zero!(T), one!(T)) + } #[inline] pub fn perp_dot(&self, other: &Vec2) -> T { @@ -76,30 +90,131 @@ impl Vec2 { (*self.index(1) * *other.index(0)) } - #[inline] pub fn add_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x + value)) } - #[inline] pub fn sub_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x - value)) } - #[inline] pub fn mul_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x * value)) } - #[inline] pub fn div_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x / value)) } - #[inline] pub fn rem_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x % value)) } + #[inline] + pub fn add_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) + value, + *self.index(1) + value) + } - #[inline] pub fn add_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a + b)) } - #[inline] pub fn sub_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a - b)) } - #[inline] pub fn mul_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a * b)) } - #[inline] pub fn div_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a / b)) } - #[inline] pub fn rem_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a % b)) } + #[inline] + pub fn sub_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) - value, + *self.index(1) - value) + } - #[inline] pub fn neg_self(&mut self) { self.map_mut(|x| *x = -*x) } - #[inline] pub fn add_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x + value.clone()) } - #[inline] pub fn sub_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x - value.clone()) } - #[inline] pub fn mul_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x * value.clone()) } - #[inline] pub fn div_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x / value.clone()) } - #[inline] pub fn rem_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x % value.clone()) } + #[inline] + pub fn mul_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) * value, + *self.index(1) * value) + } - #[inline] pub fn add_self_v(&mut self, other: &Vec2) { self.zip_mut(other, |a, &b| *a =*a + b) } - #[inline] pub fn sub_self_v(&mut self, other: &Vec2) { self.zip_mut(other, |a, &b| *a =*a - b) } - #[inline] pub fn mul_self_v(&mut self, other: &Vec2) { self.zip_mut(other, |a, &b| *a =*a * b) } - #[inline] pub fn div_self_v(&mut self, other: &Vec2) { self.zip_mut(other, |a, &b| *a =*a / b) } - #[inline] pub fn rem_self_v(&mut self, other: &Vec2) { self.zip_mut(other, |a, &b| *a =*a % b) } + #[inline] + pub fn div_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) / value, + *self.index(1) / value) + } + + #[inline] + pub fn rem_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) % value, + *self.index(1) % value) + } + + #[inline] + pub fn add_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) + *other.index(0), + *self.index(1) + *other.index(1)) + } + + #[inline] + pub fn sub_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) - *other.index(0), + *self.index(1) - *other.index(1)) + } + + #[inline] + pub fn mul_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) * *other.index(0), + *self.index(1) * *other.index(1)) + } + + #[inline] + pub fn div_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) / *other.index(0), + *self.index(1) / *other.index(1)) + } + + #[inline] + pub fn rem_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) % *other.index(0), + *self.index(1) % *other.index(1)) + } + + #[inline] + pub fn neg_self(&mut self) { + *self.index_mut(0) = -*self.index(0); + *self.index_mut(1) = -*self.index(1); + } + + #[inline] + pub fn add_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) + value; + *self.index_mut(1) = *self.index(1) + value; + } + + #[inline] + pub fn sub_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) - value; + *self.index_mut(1) = *self.index(1) - value; + } + + #[inline] + pub fn mul_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) * value; + *self.index_mut(1) = *self.index(1) * value; + } + + #[inline] + pub fn div_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) / value; + *self.index_mut(1) = *self.index(1) / value; + } + + #[inline] + pub fn rem_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) % value; + *self.index_mut(1) = *self.index(1) % value; + } + + #[inline] + pub fn add_self_v(&mut self, other: &Vec2) { + *self.index_mut(0) = *self.index(0) + *other.index(0); + *self.index_mut(1) = *self.index(1) + *other.index(1); + } + + #[inline] + pub fn sub_self_v(&mut self, other: &Vec2) { + *self.index_mut(0) = *self.index(0) - *other.index(0); + *self.index_mut(1) = *self.index(1) - *other.index(1); + } + + #[inline] + pub fn mul_self_v(&mut self, other: &Vec2) { + *self.index_mut(0) = *self.index(0) * *other.index(0); + *self.index_mut(1) = *self.index(1) * *other.index(1); + } + + #[inline] + pub fn div_self_v(&mut self, other: &Vec2) { + *self.index_mut(0) = *self.index(0) / *other.index(0); + *self.index_mut(1) = *self.index(1) / *other.index(1); + } + + #[inline] + pub fn rem_self_v(&mut self, other: &Vec2) { + *self.index_mut(0) = *self.index(0) % *other.index(0); + *self.index_mut(1) = *self.index(1) % *other.index(1); + } #[inline] pub fn dot(&self, other: &Vec2) -> T { *self.index(0) * *other.index(0) + @@ -107,20 +222,22 @@ impl Vec2 { } } -impl Neg> for Vec2 { +impl Neg> for Vec2 { #[inline] pub fn neg(&self) -> Vec2 { - Vec2::from_slice(self.map(|&x| -x)) + Vec2::new(-*self.index(0), + -*self.index(1)) } } -impl> Not> for Vec2 { +impl> Not> for Vec2 { pub fn not(&self) -> Vec2 { - Vec2::from_slice(self.map(|&x| !x)) + Vec2::new(!*self.index(0), + !*self.index(1)) } } -impl Vec2 { +impl Vec2 { #[inline] pub fn length2(&self) -> T { self.dot(self) @@ -179,24 +296,80 @@ impl Vec2 { } } -impl Vec2 { - #[inline] pub fn lt_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x < value)) } - #[inline] pub fn le_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x <= value)) } - #[inline] pub fn ge_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x >= value)) } - #[inline] pub fn gt_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x > value)) } +impl Vec2 { + #[inline] + pub fn lt_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) < value, + *self.index(1) < value) + } - #[inline] pub fn lt_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a < b)) } - #[inline] pub fn le_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a <= b)) } - #[inline] pub fn ge_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a >= b)) } - #[inline] pub fn gt_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a > b)) } + #[inline] + pub fn le_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) <= value, + *self.index(1) <= value) + } + + #[inline] + pub fn ge_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) >= value, + *self.index(1) >= value) + } + + #[inline] + pub fn gt_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) > value, + *self.index(1) > value) + } + + #[inline] + pub fn lt_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) < *other.index(0), + *self.index(1) < *other.index(1)) + } + + #[inline] + pub fn le_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) <= *other.index(0), + *self.index(1) <= *other.index(1)) + } + + #[inline] + pub fn ge_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) >= *other.index(0), + *self.index(1) >= *other.index(1)) + } + + #[inline] + pub fn gt_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) > *other.index(0), + *self.index(1) > *other.index(1)) + } } -impl Vec2 { - #[inline] pub fn eq_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x == value)) } - #[inline] pub fn ne_t(&self, value: T) -> Vec2 { Vec2::from_slice(self.map(|&x| x != value)) } +impl Vec2 { + #[inline] + pub fn eq_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) == value, + *self.index(1) == value) + } - #[inline] pub fn eq_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a == b)) } - #[inline] pub fn ne_v(&self, other: &Vec2) -> Vec2 { Vec2::from_slice(self.zip(other, |&a, &b| a != b)) } + #[inline] + pub fn ne_t(&self, value: T) -> Vec2 { + Vec2::new(*self.index(0) != value, + *self.index(1) != value) + } + + #[inline] + pub fn eq_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) == *other.index(0), + *self.index(1) == *other.index(1)) + } + + #[inline] + pub fn ne_v(&self, other: &Vec2) -> Vec2 { + Vec2::new(*self.index(0) != *other.index(0), + *self.index(1) != *other.index(1)) + } } impl Vec2 { @@ -212,7 +385,8 @@ impl Vec2 { #[inline] pub fn not(&self) -> Vec2 { - Vec2::from_slice(self.map(|&x| !x)) + Vec2::new(!*self.index(0), + !*self.index(1)) } } @@ -376,9 +550,8 @@ pub type Vec3u64 = Vec3; pub type Vec3b = Vec3; impl_dimensional!(Vec3, T, 3) -impl_dimensional_fns!(Vec3, T, 3) +impl_approx!(Vec3, 3) impl_swap!(Vec3) -impl_approx!(Vec3) impl Vec3 { #[inline] @@ -390,17 +563,37 @@ impl Vec3 { impl Vec3 { #[inline] pub fn from_value(value: T) -> Vec3 { - Vec3::new(value.clone(), value.clone(), value.clone()) + Vec3::new(value.clone(), + value.clone(), + value.clone()) } } -impl Vec3 { - #[inline] pub fn identity() -> Vec3 { Vec3::from_value(one!(T)) } - #[inline] pub fn zero() -> Vec3 { Vec3::from_value(zero!(T)) } +impl Vec3 { + #[inline] + pub fn identity() -> Vec3 { + Vec3::new(one!(T), one!(T), one!(T)) + } - #[inline] pub fn unit_x() -> Vec3 { Vec3::new(one!(T), zero!(T), zero!(T)) } - #[inline] pub fn unit_y() -> Vec3 { Vec3::new(zero!(T), one!(T), zero!(T)) } - #[inline] pub fn unit_z() -> Vec3 { Vec3::new(zero!(T), zero!(T), one!(T)) } + #[inline] + pub fn zero() -> Vec3 { + Vec3::new(zero!(T), zero!(T), zero!(T)) + } + + #[inline] + pub fn unit_x() -> Vec3 { + Vec3::new(one!(T), zero!(T), zero!(T)) + } + + #[inline] + pub fn unit_y() -> Vec3 { + Vec3::new(zero!(T), one!(T), zero!(T)) + } + + #[inline] + pub fn unit_z() -> Vec3 { + Vec3::new(zero!(T), zero!(T), one!(T)) + } #[inline] pub fn cross(&self, other: &Vec3) -> Vec3 { @@ -414,30 +607,152 @@ impl Vec3 { *self = self.cross(other) } - #[inline] pub fn add_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x + value)) } - #[inline] pub fn sub_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x - value)) } - #[inline] pub fn mul_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x * value)) } - #[inline] pub fn div_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x / value)) } - #[inline] pub fn rem_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x % value)) } + #[inline] + pub fn add_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) + value, + *self.index(1) + value, + *self.index(2) + value) + } - #[inline] pub fn add_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a + b)) } - #[inline] pub fn sub_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a - b)) } - #[inline] pub fn mul_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a * b)) } - #[inline] pub fn div_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a / b)) } - #[inline] pub fn rem_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a % b)) } + #[inline] + pub fn sub_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) - value, + *self.index(1) - value, + *self.index(2) - value) + } - #[inline] pub fn neg_self(&mut self) { self.map_mut(|x| *x = -*x) } - #[inline] pub fn add_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x + value.clone()) } - #[inline] pub fn sub_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x - value.clone()) } - #[inline] pub fn mul_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x * value.clone()) } - #[inline] pub fn div_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x / value.clone()) } - #[inline] pub fn rem_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x % value.clone()) } + #[inline] + pub fn mul_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) * value, + *self.index(1) * value, + *self.index(2) * value) + } - #[inline] pub fn add_self_v(&mut self, other: &Vec3) { self.zip_mut(other, |a, &b| *a =*a + b) } - #[inline] pub fn sub_self_v(&mut self, other: &Vec3) { self.zip_mut(other, |a, &b| *a =*a - b) } - #[inline] pub fn mul_self_v(&mut self, other: &Vec3) { self.zip_mut(other, |a, &b| *a =*a * b) } - #[inline] pub fn div_self_v(&mut self, other: &Vec3) { self.zip_mut(other, |a, &b| *a =*a / b) } - #[inline] pub fn rem_self_v(&mut self, other: &Vec3) { self.zip_mut(other, |a, &b| *a =*a % b) } + #[inline] + pub fn div_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) / value, + *self.index(1) / value, + *self.index(2) / value) + } + + #[inline] + pub fn rem_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) % value, + *self.index(1) % value, + *self.index(2) % value) + } + + #[inline] + pub fn add_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) + *other.index(0), + *self.index(1) + *other.index(1), + *self.index(2) + *other.index(2)) + } + + #[inline] + pub fn sub_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) - *other.index(0), + *self.index(1) - *other.index(1), + *self.index(2) - *other.index(2)) + } + + #[inline] + pub fn mul_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) * *other.index(0), + *self.index(1) * *other.index(1), + *self.index(2) * *other.index(2)) + } + + #[inline] + pub fn div_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) / *other.index(0), + *self.index(1) / *other.index(1), + *self.index(2) / *other.index(2)) + } + + #[inline] + pub fn rem_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) % *other.index(0), + *self.index(1) % *other.index(1), + *self.index(2) % *other.index(2)) + } + + #[inline] + pub fn neg_self(&mut self) { + *self.index_mut(0) = -*self.index(0); + *self.index_mut(1) = -*self.index(1); + *self.index_mut(2) = -*self.index(2); + } + + #[inline] + pub fn add_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) + value; + *self.index_mut(1) = *self.index(1) + value; + *self.index_mut(2) = *self.index(2) + value; + } + + #[inline] + pub fn sub_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) - value; + *self.index_mut(1) = *self.index(1) - value; + *self.index_mut(2) = *self.index(2) - value; + } + + #[inline] + pub fn mul_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) * value; + *self.index_mut(1) = *self.index(1) * value; + *self.index_mut(2) = *self.index(2) * value; + } + + #[inline] + pub fn div_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) / value; + *self.index_mut(1) = *self.index(1) / value; + *self.index_mut(2) = *self.index(2) / value; + } + + #[inline] + pub fn rem_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) % value; + *self.index_mut(1) = *self.index(1) % value; + *self.index_mut(2) = *self.index(2) % value; + } + + #[inline] + pub fn add_self_v(&mut self, other: &Vec3) { + *self.index_mut(0) = *self.index(0) + *other.index(0); + *self.index_mut(1) = *self.index(1) + *other.index(1); + *self.index_mut(2) = *self.index(2) + *other.index(2); + } + + #[inline] + pub fn sub_self_v(&mut self, other: &Vec3) { + *self.index_mut(0) = *self.index(0) - *other.index(0); + *self.index_mut(1) = *self.index(1) - *other.index(1); + *self.index_mut(2) = *self.index(2) - *other.index(2); + } + + #[inline] + pub fn mul_self_v(&mut self, other: &Vec3) { + *self.index_mut(0) = *self.index(0) * *other.index(0); + *self.index_mut(1) = *self.index(1) * *other.index(1); + *self.index_mut(2) = *self.index(2) * *other.index(2); + } + + #[inline] + pub fn div_self_v(&mut self, other: &Vec3) { + *self.index_mut(0) = *self.index(0) / *other.index(0); + *self.index_mut(1) = *self.index(1) / *other.index(1); + *self.index_mut(2) = *self.index(2) / *other.index(2); + } + + #[inline] + pub fn rem_self_v(&mut self, other: &Vec3) { + *self.index_mut(0) = *self.index(0) % *other.index(0); + *self.index_mut(1) = *self.index(1) % *other.index(1); + *self.index_mut(2) = *self.index(2) % *other.index(2); + } #[inline] pub fn dot(&self, other: &Vec3) -> T { *self.index(0) * *other.index(0) + @@ -446,20 +761,24 @@ impl Vec3 { } } -impl Neg> for Vec3 { +impl Neg> for Vec3 { #[inline] pub fn neg(&self) -> Vec3 { - Vec3::from_slice(self.map(|&x| -x)) + Vec3::new(-*self.index(0), + -*self.index(1), + -*self.index(2)) } } -impl> Not> for Vec3 { +impl> Not> for Vec3 { pub fn not(&self) -> Vec3 { - Vec3::from_slice(self.map(|&x| !x)) + Vec3::new(!*self.index(0), + !*self.index(1), + !*self.index(2)) } } -impl Vec3 { +impl Vec3 { #[inline] pub fn length2(&self) -> T { self.dot(self) @@ -518,24 +837,92 @@ impl Vec3 { } } -impl Vec3 { - #[inline] pub fn lt_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x < value)) } - #[inline] pub fn le_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x <= value)) } - #[inline] pub fn ge_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x >= value)) } - #[inline] pub fn gt_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x > value)) } +impl Vec3 { + #[inline] + pub fn lt_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) < value, + *self.index(1) < value, + *self.index(2) < value) + } - #[inline] pub fn lt_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a < b)) } - #[inline] pub fn le_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a <= b)) } - #[inline] pub fn ge_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a >= b)) } - #[inline] pub fn gt_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a > b)) } + #[inline] + pub fn le_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) <= value, + *self.index(1) <= value, + *self.index(2) <= value) + } + + #[inline] + pub fn ge_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) >= value, + *self.index(1) >= value, + *self.index(2) >= value) + } + + #[inline] + pub fn gt_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) > value, + *self.index(1) > value, + *self.index(2) > value) + } + + #[inline] + pub fn lt_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) < *other.index(0), + *self.index(1) < *other.index(1), + *self.index(2) < *other.index(2)) + } + + #[inline] + pub fn le_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) <= *other.index(0), + *self.index(1) <= *other.index(1), + *self.index(2) <= *other.index(2)) + } + + #[inline] + pub fn ge_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) >= *other.index(0), + *self.index(1) >= *other.index(1), + *self.index(2) >= *other.index(2)) + } + + #[inline] + pub fn gt_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) > *other.index(0), + *self.index(1) > *other.index(1), + *self.index(2) > *other.index(2)) + } } -impl Vec3 { - #[inline] pub fn eq_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x == value)) } - #[inline] pub fn ne_t(&self, value: T) -> Vec3 { Vec3::from_slice(self.map(|&x| x != value)) } +impl Vec3 { + #[inline] + pub fn eq_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) == value, + *self.index(1) == value, + *self.index(2) == value) + } - #[inline] pub fn eq_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a == b)) } - #[inline] pub fn ne_v(&self, other: &Vec3) -> Vec3 { Vec3::from_slice(self.zip(other, |&a, &b| a != b)) } + #[inline] + pub fn ne_t(&self, value: T) -> Vec3 { + Vec3::new(*self.index(0) != value, + *self.index(1) != value, + *self.index(2) != value) + } + + #[inline] + pub fn eq_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) == *other.index(0), + *self.index(1) == *other.index(1), + *self.index(2) == *other.index(2)) + } + + #[inline] + pub fn ne_v(&self, other: &Vec3) -> Vec3 { + Vec3::new(*self.index(0) != *other.index(0), + *self.index(1) != *other.index(1), + *self.index(2) != *other.index(2)) + } } impl Vec3 { @@ -551,7 +938,9 @@ impl Vec3 { #[inline] pub fn not(&self) -> Vec3 { - Vec3::from_slice(self.map(|&x| !x)) + Vec3::new(!*self.index(0), + !*self.index(1), + !*self.index(2)) } } @@ -730,8 +1119,7 @@ pub type Vec4u64 = Vec4; pub type Vec4b = Vec4; impl_dimensional!(Vec4, T, 4) -impl_dimensional_fns!(Vec4, T, 4) -impl_approx!(Vec4) +impl_approx!(Vec4, 4) impl_swap!(Vec4) impl Vec4 { @@ -744,43 +1132,211 @@ impl Vec4 { impl Vec4 { #[inline] pub fn from_value(value: T) -> Vec4 { - Vec4::new(value.clone(), value.clone(), value.clone(), value.clone()) + Vec4::new(value.clone(), + value.clone(), + value.clone(), + value.clone()) } } -impl Vec4 { - #[inline] pub fn identity() -> Vec4 { Vec4::from_value(one!(T)) } - #[inline] pub fn zero() -> Vec4 { Vec4::from_value(zero!(T)) } +impl Vec4 { + #[inline] + pub fn identity() -> Vec4 { + Vec4::new(one!(T), one!(T), one!(T), one!(T)) + } - #[inline] pub fn unit_x() -> Vec4 { Vec4::new(one!(T), zero!(T), zero!(T), zero!(T)) } - #[inline] pub fn unit_y() -> Vec4 { Vec4::new(zero!(T), one!(T), zero!(T), zero!(T)) } - #[inline] pub fn unit_z() -> Vec4 { Vec4::new(zero!(T), zero!(T), one!(T), zero!(T)) } - #[inline] pub fn unit_w() -> Vec4 { Vec4::new(zero!(T), zero!(T), zero!(T), one!(T)) } + #[inline] + pub fn zero() -> Vec4 { + Vec4::new(zero!(T), zero!(T), zero!(T), zero!(T)) + } - #[inline] pub fn add_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x + value)) } - #[inline] pub fn sub_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x - value)) } - #[inline] pub fn mul_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x * value)) } - #[inline] pub fn div_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x / value)) } - #[inline] pub fn rem_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x % value)) } + #[inline] + pub fn unit_x() -> Vec4 { + Vec4::new(one!(T), zero!(T), zero!(T), zero!(T)) + } - #[inline] pub fn add_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a + b)) } - #[inline] pub fn sub_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a - b)) } - #[inline] pub fn mul_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a * b)) } - #[inline] pub fn div_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a / b)) } - #[inline] pub fn rem_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a % b)) } + #[inline] + pub fn unit_y() -> Vec4 { + Vec4::new(zero!(T), one!(T), zero!(T), zero!(T)) + } - #[inline] pub fn neg_self(&mut self) { self.map_mut(|x| *x = -*x) } - #[inline] pub fn add_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x + value.clone()) } - #[inline] pub fn sub_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x - value.clone()) } - #[inline] pub fn mul_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x * value.clone()) } - #[inline] pub fn div_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x / value.clone()) } - #[inline] pub fn rem_self_t(&mut self, value: T) { self.map_mut(|x| *x = *x % value.clone()) } + #[inline] + pub fn unit_z() -> Vec4 { + Vec4::new(zero!(T), zero!(T), one!(T), zero!(T)) + } - #[inline] pub fn add_self_v(&mut self, other: &Vec4) { self.zip_mut(other, |a, &b| *a =*a + b) } - #[inline] pub fn sub_self_v(&mut self, other: &Vec4) { self.zip_mut(other, |a, &b| *a =*a - b) } - #[inline] pub fn mul_self_v(&mut self, other: &Vec4) { self.zip_mut(other, |a, &b| *a =*a * b) } - #[inline] pub fn div_self_v(&mut self, other: &Vec4) { self.zip_mut(other, |a, &b| *a =*a / b) } - #[inline] pub fn rem_self_v(&mut self, other: &Vec4) { self.zip_mut(other, |a, &b| *a =*a % b) } + #[inline] + pub fn unit_w() -> Vec4 { + Vec4::new(zero!(T), zero!(T), zero!(T), one!(T)) + } + + #[inline] + pub fn add_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) + value, + *self.index(1) + value, + *self.index(2) + value, + *self.index(3) + value) + } + + #[inline] + pub fn sub_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) - value, + *self.index(1) - value, + *self.index(2) - value, + *self.index(3) - value) + } + + #[inline] + pub fn mul_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) * value, + *self.index(1) * value, + *self.index(2) * value, + *self.index(3) * value) + } + + #[inline] + pub fn div_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) / value, + *self.index(1) / value, + *self.index(2) / value, + *self.index(3) / value) + } + + #[inline] + pub fn rem_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) % value, + *self.index(1) % value, + *self.index(2) % value, + *self.index(3) % value) + } + + #[inline] + pub fn add_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) + *other.index(0), + *self.index(1) + *other.index(1), + *self.index(2) + *other.index(2), + *self.index(3) + *other.index(3)) + } + + #[inline] + pub fn sub_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) - *other.index(0), + *self.index(1) - *other.index(1), + *self.index(2) - *other.index(2), + *self.index(3) - *other.index(3)) + } + + #[inline] + pub fn mul_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) * *other.index(0), + *self.index(1) * *other.index(1), + *self.index(2) * *other.index(2), + *self.index(3) * *other.index(3)) + } + + #[inline] + pub fn div_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) / *other.index(0), + *self.index(1) / *other.index(1), + *self.index(2) / *other.index(2), + *self.index(3) / *other.index(3)) + } + + #[inline] + pub fn rem_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) % *other.index(0), + *self.index(1) % *other.index(1), + *self.index(2) % *other.index(2), + *self.index(3) % *other.index(3)) + } + + #[inline] + pub fn neg_self(&mut self) { + *self.index_mut(0) = -*self.index(0); + *self.index_mut(1) = -*self.index(1); + *self.index_mut(2) = -*self.index(2); + *self.index_mut(3) = -*self.index(3); + } + + #[inline] + pub fn add_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) + value; + *self.index_mut(1) = *self.index(1) + value; + *self.index_mut(2) = *self.index(2) + value; + *self.index_mut(3) = *self.index(3) + value; + } + + #[inline] + pub fn sub_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) - value; + *self.index_mut(1) = *self.index(1) - value; + *self.index_mut(2) = *self.index(2) - value; + *self.index_mut(3) = *self.index(3) - value; + } + + #[inline] + pub fn mul_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) * value; + *self.index_mut(1) = *self.index(1) * value; + *self.index_mut(2) = *self.index(2) * value; + *self.index_mut(3) = *self.index(3) * value; + } + + #[inline] + pub fn div_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) / value; + *self.index_mut(1) = *self.index(1) / value; + *self.index_mut(2) = *self.index(2) / value; + *self.index_mut(3) = *self.index(3) / value; + } + + #[inline] + pub fn rem_self_t(&mut self, value: T) { + *self.index_mut(0) = *self.index(0) % value; + *self.index_mut(1) = *self.index(1) % value; + *self.index_mut(2) = *self.index(2) % value; + *self.index_mut(3) = *self.index(3) % value; + } + + #[inline] + pub fn add_self_v(&mut self, other: &Vec4) { + *self.index_mut(0) = *self.index(0) + *other.index(0); + *self.index_mut(1) = *self.index(1) + *other.index(1); + *self.index_mut(2) = *self.index(2) + *other.index(2); + *self.index_mut(3) = *self.index(3) + *other.index(3); + } + + #[inline] + pub fn sub_self_v(&mut self, other: &Vec4) { + *self.index_mut(0) = *self.index(0) - *other.index(0); + *self.index_mut(1) = *self.index(1) - *other.index(1); + *self.index_mut(2) = *self.index(2) - *other.index(2); + *self.index_mut(3) = *self.index(3) - *other.index(3); + } + + #[inline] + pub fn mul_self_v(&mut self, other: &Vec4) { + *self.index_mut(0) = *self.index(0) * *other.index(0); + *self.index_mut(1) = *self.index(1) * *other.index(1); + *self.index_mut(2) = *self.index(2) * *other.index(2); + *self.index_mut(3) = *self.index(3) * *other.index(3); + } + + #[inline] + pub fn div_self_v(&mut self, other: &Vec4) { + *self.index_mut(0) = *self.index(0) / *other.index(0); + *self.index_mut(1) = *self.index(1) / *other.index(1); + *self.index_mut(2) = *self.index(2) / *other.index(2); + *self.index_mut(3) = *self.index(3) / *other.index(3); + } + + #[inline] + pub fn rem_self_v(&mut self, other: &Vec4) { + *self.index_mut(0) = *self.index(0) % *other.index(0); + *self.index_mut(1) = *self.index(1) % *other.index(1); + *self.index_mut(2) = *self.index(2) % *other.index(2); + *self.index_mut(3) = *self.index(3) % *other.index(3); + } #[inline] pub fn dot(&self, other: &Vec4) -> T { *self.index(0) * *other.index(0) + @@ -790,20 +1346,26 @@ impl Vec4 { } } -impl Neg> for Vec4 { +impl Neg> for Vec4 { #[inline] pub fn neg(&self) -> Vec4 { - Vec4::from_slice(self.map(|&x| -x)) + Vec4::new(-*self.index(0), + -*self.index(1), + -*self.index(2), + -*self.index(3)) } } -impl> Not> for Vec4 { +impl> Not> for Vec4 { pub fn not(&self) -> Vec4 { - Vec4::from_slice(self.map(|&x| !x)) + Vec4::new(!*self.index(0), + !*self.index(1), + !*self.index(2), + !*self.index(3)) } } -impl Vec4 { +impl Vec4 { #[inline] pub fn length2(&self) -> T { self.dot(self) @@ -862,24 +1424,104 @@ impl Vec4 { } } -impl Vec4 { - #[inline] pub fn lt_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x < value)) } - #[inline] pub fn le_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x <= value)) } - #[inline] pub fn ge_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x >= value)) } - #[inline] pub fn gt_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x > value)) } +impl Vec4 { + #[inline] + pub fn lt_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) < value, + *self.index(1) < value, + *self.index(2) < value, + *self.index(3) < value) + } - #[inline] pub fn lt_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a < b)) } - #[inline] pub fn le_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a <= b)) } - #[inline] pub fn ge_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a >= b)) } - #[inline] pub fn gt_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a > b)) } + #[inline] + pub fn le_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) <= value, + *self.index(1) <= value, + *self.index(2) <= value, + *self.index(3) <= value) + } + + #[inline] + pub fn ge_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) >= value, + *self.index(1) >= value, + *self.index(2) >= value, + *self.index(3) >= value) + } + + #[inline] + pub fn gt_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) > value, + *self.index(1) > value, + *self.index(2) > value, + *self.index(3) > value) + } + + #[inline] + pub fn lt_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) < *other.index(0), + *self.index(1) < *other.index(1), + *self.index(2) < *other.index(2), + *self.index(3) < *other.index(3)) + } + + #[inline] + pub fn le_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) <= *other.index(0), + *self.index(1) <= *other.index(1), + *self.index(2) <= *other.index(2), + *self.index(3) <= *other.index(3)) + } + + #[inline] + pub fn ge_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) >= *other.index(0), + *self.index(1) >= *other.index(1), + *self.index(2) >= *other.index(2), + *self.index(3) >= *other.index(3)) + } + + #[inline] + pub fn gt_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) > *other.index(0), + *self.index(1) > *other.index(1), + *self.index(2) > *other.index(2), + *self.index(3) > *other.index(3)) + } } -impl Vec4 { - #[inline] pub fn eq_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x == value)) } - #[inline] pub fn ne_t(&self, value: T) -> Vec4 { Vec4::from_slice(self.map(|&x| x != value)) } +impl Vec4 { + #[inline] + pub fn eq_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) == value, + *self.index(1) == value, + *self.index(2) == value, + *self.index(3) == value) + } - #[inline] pub fn eq_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a == b)) } - #[inline] pub fn ne_v(&self, other: &Vec4) -> Vec4 { Vec4::from_slice(self.zip(other, |&a, &b| a != b)) } + #[inline] + pub fn ne_t(&self, value: T) -> Vec4 { + Vec4::new(*self.index(0) != value, + *self.index(1) != value, + *self.index(2) != value, + *self.index(3) != value) + } + + #[inline] + pub fn eq_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) == *other.index(0), + *self.index(1) == *other.index(1), + *self.index(2) == *other.index(2), + *self.index(3) == *other.index(3)) + } + + #[inline] + pub fn ne_v(&self, other: &Vec4) -> Vec4 { + Vec4::new(*self.index(0) != *other.index(0), + *self.index(1) != *other.index(1), + *self.index(2) != *other.index(2), + *self.index(3) != *other.index(3)) + } } impl Vec4 { @@ -895,7 +1537,10 @@ impl Vec4 { #[inline] pub fn not(&self) -> Vec4 { - Vec4::from_slice(self.map(|&x| !x)) + Vec4::new(!*self.index(0), + !*self.index(1), + !*self.index(2), + !*self.index(3)) } }