// 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. use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One}; #[deriving(Eq)] pub struct Vec2 { x: T, y: T } impl Vec2 { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] } #[inline] pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { &'a mut self.as_mut_slice()[i] } #[inline] pub fn as_slice<'a>(&'a self) -> &'a [T,..2] { unsafe { transmute(self) } } #[inline] pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T,..2] { unsafe { transmute(self) } } } impl Vec2 { #[inline] pub fn new(x: T, y: T ) -> Vec2 { Vec2 { x: x, y: y } } #[inline] pub fn from_value(value: T) -> Vec2 { Vec2::new(value, value) } #[inline] pub fn swap(&mut self, a: uint, b: uint) { let tmp = *self.index(a); *self.index_mut(a) = *self.index(b); *self.index_mut(b) = tmp; } #[inline(always)] pub fn map(&self, f: &fn(&T) -> T) -> Vec2 { Vec2::new(f(self.index(0)), f(self.index(1))) } } impl Vec2 { #[inline] pub fn identity() -> Vec2 { Vec2::new(One::one::(), One::one::()) } #[inline] pub fn zero() -> Vec2 { Vec2::new(Zero::zero::(), Zero::zero::()) } #[inline] pub fn unit_x() -> Vec2 { Vec2::new(One::one::(), Zero::zero::()) } #[inline] pub fn unit_y() -> Vec2 { Vec2::new(Zero::zero::(), One::one::()) } #[inline] pub fn is_zero(&self) -> bool { *self.index(0) == Zero::zero() && *self.index(1) == Zero::zero() } #[inline] pub fn add_t(&self, value: T) -> Vec2 { Vec2::new(*self.index(0) + value, *self.index(1) + value) } #[inline] pub fn sub_t(&self, value: T) -> Vec2 { Vec2::new(*self.index(0) - value, *self.index(1) - value) } #[inline] pub fn mul_t(&self, value: T) -> Vec2 { Vec2::new(*self.index(0) * value, *self.index(1) * value) } #[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) += value; *self.index_mut(1) += value; } #[inline] pub fn sub_self_t(&mut self, value: T) { *self.index_mut(0) -= value; *self.index_mut(1) -= value; } #[inline] pub fn mul_self_t(&mut self, value: T) { *self.index_mut(0) *= value; *self.index_mut(1) *= value; } #[inline] pub fn div_self_t(&mut self, value: T) { *self.index_mut(0) /= value; *self.index_mut(1) /= value; } #[inline] pub fn rem_self_t(&mut self, value: T) { *self.index_mut(0) %= value; *self.index_mut(1) %= value; } #[inline] pub fn add_self_v(&mut self, other: &Vec2) { *self.index_mut(0) += *other.index(0); *self.index_mut(1) += *other.index(1); } #[inline] pub fn sub_self_v(&mut self, other: &Vec2) { *self.index_mut(0) -= *other.index(0); *self.index_mut(1) -= *other.index(1); } #[inline] pub fn mul_self_v(&mut self, other: &Vec2) { *self.index_mut(0) *= *other.index(0); *self.index_mut(1) *= *other.index(1); } #[inline] pub fn div_self_v(&mut self, other: &Vec2) { *self.index_mut(0) /= *other.index(0); *self.index_mut(1) /= *other.index(1); } #[inline] pub fn rem_self_v(&mut self, other: &Vec2) { *self.index_mut(0) /= *other.index(0); *self.index_mut(1) /= *other.index(1); } #[inline] pub fn dot(&self, other: &Vec2) -> T { *self.index(0) * *other.index(0) + *self.index(1) * *other.index(1) } #[inline] pub fn perp_dot(&self, other: &Vec2) -> T { (*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0)) } #[inline] pub fn to_homogeneous(&self) -> Vec3 { Vec3::new(self.x, self.y, Zero::zero()) } } impl Neg> for Vec2 { #[inline] pub fn neg(&self) -> Vec2 { Vec2::new(-self.index(0), -self.index(1)) } } 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::one::()/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 n = One::one::() / self.length(); self.mul_self_t(n); } #[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> ApproxEq for Vec2 { #[inline] pub fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() } #[inline] pub fn approx_eq(&self, other: &Vec2) -> bool { self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) } #[inline] pub fn approx_eq_eps(&self, other: &Vec2, epsilon: &T) -> bool { self.index(0).approx_eq_eps(other.index(0), epsilon) && self.index(1).approx_eq_eps(other.index(1), epsilon) } } impl Vec2 { #[inline] pub fn lt_t(&self, value: T) -> Vec2 { Vec2::new(*self.index(0) < value, *self.index(1) < value) } #[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::new(*self.index(0) == value, *self.index(1) == value) } #[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 { #[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::new(!*self.index(0), !*self.index(1)) } } // GLSL-style type aliases pub type vec2 = Vec2; pub type dvec2 = Vec2; pub type bvec2 = Vec2; pub type ivec2 = Vec2; pub type uvec2 = Vec2; // Rust-style type aliases pub type Vec2f = Vec2; pub type Vec2f32 = Vec2; pub type Vec2f64 = Vec2; pub type Vec2i = Vec2; pub type Vec2i8 = Vec2; pub type Vec2i16 = Vec2; pub type Vec2i32 = Vec2; pub type Vec2i64 = Vec2; pub type Vec2u = Vec2; pub type Vec2u8 = Vec2; pub type Vec2u16 = Vec2; pub type Vec2u32 = Vec2; pub type Vec2u64 = Vec2; pub type Vec2b = Vec2; #[deriving(Eq)] pub struct Vec3 { x: T, y: T, z: T } impl Vec3 { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] } #[inline] pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { &'a mut self.as_mut_slice()[i] } #[inline] pub fn as_slice<'a>(&'a self) -> &'a [T,..3] { unsafe { transmute(self) } } #[inline] pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T,..3] { unsafe { transmute(self) } } } impl Vec3 { #[inline] pub fn new(x: T, y: T, z: T ) -> Vec3 { Vec3 { x: x, y: y, z: z } } #[inline] pub fn from_value(value: T) -> Vec3 { Vec3::new(value, value, value) } #[inline] pub fn swap(&mut self, a: uint, b: uint) { let tmp = *self.index(a); *self.index_mut(a) = *self.index(b); *self.index_mut(b) = tmp; } #[inline(always)] pub fn map(&self, f: &fn(&T) -> T) -> Vec3 { Vec3::new(f(self.index(0)), f(self.index(1)), f(self.index(2))) } } impl Vec3 { #[inline] pub fn identity() -> Vec3 { Vec3::new(One::one::(), One::one::(), One::one::()) } #[inline] pub fn zero() -> Vec3 { Vec3::new(Zero::zero::(), Zero::zero::(), Zero::zero::()) } #[inline] pub fn unit_x() -> Vec3 { Vec3::new(One::one::(), Zero::zero::(), Zero::zero::()) } #[inline] pub fn unit_y() -> Vec3 { Vec3::new(Zero::zero::(), One::one::(), Zero::zero::()) } #[inline] pub fn unit_z() -> Vec3 { Vec3::new(Zero::zero::(), Zero::zero::(), One::one::()) } #[inline] pub fn is_zero(&self) -> bool { *self.index(0) == Zero::zero() && *self.index(1) == Zero::zero() && *self.index(2) == Zero::zero() } #[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 sub_t(&self, value: T) -> Vec3 { Vec3::new(*self.index(0) - value, *self.index(1) - value, *self.index(2) - value) } #[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 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) += value; *self.index_mut(1) += value; *self.index_mut(2) += value; } #[inline] pub fn sub_self_t(&mut self, value: T) { *self.index_mut(0) -= value; *self.index_mut(1) -= value; *self.index_mut(2) -= value; } #[inline] pub fn mul_self_t(&mut self, value: T) { *self.index_mut(0) *= value; *self.index_mut(1) *= value; *self.index_mut(2) *= value; } #[inline] pub fn div_self_t(&mut self, value: T) { *self.index_mut(0) /= value; *self.index_mut(1) /= value; *self.index_mut(2) /= value; } #[inline] pub fn rem_self_t(&mut self, value: T) { *self.index_mut(0) %= value; *self.index_mut(1) %= value; *self.index_mut(2) %= value; } #[inline] pub fn add_self_v(&mut self, other: &Vec3) { *self.index_mut(0) += *other.index(0); *self.index_mut(1) += *other.index(1); *self.index_mut(2) += *other.index(2); } #[inline] pub fn sub_self_v(&mut self, other: &Vec3) { *self.index_mut(0) -= *other.index(0); *self.index_mut(1) -= *other.index(1); *self.index_mut(2) -= *other.index(2); } #[inline] pub fn mul_self_v(&mut self, other: &Vec3) { *self.index_mut(0) *= *other.index(0); *self.index_mut(1) *= *other.index(1); *self.index_mut(2) *= *other.index(2); } #[inline] pub fn div_self_v(&mut self, other: &Vec3) { *self.index_mut(0) /= *other.index(0); *self.index_mut(1) /= *other.index(1); *self.index_mut(2) /= *other.index(2); } #[inline] pub fn rem_self_v(&mut self, other: &Vec3) { *self.index_mut(0) /= *other.index(0); *self.index_mut(1) /= *other.index(1); *self.index_mut(2) /= *other.index(2); } #[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) } #[inline] pub fn cross(&self, other: &Vec3) -> Vec3 { Vec3::new((*self.index(1) * *other.index(2)) - (*self.index(2) * *other.index(1)), (*self.index(2) * *other.index(0)) - (*self.index(0) * *other.index(2)), (*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0))) } #[inline] pub fn cross_self(&mut self, other: &Vec3) { *self = self.cross(other) } #[inline] pub fn to_homogeneous(&self) -> Vec4 { Vec4::new(self.x, self.y, self.z, Zero::zero()) } } impl Neg> for Vec3 { #[inline] pub fn neg(&self) -> Vec3 { Vec3::new(-self.index(0), -self.index(1), -self.index(2)) } } 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::one::()/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 n = One::one::() / self.length(); self.mul_self_t(n); } #[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> ApproxEq for Vec3 { #[inline] pub fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() } #[inline] pub fn approx_eq(&self, other: &Vec3) -> bool { self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) } #[inline] pub fn approx_eq_eps(&self, other: &Vec3, 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) } } 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 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::new(*self.index(0) == value, *self.index(1) == value, *self.index(2) == value) } #[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 { #[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::new(!*self.index(0), !*self.index(1), !*self.index(2)) } } // GLSL-style type aliases pub type vec3 = Vec3; pub type dvec3 = Vec3; pub type bvec3 = Vec3; pub type ivec3 = Vec3; pub type uvec3 = Vec3; // Rust-style type aliases pub type Vec3f = Vec3; pub type Vec3f32 = Vec3; pub type Vec3f64 = Vec3; pub type Vec3i = Vec3; pub type Vec3i8 = Vec3; pub type Vec3i16 = Vec3; pub type Vec3i32 = Vec3; pub type Vec3i64 = Vec3; pub type Vec3u = Vec3; pub type Vec3u8 = Vec3; pub type Vec3u16 = Vec3; pub type Vec3u32 = Vec3; pub type Vec3u64 = Vec3; pub type Vec3b = Vec3; #[deriving(Eq)] pub struct Vec4 { x: T, y: T, z: T, w: T } impl Vec4 { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] } #[inline] pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { &'a mut self.as_mut_slice()[i] } #[inline] pub fn as_slice<'a>(&'a self) -> &'a [T,..4] { unsafe { transmute(self) } } #[inline] pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T,..4] { unsafe { transmute(self) } } } impl Vec4 { #[inline] pub fn new(x: T, y: T, z: T, w: T ) -> Vec4 { Vec4 { x: x, y: y, z: z, w: w } } #[inline] pub fn from_value(value: T) -> Vec4 { Vec4::new(value, value, value, value) } #[inline] pub fn swap(&mut self, a: uint, b: uint) { let tmp = *self.index(a); *self.index_mut(a) = *self.index(b); *self.index_mut(b) = tmp; } #[inline(always)] pub fn map(&self, f: &fn(&T) -> T) -> Vec4 { Vec4::new(f(self.index(0)), f(self.index(1)), f(self.index(2)), f(self.index(3))) } } impl Vec4 { #[inline] pub fn identity() -> Vec4 { Vec4::new(One::one::(), One::one::(), One::one::(), One::one::()) } #[inline] pub fn zero() -> Vec4 { Vec4::new(Zero::zero::(), Zero::zero::(), Zero::zero::(), Zero::zero::()) } #[inline] pub fn unit_x() -> Vec4 { Vec4::new(One::one::(), Zero::zero::(), Zero::zero::(), Zero::zero::()) } #[inline] pub fn unit_y() -> Vec4 { Vec4::new(Zero::zero::(), One::one::(), Zero::zero::(), Zero::zero::()) } #[inline] pub fn unit_z() -> Vec4 { Vec4::new(Zero::zero::(), Zero::zero::(), One::one::(), Zero::zero::()) } #[inline] pub fn unit_w() -> Vec4 { Vec4::new(Zero::zero::(), Zero::zero::(), Zero::zero::(), One::one::()) } #[inline] pub fn is_zero(&self) -> bool { *self.index(0) == Zero::zero() && *self.index(1) == Zero::zero() && *self.index(2) == Zero::zero() && *self.index(3) == Zero::zero() } #[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) += value; *self.index_mut(1) += value; *self.index_mut(2) += value; *self.index_mut(3) += value; } #[inline] pub fn sub_self_t(&mut self, value: T) { *self.index_mut(0) -= value; *self.index_mut(1) -= value; *self.index_mut(2) -= value; *self.index_mut(3) -= value; } #[inline] pub fn mul_self_t(&mut self, value: T) { *self.index_mut(0) *= value; *self.index_mut(1) *= value; *self.index_mut(2) *= value; *self.index_mut(3) *= value; } #[inline] pub fn div_self_t(&mut self, value: T) { *self.index_mut(0) /= value; *self.index_mut(1) /= value; *self.index_mut(2) /= value; *self.index_mut(3) /= value; } #[inline] pub fn rem_self_t(&mut self, value: T) { *self.index_mut(0) %= value; *self.index_mut(1) %= value; *self.index_mut(2) %= value; *self.index_mut(3) %= value; } #[inline] pub fn add_self_v(&mut self, other: &Vec4) { *self.index_mut(0) += *other.index(0); *self.index_mut(1) += *other.index(1); *self.index_mut(2) += *other.index(2); *self.index_mut(3) += *other.index(3); } #[inline] pub fn sub_self_v(&mut self, other: &Vec4) { *self.index_mut(0) -= *other.index(0); *self.index_mut(1) -= *other.index(1); *self.index_mut(2) -= *other.index(2); *self.index_mut(3) -= *other.index(3); } #[inline] pub fn mul_self_v(&mut self, other: &Vec4) { *self.index_mut(0) *= *other.index(0); *self.index_mut(1) *= *other.index(1); *self.index_mut(2) *= *other.index(2); *self.index_mut(3) *= *other.index(3); } #[inline] pub fn div_self_v(&mut self, other: &Vec4) { *self.index_mut(0) /= *other.index(0); *self.index_mut(1) /= *other.index(1); *self.index_mut(2) /= *other.index(2); *self.index_mut(3) /= *other.index(3); } #[inline] pub fn rem_self_v(&mut self, other: &Vec4) { *self.index_mut(0) /= *other.index(0); *self.index_mut(1) /= *other.index(1); *self.index_mut(2) /= *other.index(2); *self.index_mut(3) /= *other.index(3); } #[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::new(-self.index(0), -self.index(1), -self.index(2), -self.index(3)) } } 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::one::()/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 n = One::one::() / self.length(); self.mul_self_t(n); } #[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> ApproxEq for Vec4 { #[inline] pub fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() } #[inline] pub fn approx_eq(&self, other: &Vec4) -> bool { self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) } #[inline] pub fn approx_eq_eps(&self, other: &Vec4, 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) } } 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 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::new(*self.index(0) == value, *self.index(1) == value, *self.index(2) == value, *self.index(3) == value) } #[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 { #[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::new(!*self.index(0), !*self.index(1), !*self.index(2), !*self.index(3)) } } // GLSL-style type aliases pub type vec4 = Vec4; pub type dvec4 = Vec4; pub type bvec4 = Vec4; pub type ivec4 = Vec4; pub type uvec4 = Vec4; // Rust-style type aliases pub type Vec4f = Vec4; pub type Vec4f32 = Vec4; pub type Vec4f64 = Vec4; pub type Vec4i = Vec4; pub type Vec4i8 = Vec4; pub type Vec4i16 = Vec4; pub type Vec4i32 = Vec4; pub type Vec4i64 = Vec4; pub type Vec4u = Vec4; pub type Vec4u8 = Vec4; pub type Vec4u16 = Vec4; pub type Vec4u32 = Vec4; pub type Vec4u64 = Vec4; pub type Vec4b = Vec4;