2013-05-22 07:01:52 +00:00
|
|
|
use core::cast::transmute;
|
2013-05-07 15:00:06 +00:00
|
|
|
use core::cmp::ApproxEq;
|
2013-04-02 00:25:05 +00:00
|
|
|
use core::num::Zero::zero;
|
|
|
|
use core::num::One::one;
|
2013-05-22 05:44:54 +00:00
|
|
|
use core::util;
|
2013-05-06 03:52:22 +00:00
|
|
|
|
|
|
|
use num::NumAssign;
|
2012-12-13 13:01:42 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 01:51:18 +00:00
|
|
|
* The base generic vector trait.
|
|
|
|
*
|
|
|
|
* # Type parameters
|
|
|
|
*
|
|
|
|
* * `T` - The type of the components. This is intended to support boolean,
|
|
|
|
* integer, unsigned integer, and floating point types.
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait BaseVec<T>: Index<uint,T> + Eq {
|
2012-12-05 01:51:18 +00:00
|
|
|
/**
|
|
|
|
* Construct the vector from a single value, copying it to each component
|
|
|
|
*/
|
2013-03-28 10:37:25 +00:00
|
|
|
fn from_value(value: T) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-12 01:29:35 +00:00
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* A pointer to the first component of the vector
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn to_ptr(&self) -> *T;
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2012-12-04 11:42:24 +00:00
|
|
|
/**
|
|
|
|
* Get a mutable reference to the component at `i`
|
|
|
|
*/
|
2013-04-14 20:43:21 +00:00
|
|
|
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-04 07:58:03 +00:00
|
|
|
/**
|
|
|
|
* Swap two components of the vector in place
|
|
|
|
*/
|
|
|
|
fn swap(&mut self, a: uint, b: uint);
|
2012-11-20 07:58:24 +00:00
|
|
|
}
|
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
|
|
|
* A generic 2-dimensional vector
|
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait BaseVec2<T>: BaseVec<T> {
|
2013-03-28 10:37:25 +00:00
|
|
|
fn new(x: T, y: T) -> Self;
|
2012-11-21 04:08:36 +00:00
|
|
|
}
|
2012-11-20 07:58:24 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
|
|
|
* A generic 3-dimensional vector
|
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait BaseVec3<T>: BaseVec<T> {
|
2013-03-28 10:37:25 +00:00
|
|
|
fn new(x: T, y: T, z: T) -> Self;
|
2012-11-21 04:08:36 +00:00
|
|
|
}
|
2012-11-20 07:58:24 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
|
|
|
* A generic 4-dimensional vector
|
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait BaseVec4<T>: BaseVec<T> {
|
2013-03-28 10:37:25 +00:00
|
|
|
fn new(x: T, y: T, z: T, w: T) -> Self;
|
2012-11-21 04:08:36 +00:00
|
|
|
}
|
2012-11-15 02:23:39 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
|
|
|
* A vector with numeric components
|
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait NumVec<T>: BaseVec<T> + Neg<Self> {
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 02:10:05 +00:00
|
|
|
* The standard basis vector
|
|
|
|
*
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
2012-12-05 02:10:05 +00:00
|
|
|
*
|
|
|
|
* A vector with each component set to one
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:37:25 +00:00
|
|
|
fn identity() -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 02:10:05 +00:00
|
|
|
* The null vector
|
|
|
|
*
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
2012-12-05 02:10:05 +00:00
|
|
|
*
|
|
|
|
* A vector with each component set to zero
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:37:25 +00:00
|
|
|
fn zero() -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-24 03:46:25 +00:00
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* True if the vector is equal to zero
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn is_zero(&self) -> bool;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The scalar multiplication of the vector and `value`
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn mul_t(&self, value: T) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The scalar division of the vector and `value`
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn div_t(&self, value: T) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-28 08:47:10 +00:00
|
|
|
* Component-wise vector addition
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn add_v(&self, other: &Self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-28 08:47:10 +00:00
|
|
|
* Component-wise vector subtraction
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn sub_v(&self, other: &Self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-28 08:47:10 +00:00
|
|
|
/**
|
|
|
|
* Component-wise vector multiplication
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn mul_v(&self, other: &Self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-28 08:47:10 +00:00
|
|
|
/**
|
|
|
|
* Component-wise vector division
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn div_v(&self, other: &Self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The dot product of the vector and `other`
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn dot(&self, other: &Self) -> T;
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2012-12-04 13:32:34 +00:00
|
|
|
/**
|
|
|
|
* Negate the vector
|
|
|
|
*/
|
|
|
|
fn neg_self(&mut self);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-04 13:32:34 +00:00
|
|
|
/**
|
|
|
|
* Multiply the vector by a scalar
|
|
|
|
*/
|
|
|
|
fn mul_self_t(&mut self, value: T);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-04 13:32:34 +00:00
|
|
|
/**
|
|
|
|
* Divide the vector by a scalar
|
|
|
|
*/
|
|
|
|
fn div_self_t(&mut self, value: T);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-04 13:32:34 +00:00
|
|
|
/**
|
2012-12-28 08:47:10 +00:00
|
|
|
* Set the vector to the component-wise vector sum
|
2012-12-04 13:32:34 +00:00
|
|
|
*/
|
2013-01-29 10:23:22 +00:00
|
|
|
fn add_self_v(&mut self, other: &Self);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-04 13:32:34 +00:00
|
|
|
/**
|
2012-12-28 08:47:10 +00:00
|
|
|
* Set the vector to the component-wise vector difference
|
2012-12-04 13:32:34 +00:00
|
|
|
*/
|
2013-01-29 10:23:22 +00:00
|
|
|
fn sub_self_v(&mut self, other: &Self);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-28 08:47:10 +00:00
|
|
|
/**
|
|
|
|
* Set the vector to the component-wise vector product
|
|
|
|
*/
|
2013-01-29 10:23:22 +00:00
|
|
|
fn mul_self_v(&mut self, other: &Self);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-28 08:47:10 +00:00
|
|
|
/**
|
|
|
|
* Set the vector to the component-wise vector quotient
|
|
|
|
*/
|
2013-01-29 10:23:22 +00:00
|
|
|
fn div_self_v(&mut self, other: &Self);
|
2012-12-04 13:32:34 +00:00
|
|
|
}
|
|
|
|
|
2012-12-04 15:34:41 +00:00
|
|
|
/**
|
2013-03-29 11:51:34 +00:00
|
|
|
* A 2-dimensional vector with numeric components
|
2012-12-04 15:34:41 +00:00
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait NumVec2<T>: NumVec<T> {
|
2013-03-29 11:51:34 +00:00
|
|
|
fn unit_x() -> Self;
|
|
|
|
fn unit_y() -> Self;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The perp dot product of the vector and `other`
|
|
|
|
*/
|
|
|
|
fn perp_dot(&self, other: &Self) -> T;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A 3-dimensional vector with numeric components
|
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait NumVec3<T>: NumVec<T> {
|
2013-03-29 11:51:34 +00:00
|
|
|
fn unit_x() -> Self;
|
|
|
|
fn unit_y() -> Self;
|
|
|
|
fn unit_z() -> Self;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The cross product of the vector and `other`
|
|
|
|
*/
|
|
|
|
fn cross(&self, other: &Self) -> Self;
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2012-12-04 15:34:41 +00:00
|
|
|
/**
|
|
|
|
* Set to the cross product of the vector and `other`
|
|
|
|
*/
|
2013-01-29 10:23:22 +00:00
|
|
|
fn cross_self(&mut self, other: &Self);
|
2012-12-04 15:34:41 +00:00
|
|
|
}
|
|
|
|
|
2013-03-29 11:51:34 +00:00
|
|
|
/**
|
|
|
|
* A 4-dimensional vector with numeric components
|
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait NumVec4<T>: NumVec<T> {
|
2013-03-29 11:51:34 +00:00
|
|
|
fn unit_x() -> Self;
|
|
|
|
fn unit_y() -> Self;
|
|
|
|
fn unit_z() -> Self;
|
|
|
|
fn unit_w() -> Self;
|
|
|
|
}
|
|
|
|
|
2013-01-02 06:59:24 +00:00
|
|
|
pub trait ToHomogeneous<H> {
|
|
|
|
/**
|
|
|
|
* Convert to a homogenous coordinate
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn to_homogeneous(&self) -> H;
|
2013-01-02 06:59:24 +00:00
|
|
|
}
|
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 02:10:05 +00:00
|
|
|
* A Euclidean (or Affine) vector
|
|
|
|
*
|
|
|
|
* # Type parameters
|
|
|
|
*
|
|
|
|
* * `T` - The type of the components. This should be a floating point type.
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait AffineVec<T>: NumVec<T> {
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The squared length of the vector. This is useful for comparisons where
|
|
|
|
* the exact length does not need to be calculated.
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn length2(&self) -> T;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The length of the vector
|
|
|
|
*
|
|
|
|
* # Performance notes
|
|
|
|
*
|
|
|
|
* For instances where the exact length of the vector does not need to be
|
|
|
|
* known, for example for quaternion-quaternion length comparisons,
|
|
|
|
* it is advisable to use the `length2` method instead.
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn length(&self) -> T;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The squared distance between the vector and `other`.
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn distance2(&self, other: &Self) -> T;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The distance between the vector and `other`
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn distance(&self, other: &Self) -> T;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-13 12:01:55 +00:00
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
2013-01-27 22:22:15 +00:00
|
|
|
* The angle between the vector and `other` in radians
|
2012-12-13 12:01:55 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn angle(&self, other: &Self) -> T;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-05 08:09:53 +00:00
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The normalized vector
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn normalize(&self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-13 09:21:50 +00:00
|
|
|
/**
|
|
|
|
* Set the length of the vector whilst preserving the direction
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn normalize_to(&self, length: T) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-03 16:32:40 +00:00
|
|
|
/**
|
2012-12-03 22:31:26 +00:00
|
|
|
* Linearly intoperlate between the vector and `other`
|
2012-12-05 08:09:53 +00:00
|
|
|
*
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* The intoperlated vector
|
2012-12-03 16:32:40 +00:00
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn lerp(&self, other: &Self, amount: T) -> Self;
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2012-12-04 22:21:40 +00:00
|
|
|
/**
|
|
|
|
* Normalize the vector
|
|
|
|
*/
|
|
|
|
fn normalize_self(&mut self);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-13 09:21:50 +00:00
|
|
|
/**
|
|
|
|
* Set the vector to a specified length whilst preserving the direction
|
|
|
|
*/
|
|
|
|
fn normalize_self_to(&mut self, length: T);
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-04 22:21:40 +00:00
|
|
|
/**
|
|
|
|
* Linearly intoperlate the vector towards `other`
|
|
|
|
*/
|
2013-01-29 10:23:22 +00:00
|
|
|
fn lerp_self(&mut self, other: &Self, amount: T);
|
2012-12-16 05:19:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Component-wise vector comparison methods
|
2012-12-17 06:09:00 +00:00
|
|
|
*
|
|
|
|
* The methods contained in this trait correspond to the relational functions
|
|
|
|
* mentioned in Section 8.7 of the [GLSL 4.30.6 specification]
|
|
|
|
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
2012-12-16 05:19:38 +00:00
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait OrdVec<T, BoolVec>: BaseVec<T> {
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* Component-wise compare of `self < other`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn less_than(&self, other: &Self) -> BoolVec;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* Component-wise compare of `self <= other`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn less_than_equal(&self, other: &Self) -> BoolVec;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* Component-wise compare of `self > other`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn greater_than(&self, other: &Self) -> BoolVec;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* Component-wise compare of `self >= other`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn greater_than_equal(&self, other: &Self) -> BoolVec;
|
2012-12-17 05:35:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Component-wise equality comparison methods
|
2012-12-17 06:09:00 +00:00
|
|
|
*
|
|
|
|
* The methods contained in this trait correspond to the relational functions
|
|
|
|
* mentioned in Section 8.7 of the [GLSL 4.30.6 specification]
|
|
|
|
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
2012-12-17 05:35:03 +00:00
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait EqVec<T, BoolVec>: BaseVec<T> {
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* Component-wise compare of `self == other`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn equal(&self, other: &Self) -> BoolVec;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* Component-wise compare of `self != other`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn not_equal(&self, other: &Self) -> BoolVec;
|
2012-12-16 05:19:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A vector with boolean components
|
2012-12-17 06:09:00 +00:00
|
|
|
*
|
|
|
|
* The methods contained in this trait correspond to the relational functions
|
|
|
|
* mentioned in Section 8.7 of the [GLSL 4.30.6 specification]
|
|
|
|
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
2012-12-16 05:19:38 +00:00
|
|
|
*/
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait BoolVec: BaseVec<bool> {
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* `true` if of any component is `true`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn any(&self) -> bool;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* `true` only if all components are `true`
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn all(&self) -> bool;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2012-12-17 05:35:03 +00:00
|
|
|
/**
|
|
|
|
* # Return value
|
|
|
|
*
|
|
|
|
* the component-wise logical complement
|
|
|
|
*/
|
2013-03-28 10:35:51 +00:00
|
|
|
fn not(&self) -> Self;
|
2013-02-09 22:42:06 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait TrigVec<T>: BaseVec<T> {
|
2013-03-28 10:35:51 +00:00
|
|
|
fn radians(&self) -> Self;
|
|
|
|
fn degrees(&self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2013-02-09 22:42:06 +00:00
|
|
|
// Triganometric functions
|
2013-03-28 10:35:51 +00:00
|
|
|
fn sin(&self) -> Self;
|
|
|
|
fn cos(&self) -> Self;
|
|
|
|
fn tan(&self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2013-02-09 22:42:06 +00:00
|
|
|
// Inverse triganometric functions
|
2013-03-28 10:35:51 +00:00
|
|
|
fn asin(&self) -> Self;
|
|
|
|
fn acos(&self) -> Self;
|
|
|
|
fn atan(&self) -> Self;
|
|
|
|
fn atan2(&self, other: Self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2013-02-09 22:42:06 +00:00
|
|
|
// Hyperbolic triganometric functions
|
2013-03-28 10:35:51 +00:00
|
|
|
fn sinh(&self) -> Self;
|
|
|
|
fn cosh(&self) -> Self;
|
|
|
|
fn tanh(&self) -> Self;
|
|
|
|
// fn asinh() -> Self;
|
|
|
|
// fn acosh() -> Self;
|
|
|
|
// fn atanh() -> Self;
|
2013-02-09 22:42:06 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait ExpVec<T>: BaseVec<T> {
|
2013-02-09 22:42:06 +00:00
|
|
|
// Exponential functions
|
2013-03-28 10:35:51 +00:00
|
|
|
fn pow_t(&self, n: Self) -> Self;
|
|
|
|
fn pow_v(&self, n: T) -> Self;
|
|
|
|
fn exp(&self) -> Self;
|
|
|
|
fn exp2(&self) -> Self;
|
|
|
|
fn ln(&self) -> Self;
|
|
|
|
fn ln2(&self) -> Self;
|
|
|
|
fn sqrt(&self) -> Self;
|
|
|
|
fn inv_sqrt(&self) -> Self;
|
2013-02-09 22:42:06 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait ApproxVec<T>: BaseVec<T> {
|
2013-02-09 22:42:06 +00:00
|
|
|
// Whole-number approximation functions
|
2013-03-28 10:35:51 +00:00
|
|
|
fn floor(&self) -> Self;
|
|
|
|
fn trunc(&self) -> Self;
|
|
|
|
fn round(&self) -> Self;
|
|
|
|
// fn round_even(&self) -> Self;
|
|
|
|
fn ceil(&self) -> Self;
|
|
|
|
fn fract(&self) -> Self;
|
2013-02-09 22:42:06 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait SignedVec<T,BV>: BaseVec<T> {
|
2013-03-28 10:35:51 +00:00
|
|
|
fn is_positive(&self) -> BV;
|
|
|
|
fn is_negative(&self) -> BV;
|
|
|
|
fn is_nonpositive(&self) -> BV;
|
|
|
|
fn is_nonnegative(&self) -> BV;
|
|
|
|
|
|
|
|
fn abs(&self) -> Self;
|
|
|
|
fn sign(&self) -> Self;
|
|
|
|
fn copysign(&self, other: Self) -> Self;
|
2013-02-09 22:42:06 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait ExtentVec<T>: BaseVec<T> {
|
2013-03-28 10:35:51 +00:00
|
|
|
fn min_v(&self, other: &Self) -> Self;
|
|
|
|
fn max_v(&self, other: &Self) -> Self;
|
|
|
|
fn clamp_v(&self, mn: &Self, mx: &Self) -> Self;
|
2013-03-28 09:45:43 +00:00
|
|
|
|
2013-03-28 10:35:51 +00:00
|
|
|
fn min_t(&self, other: T) -> Self;
|
|
|
|
fn max_t(&self, other: T) -> Self;
|
|
|
|
fn clamp_t(&self, mn: T, mx: T) -> Self;
|
2013-02-09 22:42:06 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
pub trait MixVec<T>: BaseVec<T> {
|
2013-02-09 22:42:06 +00:00
|
|
|
// Functions for blending numbers together
|
2013-03-28 10:35:51 +00:00
|
|
|
fn mix(&self, other: Self, value: Self) -> Self;
|
|
|
|
fn smooth_step(&self, edge0: Self, edge1: Self) -> Self;
|
|
|
|
fn step(&self, edge: Self) -> Self;
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
2013-03-31 20:35:09 +00:00
|
|
|
// Utility macros
|
|
|
|
|
|
|
|
macro_rules! zip_vec2(
|
|
|
|
($a:ident[] $method:ident $b:ident[]) => (
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new($a[0].$method(&($b[0])),
|
|
|
|
$a[1].$method(&($b[1])))
|
2013-03-31 20:35:09 +00:00
|
|
|
);
|
|
|
|
($a:ident[] $method:ident $b:ident) => (
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new($a[0].$method(&($b)),
|
|
|
|
$a[1].$method(&($b)))
|
2013-03-31 20:35:09 +00:00
|
|
|
);
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! zip_vec3(
|
|
|
|
($a:ident[] $method:ident $b:ident[]) => (
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new($a[0].$method(&($b[0])),
|
|
|
|
$a[1].$method(&($b[1])),
|
|
|
|
$a[2].$method(&($b[2])))
|
2013-03-31 20:35:09 +00:00
|
|
|
);
|
|
|
|
($a:ident[] $method:ident $b:ident) => (
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new($a[0].$method(&($b)),
|
|
|
|
$a[1].$method(&($b)),
|
|
|
|
$a[2].$method(&($b)))
|
2013-03-31 20:35:09 +00:00
|
|
|
);
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! zip_vec4(
|
|
|
|
($a:ident[] $method:ident $b:ident[]) => (
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new($a[0].$method(&($b[0])),
|
|
|
|
$a[1].$method(&($b[1])),
|
|
|
|
$a[2].$method(&($b[2])),
|
|
|
|
$a[3].$method(&($b[3])))
|
2013-03-31 20:35:09 +00:00
|
|
|
);
|
|
|
|
($a:ident[] $method:ident $b:ident) => (
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new($a[0].$method(&($b)),
|
|
|
|
$a[1].$method(&($b)),
|
|
|
|
$a[2].$method(&($b)),
|
|
|
|
$a[3].$method(&($b)))
|
2013-03-31 20:35:09 +00:00
|
|
|
);
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! zip_assign(
|
2013-05-06 03:52:22 +00:00
|
|
|
($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method(&$b[0]); $a.index_mut(1).$method(&$b[1]); });
|
|
|
|
($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method(&$b[2]); });
|
|
|
|
($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method(&$b[3]); });
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method(&$b); $a.index_mut(1).$method(&$b); });
|
|
|
|
($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); });
|
|
|
|
($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method(&$b); });
|
2013-03-31 20:35:09 +00:00
|
|
|
)
|
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
/**
|
|
|
|
* A 2-dimensional vector
|
|
|
|
*
|
|
|
|
* # Type parameters
|
|
|
|
*
|
|
|
|
* * `T` - The type of the components. This is intended to support boolean,
|
|
|
|
* integer, unsigned integer, and floating point types.
|
|
|
|
*
|
|
|
|
* # Fields
|
|
|
|
*
|
|
|
|
* * `x` - the first component of the vector
|
|
|
|
* * `y` - the second component of the vector
|
|
|
|
*/
|
|
|
|
#[deriving(Eq)]
|
|
|
|
pub struct Vec2<T> { x: T, y: T }
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Eq> BaseVec<T> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn from_value(value: T) -> Vec2<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(value, value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn to_ptr(&self) -> *T {
|
|
|
|
unsafe { cast::transmute(self) }
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
2013-04-14 20:43:21 +00:00
|
|
|
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
|
2013-05-22 07:01:52 +00:00
|
|
|
unsafe {
|
|
|
|
&'a mut transmute::<
|
|
|
|
&'a mut Vec2<T>,
|
|
|
|
&'a mut [T,..2]
|
|
|
|
>(self)[i]
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn swap(&mut self, a: uint, b: uint) {
|
2013-05-22 05:44:54 +00:00
|
|
|
util::swap(self.index_mut(a), self.index_mut(b));
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T> BaseVec2<T> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn new(x: T, y: T ) -> Vec2<T> {
|
|
|
|
Vec2 { x: x, y: y }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T:Copy + Eq> Index<uint, T> for Vec2<T> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn index(&self, i: &uint) -> T {
|
2013-05-22 07:01:52 +00:00
|
|
|
unsafe { transmute::<Vec2<T>,[T,..2]>(*self)[*i] }
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn identity() -> Vec2<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(one::<T>(), one::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn zero() -> Vec2<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(zero::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
self[0] == zero() &&
|
|
|
|
self[1] == zero()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_t(&self, value: T) -> Vec2<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] mul value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_t(&self, value: T) -> Vec2<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] div value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn add_v(&self, other: &Vec2<T>) -> Vec2<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] add other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn sub_v(&self, other: &Vec2<T>) -> Vec2<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] sub other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_v(&self, other: &Vec2<T>) -> Vec2<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] mul other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_v(&self, other: &Vec2<T>) -> Vec2<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] div other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn dot(&self, other: &Vec2<T>) -> T {
|
|
|
|
self[0] * other[0] +
|
|
|
|
self[1] * other[1]
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn neg_self(&mut self) {
|
2013-03-31 20:35:09 +00:00
|
|
|
*self.index_mut(0) = -self[0];
|
|
|
|
*self.index_mut(1) = -self[1];
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_self_t(&mut self, value: T) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] mul_assign value ..2);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_self_t(&mut self, value: T) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] div_assign value ..2);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn add_self_v(&mut self, other: &Vec2<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] add_assign other[] ..2);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn sub_self_v(&mut self, other: &Vec2<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] sub_assign other[] ..2);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_self_v(&mut self, other: &Vec2<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] mul_assign other[] ..2);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_self_v(&mut self, other: &Vec2<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] div_assign other[] ..2);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> Neg<Vec2<T>> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn neg(&self) -> Vec2<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(-self[0], -self[1])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> NumVec2<T> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn unit_x() -> Vec2<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(one::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn unit_y() -> Vec2<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(zero::<T>(), one::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn perp_dot(&self, other: &Vec2<T>) ->T {
|
|
|
|
(self[0] * other[1]) - (self[1] * other[0])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> ToHomogeneous<Vec3<T>> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn to_homogeneous(&self) -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(self.x, self.y, zero())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn length2(&self) -> T {
|
|
|
|
self.dot(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn length(&self) -> T {
|
|
|
|
self.length2().sqrt()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn distance2(&self, other: &Vec2<T>) -> T {
|
|
|
|
other.sub_v(self).length2()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn distance(&self, other: &Vec2<T>) -> T {
|
|
|
|
other.distance2(self).sqrt()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn angle(&self, other: &Vec2<T>) -> T {
|
2013-05-06 03:52:22 +00:00
|
|
|
self.perp_dot(other).atan2(self.dot(other))
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize(&self) -> Vec2<T> {
|
|
|
|
self.mul_t(one::<T>()/self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_to(&self, length: T) -> Vec2<T> {
|
|
|
|
self.mul_t(length / self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn lerp(&self, other: &Vec2<T>, amount: T) -> Vec2<T> {
|
|
|
|
self.add_v(&other.sub_v(self).mul_t(amount))
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_self(&mut self) {
|
|
|
|
let n = one::<T>() / self.length();
|
|
|
|
self.mul_self_t(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_self_to(&mut self, length: T) {
|
|
|
|
let n = length / self.length();
|
|
|
|
self.mul_self_t(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn lerp_self(&mut self, other: &Vec2<T>, amount: T) {
|
|
|
|
let v = other.sub_v(self).mul_t(amount);
|
|
|
|
self.add_self_v(&v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-07 15:00:06 +00:00
|
|
|
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec2<T> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn approx_epsilon() -> T {
|
|
|
|
ApproxEq::approx_epsilon::<T,T>()
|
|
|
|
}
|
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
2013-05-07 15:00:06 +00:00
|
|
|
fn approx_eq(&self, other: &Vec2<T>) -> bool {
|
|
|
|
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-05-07 15:00:06 +00:00
|
|
|
fn approx_eq_eps(&self, other: &Vec2<T>, epsilon: &T) -> bool {
|
|
|
|
self[0].approx_eq_eps(&other[0], epsilon) &&
|
|
|
|
self[1].approx_eq_eps(&other[1], epsilon)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Ord + Eq> OrdVec<T, Vec2<bool>> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn less_than(&self, other: &Vec2<T>) -> Vec2<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] lt other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn less_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] le other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn greater_than(&self, other: &Vec2<T>) -> Vec2<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] gt other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn greater_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] ge other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Eq> EqVec<T, Vec2<bool>> for Vec2<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] eq other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn not_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec2!(self[] ne other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl BoolVec for Vec2<bool> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn any(&self) -> bool {
|
|
|
|
self[0] || self[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn all(&self) -> bool {
|
|
|
|
self[0] && self[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn not(&self) -> Vec2<bool> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec2::new(!self[0], !self[1])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A 3-dimensional vector
|
|
|
|
*
|
|
|
|
* # Type parameters
|
|
|
|
*
|
|
|
|
* * `T` - The type of the components. This is intended to support boolean,
|
|
|
|
* integer, unsigned integer, and floating point types.
|
|
|
|
*
|
|
|
|
* # Fields
|
|
|
|
*
|
|
|
|
* * `x` - the first component of the vector
|
|
|
|
* * `y` - the second component of the vector
|
|
|
|
* * `z` - the third component of the vector
|
|
|
|
*/
|
|
|
|
#[deriving(Eq)]
|
|
|
|
pub struct Vec3<T> { x: T, y: T, z: T }
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Eq> BaseVec<T> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn from_value(value: T) -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(value, value, value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn to_ptr(&self) -> *T {
|
|
|
|
unsafe { cast::transmute(self) }
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
2013-04-14 20:43:21 +00:00
|
|
|
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
|
2013-05-22 07:01:52 +00:00
|
|
|
unsafe {
|
|
|
|
&'a mut transmute::<
|
|
|
|
&'a mut Vec3<T>,
|
|
|
|
&'a mut [T,..3]
|
|
|
|
>(self)[i]
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn swap(&mut self, a: uint, b: uint) {
|
2013-05-22 05:44:54 +00:00
|
|
|
util::swap(self.index_mut(a), self.index_mut(b));
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T> BaseVec3<T> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn new(x: T, y: T, z: T) -> Vec3<T> {
|
|
|
|
Vec3 { x: x, y: y, z: z }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T:Copy + Eq> Index<uint, T> for Vec3<T> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn index(&self, i: &uint) -> T {
|
2013-05-22 07:01:52 +00:00
|
|
|
unsafe { transmute::<Vec3<T>,[T,..3]>(*self)[*i] }
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn identity() -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(one::<T>(), one::<T>(), one::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn zero() -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(zero::<T>(), zero::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
self[0] == zero() &&
|
|
|
|
self[1] == zero() &&
|
|
|
|
self[2] == zero()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_t(&self, value: T) -> Vec3<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] mul value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_t(&self, value: T) -> Vec3<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] div value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-03-31 20:35:09 +00:00
|
|
|
fn add_v(&self, other: &Vec3<T>) -> Vec3<T> {
|
|
|
|
zip_vec3!(self[] add other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-03-31 20:35:09 +00:00
|
|
|
fn sub_v(&self, other: &Vec3<T>) -> Vec3<T> {
|
|
|
|
zip_vec3!(self[] sub other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-03-31 20:35:09 +00:00
|
|
|
fn mul_v(&self, other: &Vec3<T>) -> Vec3<T> {
|
|
|
|
zip_vec3!(self[] mul other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-03-31 20:35:09 +00:00
|
|
|
fn div_v(&self, other: &Vec3<T>) -> Vec3<T> {
|
|
|
|
zip_vec3!(self[] div other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn dot(&self, other: &Vec3<T>) -> T {
|
|
|
|
self[0] * other[0] +
|
|
|
|
self[1] * other[1] +
|
|
|
|
self[2] * other[2]
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn neg_self(&mut self) {
|
2013-03-31 20:35:09 +00:00
|
|
|
*self.index_mut(0) = -self[0];
|
|
|
|
*self.index_mut(1) = -self[1];
|
|
|
|
*self.index_mut(2) = -self[2];
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_self_t(&mut self, value: T) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] mul_assign value ..3);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_self_t(&mut self, value: T) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] div_assign value ..3);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn add_self_v(&mut self, other: &Vec3<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] add_assign other[] ..3);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn sub_self_v(&mut self, other: &Vec3<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] sub_assign other[] ..3);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_self_v(&mut self, other: &Vec3<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] mul_assign other[] ..3);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_self_v(&mut self, other: &Vec3<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] div_assign other[] ..3);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> Neg<Vec3<T>> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn neg(&self) -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(-self[0], -self[1], -self[2])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> NumVec3<T> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn unit_x() -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(one::<T>(), zero::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn unit_y() -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(zero::<T>(), one::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn unit_z() -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(zero::<T>(), zero::<T>(), one::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn cross(&self, other: &Vec3<T>) -> Vec3<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new((self[1] * other[2]) - (self[2] * other[1]),
|
|
|
|
(self[2] * other[0]) - (self[0] * other[2]),
|
|
|
|
(self[0] * other[1]) - (self[1] * other[0]))
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn cross_self(&mut self, other: &Vec3<T>) {
|
|
|
|
*self = self.cross(other);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> ToHomogeneous<Vec4<T>> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn to_homogeneous(&self) -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(self.x, self.y, self.z, zero())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn length2(&self) -> T {
|
|
|
|
self.dot(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn length(&self) -> T {
|
|
|
|
self.length2().sqrt()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn distance2(&self, other: &Vec3<T>) -> T {
|
|
|
|
other.sub_v(self).length2()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn distance(&self, other: &Vec3<T>) -> T {
|
|
|
|
other.distance2(self).sqrt()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn angle(&self, other: &Vec3<T>) -> T {
|
2013-05-06 03:52:22 +00:00
|
|
|
self.cross(other).length().atan2(self.dot(other))
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize(&self) -> Vec3<T> {
|
|
|
|
self.mul_t(one::<T>()/self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_to(&self, length: T) -> Vec3<T> {
|
|
|
|
self.mul_t(length / self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn lerp(&self, other: &Vec3<T>, amount: T) -> Vec3<T> {
|
|
|
|
self.add_v(&other.sub_v(self).mul_t(amount))
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_self(&mut self) {
|
|
|
|
let n = one::<T>() / self.length();
|
|
|
|
self.mul_self_t(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_self_to(&mut self, length: T) {
|
|
|
|
let n = length / self.length();
|
|
|
|
self.mul_self_t(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn lerp_self(&mut self, other: &Vec3<T>, amount: T) {
|
|
|
|
let v = other.sub_v(self).mul_t(amount);
|
|
|
|
self.add_self_v(&v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-07 15:00:06 +00:00
|
|
|
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec3<T> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn approx_epsilon() -> T {
|
|
|
|
ApproxEq::approx_epsilon::<T,T>()
|
|
|
|
}
|
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
2013-05-07 15:00:06 +00:00
|
|
|
fn approx_eq(&self, other: &Vec3<T>) -> bool {
|
|
|
|
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-05-07 15:00:06 +00:00
|
|
|
fn approx_eq_eps(&self, other: &Vec3<T>, epsilon: &T) -> bool {
|
|
|
|
self[0].approx_eq_eps(&other[0], epsilon) &&
|
|
|
|
self[1].approx_eq_eps(&other[1], epsilon) &&
|
|
|
|
self[2].approx_eq_eps(&other[2], epsilon)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Ord + Eq> OrdVec<T, Vec3<bool>> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn less_than(&self, other: &Vec3<T>) -> Vec3<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] lt other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn less_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] le other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn greater_than(&self, other: &Vec3<T>) -> Vec3<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] gt other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn greater_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] ge other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Eq> EqVec<T, Vec3<bool>> for Vec3<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] eq other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn not_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec3!(self[] ne other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl BoolVec for Vec3<bool> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn any(&self) -> bool {
|
|
|
|
self[0] || self[1] || self[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn all(&self) -> bool {
|
|
|
|
self[0] && self[1] && self[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn not(&self) -> Vec3<bool> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec3::new(!self[0], !self[1], !self[2])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A 4-dimensional vector
|
|
|
|
*
|
|
|
|
* # Type parameters
|
|
|
|
*
|
|
|
|
* * `T` - The type of the components. This is intended to support boolean,
|
|
|
|
* integer, unsigned integer, and floating point types.
|
|
|
|
*
|
|
|
|
* # Fields
|
|
|
|
*
|
|
|
|
* * `x` - the first component of the vector
|
|
|
|
* * `y` - the second component of the vector
|
|
|
|
* * `z` - the third component of the vector
|
|
|
|
* * `w` - the fourth component of the vector
|
|
|
|
*/
|
|
|
|
#[deriving(Eq)]
|
|
|
|
pub struct Vec4<T> { x: T, y: T, z: T, w: T }
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Eq> BaseVec<T> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn from_value(value: T) -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(value, value, value, value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn to_ptr(&self) -> *T {
|
|
|
|
unsafe { cast::transmute(self) }
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
2013-04-14 20:43:21 +00:00
|
|
|
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
|
2013-05-22 07:01:52 +00:00
|
|
|
unsafe {
|
|
|
|
&'a mut transmute::<
|
|
|
|
&'a mut Vec4<T>,
|
|
|
|
&'a mut [T,..4]
|
|
|
|
>(self)[i]
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn swap(&mut self, a: uint, b: uint) {
|
2013-05-22 05:44:54 +00:00
|
|
|
util::swap(self.index_mut(a), self.index_mut(b));
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T> BaseVec4<T> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn new(x: T, y: T, z: T, w: T) -> Vec4<T> {
|
|
|
|
Vec4 { x: x, y: y, z: z, w: w }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T:Copy + Eq> Index<uint, T> for Vec4<T> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn index(&self, i: &uint) -> T {
|
2013-05-22 07:01:52 +00:00
|
|
|
unsafe { transmute::<Vec4<T>,[T,..4]>(*self)[*i] }
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn identity() -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(one::<T>(), one::<T>(), one::<T>(), one::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn zero() -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(zero::<T>(), zero::<T>(), zero::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
self[0] == zero() &&
|
|
|
|
self[1] == zero() &&
|
|
|
|
self[2] == zero() &&
|
|
|
|
self[3] == zero()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_t(&self, value: T) -> Vec4<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] mul value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_t(&self, value: T) -> Vec4<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] div value)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn add_v(&self, other: &Vec4<T>) -> Vec4<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] add other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn sub_v(&self, other: &Vec4<T>) -> Vec4<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] sub other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_v(&self, other: &Vec4<T>) -> Vec4<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] mul other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_v(&self, other: &Vec4<T>) -> Vec4<T> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] div other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn dot(&self, other: &Vec4<T>) -> T {
|
|
|
|
self[0] * other[0] +
|
|
|
|
self[1] * other[1] +
|
|
|
|
self[2] * other[2] +
|
|
|
|
self[3] * other[3]
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn neg_self(&mut self) {
|
2013-03-31 20:35:09 +00:00
|
|
|
*self.index_mut(0) = -self[0];
|
|
|
|
*self.index_mut(1) = -self[1];
|
|
|
|
*self.index_mut(2) = -self[2];
|
|
|
|
*self.index_mut(3) = -self[3];
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_self_t(&mut self, value: T) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] mul_assign value ..4);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_self_t(&mut self, value: T) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] div_assign value ..4);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn add_self_v(&mut self, other: &Vec4<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] add_assign other[] ..4);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn sub_self_v(&mut self, other: &Vec4<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] sub_assign other[] ..4);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn mul_self_v(&mut self, other: &Vec4<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] mul_assign other[] ..4);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn div_self_v(&mut self, other: &Vec4<T>) {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_assign!(self[] div_assign other[] ..4);
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> Neg<Vec4<T>> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn neg(&self) -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(-self[0], -self[1], -self[2], -self[3])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Num> NumVec4<T> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn unit_x() -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(one::<T>(), zero::<T>(), zero::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn unit_y() -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(zero::<T>(), one::<T>(), zero::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn unit_z() -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(zero::<T>(), zero::<T>(), one::<T>(), zero::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn unit_w() -> Vec4<T> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(zero::<T>(), zero::<T>(), zero::<T>(), one::<T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:52:22 +00:00
|
|
|
impl<T:Copy + Real + NumAssign> AffineVec<T> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn length2(&self) -> T {
|
|
|
|
self.dot(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn length(&self) -> T {
|
|
|
|
self.length2().sqrt()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn distance2(&self, other: &Vec4<T>) -> T {
|
|
|
|
other.sub_v(self).length2()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn distance(&self, other: &Vec4<T>) -> T {
|
|
|
|
other.distance2(self).sqrt()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn angle(&self, other: &Vec4<T>) -> T {
|
2013-05-06 03:52:22 +00:00
|
|
|
(self.dot(other) / (self.length() * other.length())).acos()
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize(&self) -> Vec4<T> {
|
|
|
|
self.mul_t(one::<T>()/self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_to(&self, length: T) -> Vec4<T> {
|
|
|
|
self.mul_t(length / self.length())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn lerp(&self, other: &Vec4<T>, amount: T) -> Vec4<T> {
|
|
|
|
self.add_v(&other.sub_v(self).mul_t(amount))
|
|
|
|
}
|
2013-05-07 15:00:06 +00:00
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_self(&mut self) {
|
|
|
|
let n = one::<T>() / self.length();
|
|
|
|
self.mul_self_t(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn normalize_self_to(&mut self, length: T) {
|
|
|
|
let n = length / self.length();
|
|
|
|
self.mul_self_t(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn lerp_self(&mut self, other: &Vec4<T>, amount: T) {
|
|
|
|
let v = other.sub_v(self).mul_t(amount);
|
|
|
|
self.add_self_v(&v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-07 15:00:06 +00:00
|
|
|
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec4<T> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn approx_epsilon() -> T {
|
|
|
|
ApproxEq::approx_epsilon::<T,T>()
|
|
|
|
}
|
|
|
|
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
2013-05-07 15:00:06 +00:00
|
|
|
fn approx_eq(&self, other: &Vec4<T>) -> bool {
|
|
|
|
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2013-05-07 15:00:06 +00:00
|
|
|
fn approx_eq_eps(&self, other: &Vec4<T>, epsilon: &T) -> bool {
|
|
|
|
self[0].approx_eq_eps(&other[0], epsilon) &&
|
|
|
|
self[1].approx_eq_eps(&other[1], epsilon) &&
|
|
|
|
self[2].approx_eq_eps(&other[2], epsilon) &&
|
|
|
|
self[3].approx_eq_eps(&other[3], epsilon)
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Ord + Eq> OrdVec<T, Vec4<bool>> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn less_than(&self, other: &Vec4<T>) -> Vec4<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] lt other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn less_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] le other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn greater_than(&self, other: &Vec4<T>) -> Vec4<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] gt other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn greater_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] ge other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl<T:Copy + Eq> EqVec<T, Vec4<bool>> for Vec4<T> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] eq other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn not_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
2013-03-31 20:35:09 +00:00
|
|
|
zip_vec4!(self[] ne other[])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-02 05:12:13 +00:00
|
|
|
impl BoolVec for Vec4<bool> {
|
2013-03-31 06:27:59 +00:00
|
|
|
#[inline(always)]
|
|
|
|
fn any(&self) -> bool {
|
|
|
|
self[0] || self[1] || self[2] || self[3]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn all(&self) -> bool {
|
|
|
|
self[0] && self[1] && self[2] && self[3]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn not(&self) -> Vec4<bool> {
|
2013-04-02 05:12:13 +00:00
|
|
|
BaseVec4::new(!self[0], !self[1], !self[2], !self[3])
|
2013-03-31 06:27:59 +00:00
|
|
|
}
|
|
|
|
}
|