diff --git a/src/vec.rs b/src/vec.rs index 30d9e51..e2ea289 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -17,7 +17,6 @@ pub use dim::Dimensional; mod num_macros; mod dim_macros; -mod vec_macros; #[deriving(Clone, Eq)] pub struct Vec2 { x: T, y: T } @@ -50,17 +49,24 @@ impl_dimensional_fns!(Vec2, T, 2) impl_swap!(Vec2) impl_approx!(Vec2) -impl_vec!(Vec2 { x, y }) -impl_vec_clonable!(Vec2) -impl_vec_numeric!(Vec2) -impl_vec_neg!(Vec2) -impl_vec_euclidean!(Vec2) -impl_vec_ord!(Vec2) -impl_vec_eq!(Vec2) -impl_vec_bool!(Vec2) -impl_vec_not!(Vec2) +impl Vec2 { + #[inline] + pub fn new(x: T, y: T) -> Vec2 { + Vec2 { x: x, y: y } + } +} + +impl Vec2 { + #[inline] + pub fn from_value(value: T) -> Vec2 { + 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)) } + #[inline] pub fn unit_x() -> Vec2 { Vec2::new(one!(T), zero!(T)) } #[inline] pub fn unit_y() -> Vec2 { Vec2::new(zero!(T), one!(T)) } @@ -69,6 +75,145 @@ impl Vec2 { (*self.index(0) * *other.index(1)) - (*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_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 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 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 dot(&self, other: &Vec2) -> T { + *self.index(0) * *other.index(0) + + *self.index(1) * *other.index(1) + } +} + +impl Neg> for Vec2 { + #[inline] + pub fn neg(&self) -> Vec2 { + Vec2::from_slice(self.map(|&x| -x)) + } +} + +impl> Not> for Vec2 { + pub fn not(&self) -> Vec2 { + Vec2::from_slice(self.map(|&x| !x)) + } +} + +impl Vec2 { + #[inline] + pub fn length2(&self) -> T { + self.dot(self) + } + + #[inline] + pub fn length(&self) -> T { + self.length2().sqrt() + } + + #[inline] + pub fn distance2(&self, other: &Vec2) -> T { + other.sub_v(self).length2() + } + + #[inline] + pub fn distance(&self, other: &Vec2) -> T { + other.distance2(self).sqrt() + } + + #[inline] + pub fn angle(&self, other: &Vec2) -> T { + self.perp_dot(other).atan2(&self.dot(other)) + } + + #[inline] + pub fn normalize(&self) -> Vec2 { + self.mul_t(one!(T)/self.length()) + } + + #[inline] + pub fn normalize_to(&self, length: T) -> Vec2 { + self.mul_t(length / self.length()) + } + + #[inline] + pub fn lerp(&self, other: &Vec2, amount: T) -> Vec2 { + self.add_v(&other.sub_v(self).mul_t(amount)) + } + + #[inline] + pub fn normalize_self(&mut self) { + let rlen = self.length().recip(); + self.mul_self_t(rlen); + } + + #[inline] + pub fn normalize_self_to(&mut self, length: T) { + let n = length / self.length(); + self.mul_self_t(n); + } + + pub fn lerp_self(&mut self, other: &Vec2, amount: T) { + let v = other.sub_v(self).mul_t(amount); + self.add_self_v(&v); + } +} + +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)) } + + #[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)) } +} + +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)) } + + #[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)) } +} + +impl Vec2 { + #[inline] + pub fn any(&self) -> bool { + *self.index(0) || *self.index(1) + } + + #[inline] + pub fn all(&self) -> bool { + *self.index(0) && *self.index(1) + } + + #[inline] + pub fn not(&self) -> Vec2 { + Vec2::from_slice(self.map(|&x| !x)) + } } #[cfg(test)] @@ -235,17 +380,24 @@ impl_dimensional_fns!(Vec3, T, 3) impl_swap!(Vec3) impl_approx!(Vec3) -impl_vec!(Vec3 { x, y, z }) -impl_vec_clonable!(Vec3) -impl_vec_numeric!(Vec3) -impl_vec_neg!(Vec3) -impl_vec_euclidean!(Vec3) -impl_vec_ord!(Vec3) -impl_vec_eq!(Vec3) -impl_vec_bool!(Vec3) -impl_vec_not!(Vec3) +impl Vec3 { + #[inline] + pub fn new(x: T, y: T, z: T) -> Vec3 { + Vec3 { x: x, y: y, z: z } + } +} + +impl Vec3 { + #[inline] + pub fn from_value(value: T) -> Vec3 { + 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)) } + #[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)) } @@ -261,6 +413,146 @@ impl Vec3 { pub fn cross_self(&mut self, other: &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_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 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 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 dot(&self, other: &Vec3) -> T { + *self.index(0) * *other.index(0) + + *self.index(1) * *other.index(1) + + *self.index(2) * *other.index(2) + } +} + +impl Neg> for Vec3 { + #[inline] + pub fn neg(&self) -> Vec3 { + Vec3::from_slice(self.map(|&x| -x)) + } +} + +impl> Not> for Vec3 { + pub fn not(&self) -> Vec3 { + Vec3::from_slice(self.map(|&x| !x)) + } +} + +impl Vec3 { + #[inline] + pub fn length2(&self) -> T { + self.dot(self) + } + + #[inline] + pub fn length(&self) -> T { + self.length2().sqrt() + } + + #[inline] + pub fn distance2(&self, other: &Vec3) -> T { + other.sub_v(self).length2() + } + + #[inline] + pub fn distance(&self, other: &Vec3) -> T { + other.distance2(self).sqrt() + } + + #[inline] + pub fn angle(&self, other: &Vec3) -> T { + self.cross(other).length().atan2(&self.dot(other)) + } + + #[inline] + pub fn normalize(&self) -> Vec3 { + self.mul_t(one!(T)/self.length()) + } + + #[inline] + pub fn normalize_to(&self, length: T) -> Vec3 { + self.mul_t(length / self.length()) + } + + #[inline] + pub fn lerp(&self, other: &Vec3, amount: T) -> Vec3 { + self.add_v(&other.sub_v(self).mul_t(amount)) + } + + #[inline] + pub fn normalize_self(&mut self) { + let rlen = self.length().recip(); + self.mul_self_t(rlen); + } + + #[inline] + pub fn normalize_self_to(&mut self, length: T) { + let n = length / self.length(); + self.mul_self_t(n); + } + + pub fn lerp_self(&mut self, other: &Vec3, amount: T) { + let v = other.sub_v(self).mul_t(amount); + self.add_self_v(&v); + } +} + +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)) } + + #[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)) } +} + +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)) } + + #[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)) } +} + +impl Vec3 { + #[inline] + pub fn any(&self) -> bool { + *self.index(0) || *self.index(1) || *self.index(2) + } + + #[inline] + pub fn all(&self) -> bool { + *self.index(0) && *self.index(1) && *self.index(2) + } + + #[inline] + pub fn not(&self) -> Vec3 { + Vec3::from_slice(self.map(|&x| !x)) + } } #[cfg(test)] @@ -442,21 +734,169 @@ impl_dimensional_fns!(Vec4, T, 4) impl_approx!(Vec4) impl_swap!(Vec4) -impl_vec!(Vec4 { x, y, z, w }) -impl_vec_clonable!(Vec4) -impl_vec_numeric!(Vec4) -impl_vec_neg!(Vec4) -impl_vec_euclidean!(Vec4) -impl_vec_ord!(Vec4) -impl_vec_eq!(Vec4) -impl_vec_bool!(Vec4) -impl_vec_not!(Vec4) +impl Vec4 { + #[inline] + pub fn new(x: T, y: T, z: T, w: T) -> Vec4 { + Vec4 { x: x, y: y, z: z, w: w } + } +} + +impl Vec4 { + #[inline] + pub fn from_value(value: T) -> Vec4 { + 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)) } + #[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 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 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 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 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 dot(&self, other: &Vec4) -> T { + *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 Neg> for Vec4 { + #[inline] + pub fn neg(&self) -> Vec4 { + Vec4::from_slice(self.map(|&x| -x)) + } +} + +impl> Not> for Vec4 { + pub fn not(&self) -> Vec4 { + Vec4::from_slice(self.map(|&x| !x)) + } +} + +impl Vec4 { + #[inline] + pub fn length2(&self) -> T { + self.dot(self) + } + + #[inline] + pub fn length(&self) -> T { + self.length2().sqrt() + } + + #[inline] + pub fn distance2(&self, other: &Vec4) -> T { + other.sub_v(self).length2() + } + + #[inline] + pub fn distance(&self, other: &Vec4) -> T { + other.distance2(self).sqrt() + } + + #[inline] + pub fn angle(&self, other: &Vec4) -> T { + (self.dot(other) / (self.length() * other.length())).acos() + } + + #[inline] + pub fn normalize(&self) -> Vec4 { + self.mul_t(one!(T)/self.length()) + } + + #[inline] + pub fn normalize_to(&self, length: T) -> Vec4 { + self.mul_t(length / self.length()) + } + + #[inline] + pub fn lerp(&self, other: &Vec4, amount: T) -> Vec4 { + self.add_v(&other.sub_v(self).mul_t(amount)) + } + + #[inline] + pub fn normalize_self(&mut self) { + let rlen = self.length().recip(); + self.mul_self_t(rlen); + } + + #[inline] + pub fn normalize_self_to(&mut self, length: T) { + let n = length / self.length(); + self.mul_self_t(n); + } + + pub fn lerp_self(&mut self, other: &Vec4, amount: T) { + let v = other.sub_v(self).mul_t(amount); + self.add_self_v(&v); + } +} + +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)) } + + #[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)) } +} + +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)) } + + #[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)) } +} + +impl Vec4 { + #[inline] + pub fn any(&self) -> bool { + *self.index(0) || *self.index(1) || *self.index(2) || *self.index(3) + } + + #[inline] + pub fn all(&self) -> bool { + *self.index(0) && *self.index(1) && *self.index(2) && *self.index(3) + } + + #[inline] + pub fn not(&self) -> Vec4 { + Vec4::from_slice(self.map(|&x| !x)) + } } #[cfg(test)] diff --git a/src/vec_macros.rs b/src/vec_macros.rs deleted file mode 100644 index 3402502..0000000 --- a/src/vec_macros.rs +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2013 The Lmath Developers. For a full listing of the authors, -// refer to the AUTHORS file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#[macro_escape]; - -macro_rules! impl_vec( - ($Vec:ident { $($field:ident),+ }) => ( - impl $Vec { - #[inline] - pub fn new($($field: T),+) -> $Vec { - $Vec { $($field: $field),+ } - } - } - ) -) - -macro_rules! impl_vec_clonable( - ($Vec:ident) => ( - impl $Vec { - #[inline] - pub fn from_value(value: T) -> $Vec { - vec_from_value!($Vec) - } - } - ) -) - -macro_rules! vec_from_value( - (Vec2) => (Vec2::new(value.clone(), value.clone())); - (Vec3) => (Vec3::new(value.clone(), value.clone(), value.clone())); - (Vec4) => (Vec4::new(value.clone(), value.clone(), value.clone(), value.clone())); -) - -macro_rules! impl_vec_numeric( - ($Vec:ident) => ( - impl $Vec { - #[inline] pub fn identity() -> $Vec { $Vec::from_value(one!(T)) } - #[inline] pub fn zero() -> $Vec { $Vec::from_value(zero!(T)) } - - #[inline] pub fn add_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x + value)) } - #[inline] pub fn sub_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x - value)) } - #[inline] pub fn mul_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x * value)) } - #[inline] pub fn div_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x / value)) } - #[inline] pub fn rem_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x % value)) } - - #[inline] pub fn add_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a + b)) } - #[inline] pub fn sub_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a - b)) } - #[inline] pub fn mul_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a * b)) } - #[inline] pub fn div_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a / b)) } - #[inline] pub fn rem_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a % b)) } - - #[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 add_self_v(&mut self, other: &$Vec) { self.zip_mut(other, |a, &b| *a =*a + b) } - #[inline] pub fn sub_self_v(&mut self, other: &$Vec) { self.zip_mut(other, |a, &b| *a =*a - b) } - #[inline] pub fn mul_self_v(&mut self, other: &$Vec) { self.zip_mut(other, |a, &b| *a =*a * b) } - #[inline] pub fn div_self_v(&mut self, other: &$Vec) { self.zip_mut(other, |a, &b| *a =*a / b) } - #[inline] pub fn rem_self_v(&mut self, other: &$Vec) { self.zip_mut(other, |a, &b| *a =*a % b) } - - #[inline] pub fn dot(&self, other: &$Vec) -> T { vec_dot!($Vec) } - } - ) -) - -macro_rules! vec_dot( - (Vec2) => ( - *self.index(0) * *other.index(0) + - *self.index(1) * *other.index(1) - ); - (Vec3) => ( - *self.index(0) * *other.index(0) + - *self.index(1) * *other.index(1) + - *self.index(2) * *other.index(2) - ); - (Vec4) => ( - *self.index(0) * *other.index(0) + - *self.index(1) * *other.index(1) + - *self.index(2) * *other.index(2) + - *self.index(3) * *other.index(3) - ); -) - -macro_rules! impl_vec_neg( - ($Vec:ident) => ( - impl Neg<$Vec> for $Vec { - #[inline] - pub fn neg(&self) -> $Vec { - $Vec::from_slice(self.map(|&x| -x)) - } - } - ) -) - -macro_rules! impl_vec_euclidean( - ($Vec:ident) => ( - impl $Vec { - #[inline] - pub fn length2(&self) -> T { - self.dot(self) - } - - #[inline] - pub fn length(&self) -> T { - self.length2().sqrt() - } - - #[inline] - pub fn distance2(&self, other: &$Vec) -> T { - other.sub_v(self).length2() - } - - #[inline] - pub fn distance(&self, other: &$Vec) -> T { - other.distance2(self).sqrt() - } - - #[inline] - pub fn angle(&self, other: &$Vec) -> T { - vec_angle!($Vec) - } - - #[inline] - pub fn normalize(&self) -> $Vec { - self.mul_t(one!(T)/self.length()) - } - - #[inline] - pub fn normalize_to(&self, length: T) -> $Vec { - self.mul_t(length / self.length()) - } - - #[inline] - pub fn lerp(&self, other: &$Vec, amount: T) -> $Vec { - self.add_v(&other.sub_v(self).mul_t(amount)) - } - - #[inline] - pub fn normalize_self(&mut self) { - let rlen = self.length().recip(); - self.mul_self_t(rlen); - } - - #[inline] - pub fn normalize_self_to(&mut self, length: T) { - let n = length / self.length(); - self.mul_self_t(n); - } - - pub fn lerp_self(&mut self, other: &$Vec, amount: T) { - let v = other.sub_v(self).mul_t(amount); - self.add_self_v(&v); - } - } - ) -) - -macro_rules! vec_angle( - (Vec2) => (self.perp_dot(other).atan2(&self.dot(other))); - (Vec3) => (self.cross(other).length().atan2(&self.dot(other))); - (Vec4) => ((self.dot(other) / (self.length() * other.length())).acos()); -) - -macro_rules! impl_vec_ord( - ($Vec:ident) => ( - impl $Vec { - #[inline] pub fn lt_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x < value)) } - #[inline] pub fn le_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x <= value)) } - #[inline] pub fn ge_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x >= value)) } - #[inline] pub fn gt_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x > value)) } - - #[inline] pub fn lt_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a < b)) } - #[inline] pub fn le_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a <= b)) } - #[inline] pub fn ge_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a >= b)) } - #[inline] pub fn gt_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a > b)) } - } - ) -) - -macro_rules! impl_vec_eq( - ($Vec:ident) => ( - impl $Vec { - #[inline] pub fn eq_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x == value)) } - #[inline] pub fn ne_t(&self, value: T) -> $Vec { $Vec::from_slice(self.map(|&x| x != value)) } - - #[inline] pub fn eq_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a == b)) } - #[inline] pub fn ne_v(&self, other: &$Vec) -> $Vec { $Vec::from_slice(self.zip(other, |&a, &b| a != b)) } - } - ) -) - -macro_rules! impl_vec_bool( - ($Vec:ident) => ( - impl $Vec { - #[inline] - pub fn any(&self) -> bool { vec_any!($Vec) } - - #[inline] - pub fn all(&self) -> bool { vec_all!($Vec) } - - #[inline] - pub fn not(&self) -> $Vec { - $Vec::from_slice(self.map(|&x| !x)) - } - } - ) -) - -macro_rules! vec_any( - (Vec2) => (*self.index(0) || *self.index(1)); - (Vec3) => (*self.index(0) || *self.index(1) || *self.index(2)); - (Vec4) => (*self.index(0) || *self.index(1) || *self.index(2) || *self.index(3)); -) - -macro_rules! vec_all( - (Vec2) => (*self.index(0) && *self.index(1)); - (Vec3) => (*self.index(0) && *self.index(1) && *self.index(2)); - (Vec4) => (*self.index(0) && *self.index(1) && *self.index(2) && *self.index(3)); -) - -macro_rules! impl_vec_not( - ($Vec:ident) => ( - impl> Not<$Vec> for $Vec { - pub fn not(&self) -> $Vec { - $Vec::from_slice(self.map(|&x| !x)) - } - } - ) -)