Untangle vec macros

This commit is contained in:
Brendan Zabarauskas 2013-07-01 13:25:45 +10:00
parent b7530c3512
commit 1819846a4c
2 changed files with 468 additions and 273 deletions

View file

@ -17,7 +17,6 @@ pub use dim::Dimensional;
mod num_macros; mod num_macros;
mod dim_macros; mod dim_macros;
mod vec_macros;
#[deriving(Clone, Eq)] #[deriving(Clone, Eq)]
pub struct Vec2<T> { x: T, y: T } pub struct Vec2<T> { x: T, y: T }
@ -50,17 +49,24 @@ impl_dimensional_fns!(Vec2, T, 2)
impl_swap!(Vec2) impl_swap!(Vec2)
impl_approx!(Vec2) impl_approx!(Vec2)
impl_vec!(Vec2 { x, y }) impl<T> Vec2<T> {
impl_vec_clonable!(Vec2) #[inline]
impl_vec_numeric!(Vec2) pub fn new(x: T, y: T) -> Vec2<T> {
impl_vec_neg!(Vec2) Vec2 { x: x, y: y }
impl_vec_euclidean!(Vec2) }
impl_vec_ord!(Vec2) }
impl_vec_eq!(Vec2)
impl_vec_bool!(Vec2) impl<T:Clone> Vec2<T> {
impl_vec_not!(Vec2) #[inline]
pub fn from_value(value: T) -> Vec2<T> {
Vec2::new(value.clone(), value.clone())
}
}
impl<T:Clone + Num> Vec2<T> { impl<T:Clone + Num> Vec2<T> {
#[inline] pub fn identity() -> Vec2<T> { Vec2::from_value(one!(T)) }
#[inline] pub fn zero() -> Vec2<T> { Vec2::from_value(zero!(T)) }
#[inline] pub fn unit_x() -> Vec2<T> { Vec2::new(one!(T), zero!(T)) } #[inline] pub fn unit_x() -> Vec2<T> { Vec2::new(one!(T), zero!(T)) }
#[inline] pub fn unit_y() -> Vec2<T> { Vec2::new(zero!(T), one!(T)) } #[inline] pub fn unit_y() -> Vec2<T> { Vec2::new(zero!(T), one!(T)) }
@ -69,6 +75,145 @@ impl<T:Clone + Num> Vec2<T> {
(*self.index(0) * *other.index(1)) - (*self.index(0) * *other.index(1)) -
(*self.index(1) * *other.index(0)) (*self.index(1) * *other.index(0))
} }
#[inline] pub fn add_t(&self, value: T) -> Vec2<T> { Vec2::from_slice(self.map(|&x| x + value)) }
#[inline] pub fn sub_t(&self, value: T) -> Vec2<T> { Vec2::from_slice(self.map(|&x| x - value)) }
#[inline] pub fn mul_t(&self, value: T) -> Vec2<T> { Vec2::from_slice(self.map(|&x| x * value)) }
#[inline] pub fn div_t(&self, value: T) -> Vec2<T> { Vec2::from_slice(self.map(|&x| x / value)) }
#[inline] pub fn rem_t(&self, value: T) -> Vec2<T> { Vec2::from_slice(self.map(|&x| x % value)) }
#[inline] pub fn add_v(&self, other: &Vec2<T>) -> Vec2<T> { Vec2::from_slice(self.zip(other, |&a, &b| a + b)) }
#[inline] pub fn sub_v(&self, other: &Vec2<T>) -> Vec2<T> { Vec2::from_slice(self.zip(other, |&a, &b| a - b)) }
#[inline] pub fn mul_v(&self, other: &Vec2<T>) -> Vec2<T> { Vec2::from_slice(self.zip(other, |&a, &b| a * b)) }
#[inline] pub fn div_v(&self, other: &Vec2<T>) -> Vec2<T> { Vec2::from_slice(self.zip(other, |&a, &b| a / b)) }
#[inline] pub fn rem_v(&self, other: &Vec2<T>) -> Vec2<T> { 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<T>) { self.zip_mut(other, |a, &b| *a =*a + b) }
#[inline] pub fn sub_self_v(&mut self, other: &Vec2<T>) { self.zip_mut(other, |a, &b| *a =*a - b) }
#[inline] pub fn mul_self_v(&mut self, other: &Vec2<T>) { self.zip_mut(other, |a, &b| *a =*a * b) }
#[inline] pub fn div_self_v(&mut self, other: &Vec2<T>) { self.zip_mut(other, |a, &b| *a =*a / b) }
#[inline] pub fn rem_self_v(&mut self, other: &Vec2<T>) { self.zip_mut(other, |a, &b| *a =*a % b) }
#[inline] pub fn dot(&self, other: &Vec2<T>) -> T {
*self.index(0) * *other.index(0) +
*self.index(1) * *other.index(1)
}
}
impl<T:Clone + Num> Neg<Vec2<T>> for Vec2<T> {
#[inline]
pub fn neg(&self) -> Vec2<T> {
Vec2::from_slice(self.map(|&x| -x))
}
}
impl<T:Clone + Not<T>> Not<Vec2<T>> for Vec2<T> {
pub fn not(&self) -> Vec2<T> {
Vec2::from_slice(self.map(|&x| !x))
}
}
impl<T:Clone + Real> Vec2<T> {
#[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>) -> T {
other.sub_v(self).length2()
}
#[inline]
pub fn distance(&self, other: &Vec2<T>) -> T {
other.distance2(self).sqrt()
}
#[inline]
pub fn angle(&self, other: &Vec2<T>) -> T {
self.perp_dot(other).atan2(&self.dot(other))
}
#[inline]
pub fn normalize(&self) -> Vec2<T> {
self.mul_t(one!(T)/self.length())
}
#[inline]
pub fn normalize_to(&self, length: T) -> Vec2<T> {
self.mul_t(length / self.length())
}
#[inline]
pub fn lerp(&self, other: &Vec2<T>, amount: T) -> Vec2<T> {
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<T>, amount: T) {
let v = other.sub_v(self).mul_t(amount);
self.add_self_v(&v);
}
}
impl<T:Clone + Ord> Vec2<T> {
#[inline] pub fn lt_t(&self, value: T) -> Vec2<bool> { Vec2::from_slice(self.map(|&x| x < value)) }
#[inline] pub fn le_t(&self, value: T) -> Vec2<bool> { Vec2::from_slice(self.map(|&x| x <= value)) }
#[inline] pub fn ge_t(&self, value: T) -> Vec2<bool> { Vec2::from_slice(self.map(|&x| x >= value)) }
#[inline] pub fn gt_t(&self, value: T) -> Vec2<bool> { Vec2::from_slice(self.map(|&x| x > value)) }
#[inline] pub fn lt_v(&self, other: &Vec2<T>) -> Vec2<bool> { Vec2::from_slice(self.zip(other, |&a, &b| a < b)) }
#[inline] pub fn le_v(&self, other: &Vec2<T>) -> Vec2<bool> { Vec2::from_slice(self.zip(other, |&a, &b| a <= b)) }
#[inline] pub fn ge_v(&self, other: &Vec2<T>) -> Vec2<bool> { Vec2::from_slice(self.zip(other, |&a, &b| a >= b)) }
#[inline] pub fn gt_v(&self, other: &Vec2<T>) -> Vec2<bool> { Vec2::from_slice(self.zip(other, |&a, &b| a > b)) }
}
impl<T:Clone + Eq> Vec2<T> {
#[inline] pub fn eq_t(&self, value: T) -> Vec2<bool> { Vec2::from_slice(self.map(|&x| x == value)) }
#[inline] pub fn ne_t(&self, value: T) -> Vec2<bool> { Vec2::from_slice(self.map(|&x| x != value)) }
#[inline] pub fn eq_v(&self, other: &Vec2<T>) -> Vec2<bool> { Vec2::from_slice(self.zip(other, |&a, &b| a == b)) }
#[inline] pub fn ne_v(&self, other: &Vec2<T>) -> Vec2<bool> { Vec2::from_slice(self.zip(other, |&a, &b| a != b)) }
}
impl Vec2<bool> {
#[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<bool> {
Vec2::from_slice(self.map(|&x| !x))
}
} }
#[cfg(test)] #[cfg(test)]
@ -235,17 +380,24 @@ impl_dimensional_fns!(Vec3, T, 3)
impl_swap!(Vec3) impl_swap!(Vec3)
impl_approx!(Vec3) impl_approx!(Vec3)
impl_vec!(Vec3 { x, y, z }) impl<T> Vec3<T> {
impl_vec_clonable!(Vec3) #[inline]
impl_vec_numeric!(Vec3) pub fn new(x: T, y: T, z: T) -> Vec3<T> {
impl_vec_neg!(Vec3) Vec3 { x: x, y: y, z: z }
impl_vec_euclidean!(Vec3) }
impl_vec_ord!(Vec3) }
impl_vec_eq!(Vec3)
impl_vec_bool!(Vec3) impl<T:Clone> Vec3<T> {
impl_vec_not!(Vec3) #[inline]
pub fn from_value(value: T) -> Vec3<T> {
Vec3::new(value.clone(), value.clone(), value.clone())
}
}
impl<T:Clone + Num> Vec3<T> { impl<T:Clone + Num> Vec3<T> {
#[inline] pub fn identity() -> Vec3<T> { Vec3::from_value(one!(T)) }
#[inline] pub fn zero() -> Vec3<T> { Vec3::from_value(zero!(T)) }
#[inline] pub fn unit_x() -> Vec3<T> { Vec3::new(one!(T), zero!(T), zero!(T)) } #[inline] pub fn unit_x() -> Vec3<T> { Vec3::new(one!(T), zero!(T), zero!(T)) }
#[inline] pub fn unit_y() -> Vec3<T> { Vec3::new(zero!(T), one!(T), zero!(T)) } #[inline] pub fn unit_y() -> Vec3<T> { Vec3::new(zero!(T), one!(T), zero!(T)) }
#[inline] pub fn unit_z() -> Vec3<T> { Vec3::new(zero!(T), zero!(T), one!(T)) } #[inline] pub fn unit_z() -> Vec3<T> { Vec3::new(zero!(T), zero!(T), one!(T)) }
@ -261,6 +413,146 @@ impl<T:Clone + Num> Vec3<T> {
pub fn cross_self(&mut self, other: &Vec3<T>) { pub fn cross_self(&mut self, other: &Vec3<T>) {
*self = self.cross(other) *self = self.cross(other)
} }
#[inline] pub fn add_t(&self, value: T) -> Vec3<T> { Vec3::from_slice(self.map(|&x| x + value)) }
#[inline] pub fn sub_t(&self, value: T) -> Vec3<T> { Vec3::from_slice(self.map(|&x| x - value)) }
#[inline] pub fn mul_t(&self, value: T) -> Vec3<T> { Vec3::from_slice(self.map(|&x| x * value)) }
#[inline] pub fn div_t(&self, value: T) -> Vec3<T> { Vec3::from_slice(self.map(|&x| x / value)) }
#[inline] pub fn rem_t(&self, value: T) -> Vec3<T> { Vec3::from_slice(self.map(|&x| x % value)) }
#[inline] pub fn add_v(&self, other: &Vec3<T>) -> Vec3<T> { Vec3::from_slice(self.zip(other, |&a, &b| a + b)) }
#[inline] pub fn sub_v(&self, other: &Vec3<T>) -> Vec3<T> { Vec3::from_slice(self.zip(other, |&a, &b| a - b)) }
#[inline] pub fn mul_v(&self, other: &Vec3<T>) -> Vec3<T> { Vec3::from_slice(self.zip(other, |&a, &b| a * b)) }
#[inline] pub fn div_v(&self, other: &Vec3<T>) -> Vec3<T> { Vec3::from_slice(self.zip(other, |&a, &b| a / b)) }
#[inline] pub fn rem_v(&self, other: &Vec3<T>) -> Vec3<T> { 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<T>) { self.zip_mut(other, |a, &b| *a =*a + b) }
#[inline] pub fn sub_self_v(&mut self, other: &Vec3<T>) { self.zip_mut(other, |a, &b| *a =*a - b) }
#[inline] pub fn mul_self_v(&mut self, other: &Vec3<T>) { self.zip_mut(other, |a, &b| *a =*a * b) }
#[inline] pub fn div_self_v(&mut self, other: &Vec3<T>) { self.zip_mut(other, |a, &b| *a =*a / b) }
#[inline] pub fn rem_self_v(&mut self, other: &Vec3<T>) { self.zip_mut(other, |a, &b| *a =*a % b) }
#[inline] pub fn dot(&self, other: &Vec3<T>) -> T {
*self.index(0) * *other.index(0) +
*self.index(1) * *other.index(1) +
*self.index(2) * *other.index(2)
}
}
impl<T:Clone + Num> Neg<Vec3<T>> for Vec3<T> {
#[inline]
pub fn neg(&self) -> Vec3<T> {
Vec3::from_slice(self.map(|&x| -x))
}
}
impl<T:Clone + Not<T>> Not<Vec3<T>> for Vec3<T> {
pub fn not(&self) -> Vec3<T> {
Vec3::from_slice(self.map(|&x| !x))
}
}
impl<T:Clone + Real> Vec3<T> {
#[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>) -> T {
other.sub_v(self).length2()
}
#[inline]
pub fn distance(&self, other: &Vec3<T>) -> T {
other.distance2(self).sqrt()
}
#[inline]
pub fn angle(&self, other: &Vec3<T>) -> T {
self.cross(other).length().atan2(&self.dot(other))
}
#[inline]
pub fn normalize(&self) -> Vec3<T> {
self.mul_t(one!(T)/self.length())
}
#[inline]
pub fn normalize_to(&self, length: T) -> Vec3<T> {
self.mul_t(length / self.length())
}
#[inline]
pub fn lerp(&self, other: &Vec3<T>, amount: T) -> Vec3<T> {
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<T>, amount: T) {
let v = other.sub_v(self).mul_t(amount);
self.add_self_v(&v);
}
}
impl<T:Clone + Ord> Vec3<T> {
#[inline] pub fn lt_t(&self, value: T) -> Vec3<bool> { Vec3::from_slice(self.map(|&x| x < value)) }
#[inline] pub fn le_t(&self, value: T) -> Vec3<bool> { Vec3::from_slice(self.map(|&x| x <= value)) }
#[inline] pub fn ge_t(&self, value: T) -> Vec3<bool> { Vec3::from_slice(self.map(|&x| x >= value)) }
#[inline] pub fn gt_t(&self, value: T) -> Vec3<bool> { Vec3::from_slice(self.map(|&x| x > value)) }
#[inline] pub fn lt_v(&self, other: &Vec3<T>) -> Vec3<bool> { Vec3::from_slice(self.zip(other, |&a, &b| a < b)) }
#[inline] pub fn le_v(&self, other: &Vec3<T>) -> Vec3<bool> { Vec3::from_slice(self.zip(other, |&a, &b| a <= b)) }
#[inline] pub fn ge_v(&self, other: &Vec3<T>) -> Vec3<bool> { Vec3::from_slice(self.zip(other, |&a, &b| a >= b)) }
#[inline] pub fn gt_v(&self, other: &Vec3<T>) -> Vec3<bool> { Vec3::from_slice(self.zip(other, |&a, &b| a > b)) }
}
impl<T:Clone + Eq> Vec3<T> {
#[inline] pub fn eq_t(&self, value: T) -> Vec3<bool> { Vec3::from_slice(self.map(|&x| x == value)) }
#[inline] pub fn ne_t(&self, value: T) -> Vec3<bool> { Vec3::from_slice(self.map(|&x| x != value)) }
#[inline] pub fn eq_v(&self, other: &Vec3<T>) -> Vec3<bool> { Vec3::from_slice(self.zip(other, |&a, &b| a == b)) }
#[inline] pub fn ne_v(&self, other: &Vec3<T>) -> Vec3<bool> { Vec3::from_slice(self.zip(other, |&a, &b| a != b)) }
}
impl Vec3<bool> {
#[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<bool> {
Vec3::from_slice(self.map(|&x| !x))
}
} }
#[cfg(test)] #[cfg(test)]
@ -442,21 +734,169 @@ impl_dimensional_fns!(Vec4, T, 4)
impl_approx!(Vec4) impl_approx!(Vec4)
impl_swap!(Vec4) impl_swap!(Vec4)
impl_vec!(Vec4 { x, y, z, w }) impl<T> Vec4<T> {
impl_vec_clonable!(Vec4) #[inline]
impl_vec_numeric!(Vec4) pub fn new(x: T, y: T, z: T, w: T) -> Vec4<T> {
impl_vec_neg!(Vec4) Vec4 { x: x, y: y, z: z, w: w }
impl_vec_euclidean!(Vec4) }
impl_vec_ord!(Vec4) }
impl_vec_eq!(Vec4)
impl_vec_bool!(Vec4) impl<T:Clone> Vec4<T> {
impl_vec_not!(Vec4) #[inline]
pub fn from_value(value: T) -> Vec4<T> {
Vec4::new(value.clone(), value.clone(), value.clone(), value.clone())
}
}
impl<T:Clone + Num> Vec4<T> { impl<T:Clone + Num> Vec4<T> {
#[inline] pub fn identity() -> Vec4<T> { Vec4::from_value(one!(T)) }
#[inline] pub fn zero() -> Vec4<T> { Vec4::from_value(zero!(T)) }
#[inline] pub fn unit_x() -> Vec4<T> { Vec4::new(one!(T), zero!(T), zero!(T), zero!(T)) } #[inline] pub fn unit_x() -> Vec4<T> { Vec4::new(one!(T), zero!(T), zero!(T), zero!(T)) }
#[inline] pub fn unit_y() -> Vec4<T> { Vec4::new(zero!(T), one!(T), zero!(T), zero!(T)) } #[inline] pub fn unit_y() -> Vec4<T> { Vec4::new(zero!(T), one!(T), zero!(T), zero!(T)) }
#[inline] pub fn unit_z() -> Vec4<T> { Vec4::new(zero!(T), zero!(T), one!(T), zero!(T)) } #[inline] pub fn unit_z() -> Vec4<T> { Vec4::new(zero!(T), zero!(T), one!(T), zero!(T)) }
#[inline] pub fn unit_w() -> Vec4<T> { Vec4::new(zero!(T), zero!(T), zero!(T), one!(T)) } #[inline] pub fn unit_w() -> Vec4<T> { Vec4::new(zero!(T), zero!(T), zero!(T), one!(T)) }
#[inline] pub fn add_t(&self, value: T) -> Vec4<T> { Vec4::from_slice(self.map(|&x| x + value)) }
#[inline] pub fn sub_t(&self, value: T) -> Vec4<T> { Vec4::from_slice(self.map(|&x| x - value)) }
#[inline] pub fn mul_t(&self, value: T) -> Vec4<T> { Vec4::from_slice(self.map(|&x| x * value)) }
#[inline] pub fn div_t(&self, value: T) -> Vec4<T> { Vec4::from_slice(self.map(|&x| x / value)) }
#[inline] pub fn rem_t(&self, value: T) -> Vec4<T> { Vec4::from_slice(self.map(|&x| x % value)) }
#[inline] pub fn add_v(&self, other: &Vec4<T>) -> Vec4<T> { Vec4::from_slice(self.zip(other, |&a, &b| a + b)) }
#[inline] pub fn sub_v(&self, other: &Vec4<T>) -> Vec4<T> { Vec4::from_slice(self.zip(other, |&a, &b| a - b)) }
#[inline] pub fn mul_v(&self, other: &Vec4<T>) -> Vec4<T> { Vec4::from_slice(self.zip(other, |&a, &b| a * b)) }
#[inline] pub fn div_v(&self, other: &Vec4<T>) -> Vec4<T> { Vec4::from_slice(self.zip(other, |&a, &b| a / b)) }
#[inline] pub fn rem_v(&self, other: &Vec4<T>) -> Vec4<T> { 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<T>) { self.zip_mut(other, |a, &b| *a =*a + b) }
#[inline] pub fn sub_self_v(&mut self, other: &Vec4<T>) { self.zip_mut(other, |a, &b| *a =*a - b) }
#[inline] pub fn mul_self_v(&mut self, other: &Vec4<T>) { self.zip_mut(other, |a, &b| *a =*a * b) }
#[inline] pub fn div_self_v(&mut self, other: &Vec4<T>) { self.zip_mut(other, |a, &b| *a =*a / b) }
#[inline] pub fn rem_self_v(&mut self, other: &Vec4<T>) { self.zip_mut(other, |a, &b| *a =*a % b) }
#[inline] pub fn dot(&self, other: &Vec4<T>) -> 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<T:Clone + Num> Neg<Vec4<T>> for Vec4<T> {
#[inline]
pub fn neg(&self) -> Vec4<T> {
Vec4::from_slice(self.map(|&x| -x))
}
}
impl<T:Clone + Not<T>> Not<Vec4<T>> for Vec4<T> {
pub fn not(&self) -> Vec4<T> {
Vec4::from_slice(self.map(|&x| !x))
}
}
impl<T:Clone + Real> Vec4<T> {
#[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>) -> T {
other.sub_v(self).length2()
}
#[inline]
pub fn distance(&self, other: &Vec4<T>) -> T {
other.distance2(self).sqrt()
}
#[inline]
pub fn angle(&self, other: &Vec4<T>) -> T {
(self.dot(other) / (self.length() * other.length())).acos()
}
#[inline]
pub fn normalize(&self) -> Vec4<T> {
self.mul_t(one!(T)/self.length())
}
#[inline]
pub fn normalize_to(&self, length: T) -> Vec4<T> {
self.mul_t(length / self.length())
}
#[inline]
pub fn lerp(&self, other: &Vec4<T>, amount: T) -> Vec4<T> {
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<T>, amount: T) {
let v = other.sub_v(self).mul_t(amount);
self.add_self_v(&v);
}
}
impl<T:Clone + Ord> Vec4<T> {
#[inline] pub fn lt_t(&self, value: T) -> Vec4<bool> { Vec4::from_slice(self.map(|&x| x < value)) }
#[inline] pub fn le_t(&self, value: T) -> Vec4<bool> { Vec4::from_slice(self.map(|&x| x <= value)) }
#[inline] pub fn ge_t(&self, value: T) -> Vec4<bool> { Vec4::from_slice(self.map(|&x| x >= value)) }
#[inline] pub fn gt_t(&self, value: T) -> Vec4<bool> { Vec4::from_slice(self.map(|&x| x > value)) }
#[inline] pub fn lt_v(&self, other: &Vec4<T>) -> Vec4<bool> { Vec4::from_slice(self.zip(other, |&a, &b| a < b)) }
#[inline] pub fn le_v(&self, other: &Vec4<T>) -> Vec4<bool> { Vec4::from_slice(self.zip(other, |&a, &b| a <= b)) }
#[inline] pub fn ge_v(&self, other: &Vec4<T>) -> Vec4<bool> { Vec4::from_slice(self.zip(other, |&a, &b| a >= b)) }
#[inline] pub fn gt_v(&self, other: &Vec4<T>) -> Vec4<bool> { Vec4::from_slice(self.zip(other, |&a, &b| a > b)) }
}
impl<T:Clone + Eq> Vec4<T> {
#[inline] pub fn eq_t(&self, value: T) -> Vec4<bool> { Vec4::from_slice(self.map(|&x| x == value)) }
#[inline] pub fn ne_t(&self, value: T) -> Vec4<bool> { Vec4::from_slice(self.map(|&x| x != value)) }
#[inline] pub fn eq_v(&self, other: &Vec4<T>) -> Vec4<bool> { Vec4::from_slice(self.zip(other, |&a, &b| a == b)) }
#[inline] pub fn ne_v(&self, other: &Vec4<T>) -> Vec4<bool> { Vec4::from_slice(self.zip(other, |&a, &b| a != b)) }
}
impl Vec4<bool> {
#[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<bool> {
Vec4::from_slice(self.map(|&x| !x))
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -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<T> $Vec<T> {
#[inline]
pub fn new($($field: T),+) -> $Vec<T> {
$Vec { $($field: $field),+ }
}
}
)
)
macro_rules! impl_vec_clonable(
($Vec:ident) => (
impl<T:Clone> $Vec<T> {
#[inline]
pub fn from_value(value: T) -> $Vec<T> {
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<T:Clone + Num> $Vec<T> {
#[inline] pub fn identity() -> $Vec<T> { $Vec::from_value(one!(T)) }
#[inline] pub fn zero() -> $Vec<T> { $Vec::from_value(zero!(T)) }
#[inline] pub fn add_t(&self, value: T) -> $Vec<T> { $Vec::from_slice(self.map(|&x| x + value)) }
#[inline] pub fn sub_t(&self, value: T) -> $Vec<T> { $Vec::from_slice(self.map(|&x| x - value)) }
#[inline] pub fn mul_t(&self, value: T) -> $Vec<T> { $Vec::from_slice(self.map(|&x| x * value)) }
#[inline] pub fn div_t(&self, value: T) -> $Vec<T> { $Vec::from_slice(self.map(|&x| x / value)) }
#[inline] pub fn rem_t(&self, value: T) -> $Vec<T> { $Vec::from_slice(self.map(|&x| x % value)) }
#[inline] pub fn add_v(&self, other: &$Vec<T>) -> $Vec<T> { $Vec::from_slice(self.zip(other, |&a, &b| a + b)) }
#[inline] pub fn sub_v(&self, other: &$Vec<T>) -> $Vec<T> { $Vec::from_slice(self.zip(other, |&a, &b| a - b)) }
#[inline] pub fn mul_v(&self, other: &$Vec<T>) -> $Vec<T> { $Vec::from_slice(self.zip(other, |&a, &b| a * b)) }
#[inline] pub fn div_v(&self, other: &$Vec<T>) -> $Vec<T> { $Vec::from_slice(self.zip(other, |&a, &b| a / b)) }
#[inline] pub fn rem_v(&self, other: &$Vec<T>) -> $Vec<T> { $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<T>) { self.zip_mut(other, |a, &b| *a =*a + b) }
#[inline] pub fn sub_self_v(&mut self, other: &$Vec<T>) { self.zip_mut(other, |a, &b| *a =*a - b) }
#[inline] pub fn mul_self_v(&mut self, other: &$Vec<T>) { self.zip_mut(other, |a, &b| *a =*a * b) }
#[inline] pub fn div_self_v(&mut self, other: &$Vec<T>) { self.zip_mut(other, |a, &b| *a =*a / b) }
#[inline] pub fn rem_self_v(&mut self, other: &$Vec<T>) { self.zip_mut(other, |a, &b| *a =*a % b) }
#[inline] pub fn dot(&self, other: &$Vec<T>) -> 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<T:Clone + Num> Neg<$Vec<T>> for $Vec<T> {
#[inline]
pub fn neg(&self) -> $Vec<T> {
$Vec::from_slice(self.map(|&x| -x))
}
}
)
)
macro_rules! impl_vec_euclidean(
($Vec:ident) => (
impl<T:Clone + Real> $Vec<T> {
#[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>) -> T {
other.sub_v(self).length2()
}
#[inline]
pub fn distance(&self, other: &$Vec<T>) -> T {
other.distance2(self).sqrt()
}
#[inline]
pub fn angle(&self, other: &$Vec<T>) -> T {
vec_angle!($Vec)
}
#[inline]
pub fn normalize(&self) -> $Vec<T> {
self.mul_t(one!(T)/self.length())
}
#[inline]
pub fn normalize_to(&self, length: T) -> $Vec<T> {
self.mul_t(length / self.length())
}
#[inline]
pub fn lerp(&self, other: &$Vec<T>, amount: T) -> $Vec<T> {
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<T>, 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<T:Clone + Ord> $Vec<T> {
#[inline] pub fn lt_t(&self, value: T) -> $Vec<bool> { $Vec::from_slice(self.map(|&x| x < value)) }
#[inline] pub fn le_t(&self, value: T) -> $Vec<bool> { $Vec::from_slice(self.map(|&x| x <= value)) }
#[inline] pub fn ge_t(&self, value: T) -> $Vec<bool> { $Vec::from_slice(self.map(|&x| x >= value)) }
#[inline] pub fn gt_t(&self, value: T) -> $Vec<bool> { $Vec::from_slice(self.map(|&x| x > value)) }
#[inline] pub fn lt_v(&self, other: &$Vec<T>) -> $Vec<bool> { $Vec::from_slice(self.zip(other, |&a, &b| a < b)) }
#[inline] pub fn le_v(&self, other: &$Vec<T>) -> $Vec<bool> { $Vec::from_slice(self.zip(other, |&a, &b| a <= b)) }
#[inline] pub fn ge_v(&self, other: &$Vec<T>) -> $Vec<bool> { $Vec::from_slice(self.zip(other, |&a, &b| a >= b)) }
#[inline] pub fn gt_v(&self, other: &$Vec<T>) -> $Vec<bool> { $Vec::from_slice(self.zip(other, |&a, &b| a > b)) }
}
)
)
macro_rules! impl_vec_eq(
($Vec:ident) => (
impl<T:Clone + Eq> $Vec<T> {
#[inline] pub fn eq_t(&self, value: T) -> $Vec<bool> { $Vec::from_slice(self.map(|&x| x == value)) }
#[inline] pub fn ne_t(&self, value: T) -> $Vec<bool> { $Vec::from_slice(self.map(|&x| x != value)) }
#[inline] pub fn eq_v(&self, other: &$Vec<T>) -> $Vec<bool> { $Vec::from_slice(self.zip(other, |&a, &b| a == b)) }
#[inline] pub fn ne_v(&self, other: &$Vec<T>) -> $Vec<bool> { $Vec::from_slice(self.zip(other, |&a, &b| a != b)) }
}
)
)
macro_rules! impl_vec_bool(
($Vec:ident) => (
impl $Vec<bool> {
#[inline]
pub fn any(&self) -> bool { vec_any!($Vec) }
#[inline]
pub fn all(&self) -> bool { vec_all!($Vec) }
#[inline]
pub fn not(&self) -> $Vec<bool> {
$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<T:Clone + Not<T>> Not<$Vec<T>> for $Vec<T> {
pub fn not(&self) -> $Vec<T> {
$Vec::from_slice(self.map(|&x| !x))
}
}
)
)