Remove anonymous impls on types and transfer functionality to traits

Unfortunately this causes Rust's type inference to struggle, but this is a problem with the rust compiler and hopefully this will improve over time. Users are encouraged to use the type aliases and static method wrappers included with each module.
This commit is contained in:
Brendan Zabarauskas 2013-01-29 20:26:48 +11:00
parent 683ac4ad62
commit d7f5efadbd
13 changed files with 1305 additions and 1367 deletions

View file

@ -1,6 +1,7 @@
use core::cmp::Eq;
use std::cmp::FuzzyEq;
use vec::Vec3;
use quat::Quat;
pub use mat2::{Mat2, mat2, dmat2};
@ -32,6 +33,11 @@ pub trait Matrix<T,V>: Index<uint, V> Eq Neg<self> {
*/
pure fn row(&self, i: uint) -> V;
/**
* Construct a diagonal matrix with the major diagonal set to `value`
*/
static pure fn from_value(value: T) -> self;
/**
* # Return value
*
@ -173,6 +179,63 @@ pub trait Matrix<T,V>: Index<uint, V> Eq Neg<self> {
pure fn to_ptr(&self) -> *T;
}
/**
* A 2 x 2 matrix
*/
pub trait Matrix2<T,V>: Matrix<T,V> {
static pure fn new(c0r0: T, c0r1: T,
c1r0: T, c1r1: T) -> self;
static pure fn from_cols(c0: V, c1: V) -> self;
static pure fn from_angle(radians: T) -> self;
pure fn to_mat3(&self) -> Mat3<T>;
pure fn to_mat4(&self) -> Mat4<T>;
}
/**
* A 3 x 3 matrix
*/
pub trait Matrix3<T,V>: Matrix<T,V> {
static pure fn new(c0r0:T, c0r1:T, c0r2:T,
c1r0:T, c1r1:T, c1r2:T,
c2r0:T, c2r1:T, c2r2:T) -> self;
static pure fn from_cols(c0: V, c1: V, c2: V) -> self;
static pure fn from_angle_x(radians: T) -> self;
static pure fn from_angle_y(radians: T) -> self;
static pure fn from_angle_z(radians: T) -> self;
static pure fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> self;
static pure fn from_angle_axis(radians: T, axis: &Vec3<T>) -> self;
static pure fn from_axes(x: V, y: V, z: V) -> self;
static pure fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> self;
pure fn to_mat4(&self) -> Mat4<T>;
pure fn to_quat(&self) -> Quat<T>;
}
/**
* A 4 x 4 matrix
*/
pub trait Matrix4<T,V>: Matrix<T,V> {
static pure fn new(c0r0: T, c0r1: T, c0r2: T, c0r3: T,
c1r0: T, c1r1: T, c1r2: T, c1r3: T,
c2r0: T, c2r1: T, c2r2: T, c2r3: T,
c3r0: T, c3r1: T, c3r2: T, c3r3: T) -> self;
static pure fn from_cols(c0: V, c1: V, c2: V, c3: V) -> self;
}
/**
* A mutable matrix
*/
@ -238,68 +301,4 @@ pub trait MutableMatrix<T,V>: Matrix<T,V> {
* Sets the matrix to its transpose
*/
fn transpose_self(&mut self);
}
/**
* A 2 x 2 matrix
*/
pub trait Matrix2<T,V>: Matrix<T,V> {
/**
* Returns the the matrix with an extra row and column added
* ~~~
* c0 c1 c0 c1 c2
* +----+----+ +----+----+----+
* r0 | a | b | r0 | a | b | 0 |
* +----+----+ +----+----+----+
* r1 | c | d | => r1 | c | d | 0 |
* +----+----+ +----+----+----+
* r2 | 0 | 0 | 1 |
* +----+----+----+
* ~~~
*/
pure fn to_mat3(&self) -> Mat3<T>;
/**
* Returns the the matrix with an extra two rows and columns added
* ~~~
* c0 c1 c0 c1 c2 c3
* +----+----+ +----+----+----+----+
* r0 | a | b | r0 | a | b | 0 | 0 |
* +----+----+ +----+----+----+----+
* r1 | c | d | => r1 | c | d | 0 | 0 |
* +----+----+ +----+----+----+----+
* r2 | 0 | 0 | 1 | 0 |
* +----+----+----+----+
* r3 | 0 | 0 | 0 | 1 |
* +----+----+----+----+
* ~~~
*/
pure fn to_mat4(&self) -> Mat4<T>;
}
/**
* A 3 x 3 matrix
*/
pub trait Matrix3<T,V>: Matrix<T,V> {
/**
* Returns the the matrix with an extra row and column added
* ~~~
* c0 c1 c2 c0 c1 c2 c3
* +----+----+----+ +----+----+----+----+
* r0 | a | b | c | r0 | a | b | c | 0 |
* +----+----+----+ +----+----+----+----+
* r1 | d | e | f | => r1 | d | e | f | 0 |
* +----+----+----+ +----+----+----+----+
* r2 | g | h | i | r2 | g | h | i | 0 |
* +----+----+----+ +----+----+----+----+
* r3 | 0 | 0 | 0 | 1 |
* +----+----+----+----+
* ~~~
*/
pure fn to_mat4(&self) -> Mat4<T>;
}
/**
* A 4 x 4 matrix
*/
pub trait Matrix4<T,V>: Matrix<T,V> {}
}

View file

@ -11,6 +11,7 @@ use numeric::number::Number::{zero,one};
use vec::{
Vec2,
Vector2,
vec2,
dvec2,
};
@ -19,8 +20,10 @@ use mat::{
Mat3,
Mat4,
Matrix,
MutableMatrix,
Matrix2,
Matrix3,
Matrix4,
MutableMatrix,
};
/**
@ -39,52 +42,14 @@ use mat::{
#[deriving_eq]
pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
pub impl<T:Copy Float> Mat2<T> {
/**
* Construct a 2 x 2 matrix
*
* # Arguments
*
* * `c0r0`, `c0r1` - the first column of the matrix
* * `c1r0`, `c1r1` - the second column of the matrix
*
* ~~~
* c0 c1
* +------+------+
* r0 | c0r0 | c1r0 |
* +------+------+
* r1 | c0r1 | c1r1 |
* +------+------+
* ~~~
*/
pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
#[inline(always)]
static pure fn new(c0r0: T, c0r1: T,
c1r0: T, c1r1: T) -> Mat2<T> {
Mat2::from_cols(Vec2::new(c0r0, c0r1),
Vec2::new(c1r0, c1r1))
}
pure fn col(&self, i: uint) -> Vec2<T> { self[i] }
/**
* Construct a 2 x 2 matrix from column vectors
*
* # Arguments
*
* * `c0` - the first column vector of the matrix
* * `c1` - the second column vector of the matrix
*
* ~~~
* c0 c1
* +------+------+
* r0 | c0.x | c1.x |
* +------+------+
* r1 | c0.y | c1.y |
* +------+------+
* ~~~
*/
#[inline(always)]
static pure fn from_cols(c0: Vec2<T>,
c1: Vec2<T>) -> Mat2<T> {
Mat2 { x: c0, y: c1 }
pure fn row(&self, i: uint) -> Vec2<T> {
Vector2::new(self[0][i],
self[1][i])
}
/**
@ -105,37 +70,8 @@ pub impl<T:Copy Float> Mat2<T> {
*/
#[inline(always)]
static pure fn from_value(value: T) -> Mat2<T> {
Mat2::new(value, zero(),
zero(), value)
}
// FIXME: An interim solution to the issues with static functions
#[inline(always)]
static pure fn from_angle(radians: T) -> Mat2<T> {
let cos_theta = cos(radians);
let sin_theta = sin(radians);
Mat2::new(cos_theta, -sin_theta,
sin_theta, cos_theta)
}
/// Wrapper method for `Matrix::identity`
#[inline(always)]
static pure fn identity() -> Mat2<T> { Matrix::identity() }
/// Wrapper method for `Matrix::zero`
#[inline(always)]
static pure fn zero() -> Mat2<T> { Matrix::zero() }
}
pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec2<T> { self[i] }
#[inline(always)]
pure fn row(&self, i: uint) -> Vec2<T> {
Vec2::new(self[0][i],
self[1][i])
Matrix2::new(value, zero(),
zero(), value)
}
/**
@ -151,8 +87,8 @@ pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
*/
#[inline(always)]
static pure fn identity() -> Mat2<T> {
Mat2::new(one(), zero(),
zero(), one())
Matrix2::new( one::<T>(), zero::<T>(),
zero::<T>(), one::<T>())
}
/**
@ -168,38 +104,38 @@ pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
*/
#[inline(always)]
static pure fn zero() -> Mat2<T> {
Mat2::new(zero(), zero(),
zero(), zero())
Matrix2::new(zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>())
}
#[inline(always)]
pure fn mul_t(&self, value: T) -> Mat2<T> {
Mat2::from_cols(self[0].mul_t(value),
self[1].mul_t(value))
Matrix2::from_cols(self[0].mul_t(value),
self[1].mul_t(value))
}
#[inline(always)]
pure fn mul_v(&self, vec: &Vec2<T>) -> Vec2<T> {
Vec2::new(self.row(0).dot(vec),
self.row(1).dot(vec))
Vector2::new(self.row(0).dot(vec),
self.row(1).dot(vec))
}
#[inline(always)]
pure fn add_m(&self, other: &Mat2<T>) -> Mat2<T> {
Mat2::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]))
Matrix2::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]))
}
#[inline(always)]
pure fn sub_m(&self, other: &Mat2<T>) -> Mat2<T> {
Mat2::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]))
Matrix2::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]))
}
#[inline(always)]
pure fn mul_m(&self, other: &Mat2<T>) -> Mat2<T> {
Mat2::new(self.row(0).dot(&other.col(0)), self.row(1).dot(&other.col(0)),
self.row(0).dot(&other.col(1)), self.row(1).dot(&other.col(1)))
Matrix2::new(self.row(0).dot(&other.col(0)), self.row(1).dot(&other.col(0)),
self.row(0).dot(&other.col(1)), self.row(1).dot(&other.col(1)))
}
pure fn dot(&self, other: &Mat2<T>) -> T {
@ -220,21 +156,20 @@ pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
if d.fuzzy_eq(&zero()) {
None
} else {
Some(Mat2::new( self[1][1]/d, -self[0][1]/d,
-self[1][0]/d, self[0][0]/d))
Some(Matrix2::new( self[1][1]/d, -self[0][1]/d,
-self[1][0]/d, self[0][0]/d))
}
}
#[inline(always)]
pure fn transpose(&self) -> Mat2<T> {
Mat2::new(self[0][0], self[1][0],
self[0][1], self[1][1])
Matrix2::new(self[0][0], self[1][0],
self[0][1], self[1][1])
}
#[inline(always)]
pure fn is_identity(&self) -> bool {
// self.fuzzy_eq(&Matrix::identity()) // FIXME: there's something wrong with static functions here!
self.fuzzy_eq(&Mat2::identity())
self.fuzzy_eq(&Matrix::identity())
}
#[inline(always)]
@ -245,8 +180,7 @@ pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
#[inline(always)]
pure fn is_rotated(&self) -> bool {
// !self.fuzzy_eq(&Matrix::identity()) // FIXME: there's something wrong with static functions here!
!self.fuzzy_eq(&Mat2::identity())
!self.fuzzy_eq(&Matrix::identity())
}
#[inline(always)]
@ -299,12 +233,12 @@ pub impl<T:Copy Float> Mat2<T>: MutableMatrix<T, Vec2<T>> {
#[inline(always)]
fn to_identity(&mut self) {
(*self) = Mat2::identity();
(*self) = Matrix::identity();
}
#[inline(always)]
fn to_zero(&mut self) {
(*self) = Mat2::zero();
(*self) = Matrix::zero();
}
#[inline(always)]
@ -341,19 +275,103 @@ pub impl<T:Copy Float> Mat2<T>: MutableMatrix<T, Vec2<T>> {
}
pub impl<T:Copy Float> Mat2<T>: Matrix2<T, Vec2<T>> {
/**
* Construct a 2 x 2 matrix
*
* # Arguments
*
* * `c0r0`, `c0r1` - the first column of the matrix
* * `c1r0`, `c1r1` - the second column of the matrix
*
* ~~~
* c0 c1
* +------+------+
* r0 | c0r0 | c1r0 |
* +------+------+
* r1 | c0r1 | c1r1 |
* +------+------+
* ~~~
*/
#[inline(always)]
pure fn to_mat3(&self) -> Mat3<T> {
Mat3::new(self[0][0], self[0][1], zero(),
self[1][0], self[1][1], zero(),
zero(), zero(), one())
static pure fn new(c0r0: T, c0r1: T,
c1r0: T, c1r1: T) -> Mat2<T> {
Matrix2::from_cols(Vector2::new::<T,Vec2<T>>(c0r0, c0r1),
Vector2::new::<T,Vec2<T>>(c1r0, c1r1))
}
/**
* Construct a 2 x 2 matrix from column vectors
*
* # Arguments
*
* * `c0` - the first column vector of the matrix
* * `c1` - the second column vector of the matrix
*
* ~~~
* c0 c1
* +------+------+
* r0 | c0.x | c1.x |
* +------+------+
* r1 | c0.y | c1.y |
* +------+------+
* ~~~
*/
#[inline(always)]
static pure fn from_cols(c0: Vec2<T>,
c1: Vec2<T>) -> Mat2<T> {
Mat2 { x: c0, y: c1 }
}
#[inline(always)]
static pure fn from_angle(radians: T) -> Mat2<T> {
let cos_theta = cos(radians);
let sin_theta = sin(radians);
Matrix2::new(cos_theta, -sin_theta,
sin_theta, cos_theta)
}
/**
* Returns the the matrix with an extra row and column added
* ~~~
* c0 c1 c0 c1 c2
* +----+----+ +----+----+----+
* r0 | a | b | r0 | a | b | 0 |
* +----+----+ +----+----+----+
* r1 | c | d | => r1 | c | d | 0 |
* +----+----+ +----+----+----+
* r2 | 0 | 0 | 1 |
* +----+----+----+
* ~~~
*/
#[inline(always)]
pure fn to_mat3(&self) -> Mat3<T> {
Matrix3::new(self[0][0], self[0][1], zero(),
self[1][0], self[1][1], zero(),
zero(), zero(), one())
}
/**
* Returns the the matrix with an extra two rows and columns added
* ~~~
* c0 c1 c0 c1 c2 c3
* +----+----+ +----+----+----+----+
* r0 | a | b | r0 | a | b | 0 | 0 |
* +----+----+ +----+----+----+----+
* r1 | c | d | => r1 | c | d | 0 | 0 |
* +----+----+ +----+----+----+----+
* r2 | 0 | 0 | 1 | 0 |
* +----+----+----+----+
* r3 | 0 | 0 | 0 | 1 |
* +----+----+----+----+
* ~~~
*/
#[inline(always)]
pure fn to_mat4(&self) -> Mat4<T> {
Mat4::new(self[0][0], self[0][1], zero(), zero(),
self[1][0], self[1][1], zero(), zero(),
zero(), zero(), one(), zero(),
zero(), zero(), zero(), one())
Matrix4::new(self[0][0], self[0][1], zero(), zero(),
self[1][0], self[1][1], zero(), zero(),
zero(), zero(), one(), zero(),
zero(), zero(), zero(), one())
}
}
@ -370,7 +388,7 @@ pub impl<T:Copy> Mat2<T>: Index<uint, Vec2<T>> {
pub impl<T:Copy Float> Mat2<T>: Neg<Mat2<T>> {
#[inline(always)]
pure fn neg(&self) -> Mat2<T> {
Mat2::from_cols(-self[0], -self[1])
Matrix2::from_cols(-self[0], -self[1])
}
}
@ -385,22 +403,22 @@ pub impl<T:Copy Float> Mat2<T>: FuzzyEq {
// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification]
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
pub type mat2 = Mat2<f32>; /// a 2×2 single-precision floating-point matrix
pub type dmat2 = Mat2<f64>; /// a 2×2 double-precision floating-point matrix
pub type mat2 = Mat2<f32>; // a 2×2 single-precision floating-point matrix
pub type dmat2 = Mat2<f64>; // a 2×2 double-precision floating-point matrix
// Static method wrappers for GLSL-style types
pub impl mat2 {
#[inline(always)] static pure fn new(c0r0: f32, c0r1: f32, c1r0: f32, c1r1: f32)
-> mat2 { Mat2::new(c0r0, c0r1, c1r0, c1r1) }
-> mat2 { Matrix2::new(c0r0, c0r1, c1r0, c1r1) }
#[inline(always)] static pure fn from_cols(c0: vec2, c1: vec2)
-> mat2 { Mat2::from_cols(move c0, move c1) }
#[inline(always)] static pure fn from_value(v: f32) -> mat2 { Mat2::from_value(v) }
-> mat2 { Matrix2::from_cols(move c0, move c1) }
#[inline(always)] static pure fn from_value(v: f32) -> mat2 { Matrix::from_value(v) }
#[inline(always)] static pure fn identity() -> mat2 { Matrix::identity() }
#[inline(always)] static pure fn zero() -> mat2 { Matrix::zero() }
#[inline(always)] static pure fn from_angle(radians: f32) -> mat2 { Mat2::from_angle(radians) }
#[inline(always)] static pure fn from_angle(radians: f32) -> mat2 { Matrix2::from_angle(radians) }
#[inline(always)] static pure fn dim() -> uint { 2 }
#[inline(always)] static pure fn rows() -> uint { 2 }
@ -410,14 +428,16 @@ pub impl mat2 {
pub impl dmat2 {
#[inline(always)] static pure fn new(c0r0: f64, c0r1: f64, c1r0: f64, c1r1: f64)
-> dmat2 { Mat2::new(c0r0, c0r1, c1r0, c1r1) }
-> dmat2 { Matrix2::new(c0r0, c0r1, c1r0, c1r1) }
#[inline(always)] static pure fn from_cols(c0: dvec2, c1: dvec2)
-> dmat2 { Mat2::from_cols(move c0, move c1) }
#[inline(always)] static pure fn from_value(v: f64) -> dmat2 { Mat2::from_value(v) }
-> dmat2 { Matrix2::from_cols(move c0, move c1) }
#[inline(always)] static pure fn from_value(v: f64) -> dmat2 { Matrix::from_value(v) }
#[inline(always)] static pure fn identity() -> dmat2 { Matrix::identity() }
#[inline(always)] static pure fn zero() -> dmat2 { Matrix::zero() }
#[inline(always)] static pure fn from_angle(radians: f64) -> dmat2 { Matrix2::from_angle(radians) }
#[inline(always)] static pure fn dim() -> uint { 2 }
#[inline(always)] static pure fn rows() -> uint { 2 }
#[inline(always)] static pure fn cols() -> uint { 2 }

View file

@ -15,6 +15,7 @@ use rot::Rotation;
use vec::{
Vec3,
Vector3,
vec3,
dvec3,
};
@ -22,8 +23,9 @@ use vec::{
use mat::{
Mat4,
Matrix,
MutableMatrix,
Matrix3,
Matrix4,
MutableMatrix,
};
/**
@ -42,7 +44,207 @@ use mat::{
#[deriving_eq]
pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
pub impl<T:Copy Float> Mat3<T> {
pub impl<T:Copy Float> Mat3<T>: Matrix<T, Vec3<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec3<T> { self[i] }
#[inline(always)]
pure fn row(&self, i: uint) -> Vec3<T> {
Vector3::new(self[0][i],
self[1][i],
self[2][i])
}
/**
* Construct a 3 x 3 diagonal matrix with the major diagonal set to `value`
*
* # Arguments
*
* * `value` - the value to set the major diagonal to
*
* ~~~
* c0 c1 c2
* +-----+-----+-----+
* r0 | val | 0 | 0 |
* +-----+-----+-----+
* r1 | 0 | val | 0 |
* +-----+-----+-----+
* r2 | 0 | 0 | val |
* +-----+-----+-----+
* ~~~
*/
#[inline(always)]
static pure fn from_value(value: T) -> Mat3<T> {
Matrix3::new(value, zero(), zero(),
zero(), value, zero(),
zero(), zero(), value)
}
/**
* Returns the multiplicative identity matrix
* ~~~
* c0 c1 c2
* +----+----+----+
* r0 | 1 | 0 | 0 |
* +----+----+----+
* r1 | 0 | 1 | 0 |
* +----+----+----+
* r2 | 0 | 0 | 1 |
* +----+----+----+
* ~~~
*/
#[inline(always)]
static pure fn identity() -> Mat3<T> {
Matrix3::new( one::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), one::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), one::<T>())
}
/**
* Returns the additive identity matrix
* ~~~
* c0 c1 c2
* +----+----+----+
* r0 | 0 | 0 | 0 |
* +----+----+----+
* r1 | 0 | 0 | 0 |
* +----+----+----+
* r2 | 0 | 0 | 0 |
* +----+----+----+
* ~~~
*/
#[inline(always)]
static pure fn zero() -> Mat3<T> {
Matrix3::new(zero::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
pure fn mul_t(&self, value: T) -> Mat3<T> {
Matrix3::from_cols(self[0].mul_t(value),
self[1].mul_t(value),
self[2].mul_t(value))
}
#[inline(always)]
pure fn mul_v(&self, vec: &Vec3<T>) -> Vec3<T> {
Vector3::new(self.row(0).dot(vec),
self.row(1).dot(vec),
self.row(2).dot(vec))
}
#[inline(always)]
pure fn add_m(&self, other: &Mat3<T>) -> Mat3<T> {
Matrix3::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]),
self[2].add_v(&other[2]))
}
#[inline(always)]
pure fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> {
Matrix3::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]),
self[2].sub_v(&other[2]))
}
#[inline(always)]
pure fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> {
Matrix3::new(self.row(0).dot(&other.col(0)),
self.row(1).dot(&other.col(0)),
self.row(2).dot(&other.col(0)),
self.row(0).dot(&other.col(1)),
self.row(1).dot(&other.col(1)),
self.row(2).dot(&other.col(1)),
self.row(0).dot(&other.col(2)),
self.row(1).dot(&other.col(2)),
self.row(2).dot(&other.col(2)))
}
pure fn dot(&self, other: &Mat3<T>) -> T {
other.transpose().mul_m(self).trace()
}
pure fn determinant(&self) -> T {
self.col(0).dot(&self.col(1).cross(&self.col(2)))
}
pure fn trace(&self) -> T {
self[0][0] + self[1][1] + self[2][2]
}
// #[inline(always)]
pure fn inverse(&self) -> Option<Mat3<T>> {
let d = self.determinant();
if d.fuzzy_eq(&zero()) {
None
} else {
let m: Mat3<T> = Matrix3::from_cols(self[1].cross(&self[2]).div_t(d),
self[2].cross(&self[0]).div_t(d),
self[0].cross(&self[1]).div_t(d));
Some(m.transpose())
}
}
#[inline(always)]
pure fn transpose(&self) -> Mat3<T> {
Matrix3::new(self[0][0], self[1][0], self[2][0],
self[0][1], self[1][1], self[2][1],
self[0][2], self[1][2], self[2][2])
}
#[inline(always)]
pure fn is_identity(&self) -> bool {
self.fuzzy_eq(&Matrix::identity())
}
#[inline(always)]
pure fn is_diagonal(&self) -> bool {
self[0][1].fuzzy_eq(&zero()) &&
self[0][2].fuzzy_eq(&zero()) &&
self[1][0].fuzzy_eq(&zero()) &&
self[1][2].fuzzy_eq(&zero()) &&
self[2][0].fuzzy_eq(&zero()) &&
self[2][1].fuzzy_eq(&zero())
}
#[inline(always)]
pure fn is_rotated(&self) -> bool {
!self.fuzzy_eq(&Matrix::identity())
}
#[inline(always)]
pure fn is_symmetric(&self) -> bool {
self[0][1].fuzzy_eq(&self[1][0]) &&
self[0][2].fuzzy_eq(&self[2][0]) &&
self[1][0].fuzzy_eq(&self[0][1]) &&
self[1][2].fuzzy_eq(&self[2][1]) &&
self[2][0].fuzzy_eq(&self[0][2]) &&
self[2][1].fuzzy_eq(&self[1][2])
}
#[inline(always)]
pure fn is_invertible(&self) -> bool {
!self.determinant().fuzzy_eq(&zero())
}
#[inline(always)]
pure fn to_ptr(&self) -> *T {
unsafe {
transmute::<*Mat3<T>, *T>(
to_unsafe_ptr(self)
)
}
}
}
pub impl<T:Copy Float> Mat3<T>: Matrix3<T, Vec3<T>> {
/**
* Construct a 3 x 3 matrix
*
@ -67,9 +269,9 @@ pub impl<T:Copy Float> Mat3<T> {
static pure fn new(c0r0:T, c0r1:T, c0r2:T,
c1r0:T, c1r1:T, c1r2:T,
c2r0:T, c2r1:T, c2r2:T) -> Mat3<T> {
Mat3::from_cols(Vec3::new(c0r0, c0r1, c0r2),
Vec3::new(c1r0, c1r1, c1r2),
Vec3::new(c2r0, c2r1, c2r2))
Matrix3::from_cols(Vector3::new::<T,Vec3<T>>(c0r0, c0r1, c0r2),
Vector3::new::<T,Vec3<T>>(c1r0, c1r1, c1r2),
Vector3::new::<T,Vec3<T>>(c2r0, c2r1, c2r2))
}
/**
@ -99,82 +301,46 @@ pub impl<T:Copy Float> Mat3<T> {
Mat3 { x: c0, y: c1, z: c2 }
}
/**
* Construct a 3 x 3 diagonal matrix with the major diagonal set to `value`
*
* # Arguments
*
* * `value` - the value to set the major diagonal to
*
* ~~~
* c0 c1 c2
* +-----+-----+-----+
* r0 | val | 0 | 0 |
* +-----+-----+-----+
* r1 | 0 | val | 0 |
* +-----+-----+-----+
* r2 | 0 | 0 | val |
* +-----+-----+-----+
* ~~~
*/
#[inline(always)]
static pure fn from_value(value: T) -> Mat3<T> {
Mat3::new(value, zero(), zero(),
zero(), value, zero(),
zero(), zero(), value)
}
/// Wrapper method for `Matrix::identity`
#[inline(always)]
static pure fn identity() -> Mat3<T> { Matrix::identity() }
/// Wrapper method for `Matrix::zero`
#[inline(always)]
static pure fn zero() -> Mat3<T> { Matrix::zero() }
/**
* Construct a matrix from an angular rotation around the `x` axis
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_x(radians: T) -> Mat3<T> {
// http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
let cos_theta = cos(radians);
let sin_theta = sin(radians);
Mat3::new( one(), zero(), zero(),
zero(), cos_theta, sin_theta,
zero(), -sin_theta, cos_theta)
Matrix3::new( one(), zero(), zero(),
zero(), cos_theta, sin_theta,
zero(), -sin_theta, cos_theta)
}
/**
* Construct a matrix from an angular rotation around the `y` axis
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_y(radians: T) -> Mat3<T> {
// http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
let cos_theta = cos(radians);
let sin_theta = sin(radians);
Mat3::new(cos_theta, zero(), -sin_theta,
zero(), one(), zero(),
sin_theta, zero(), cos_theta)
Matrix3::new(cos_theta, zero(), -sin_theta,
zero(), one(), zero(),
sin_theta, zero(), cos_theta)
}
/**
* Construct a matrix from an angular rotation around the `z` axis
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_z(radians: T) -> Mat3<T> {
// http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
let cos_theta = cos(radians);
let sin_theta = sin(radians);
Mat3::new( cos_theta, sin_theta, zero(),
-sin_theta, cos_theta, zero(),
zero(), zero(), one())
Matrix3::new( cos_theta, sin_theta, zero(),
-sin_theta, cos_theta, zero(),
zero(), zero(), one())
}
/**
@ -186,7 +352,6 @@ pub impl<T:Copy Float> Mat3<T> {
* * `theta_y` - the angular rotation around the `y` axis (yaw)
* * `theta_z` - the angular rotation around the `z` axis (roll)
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Mat3<T> {
// http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations
@ -197,15 +362,14 @@ pub impl<T:Copy Float> Mat3<T> {
let cz = cos(radians_z);
let sz = sin(radians_z);
Mat3::new( cy*cz, cy*sz, -sy,
-cx*sz + sx*sy*cz, cx*cz + sx*sy*sz, sx*cy,
sx*sz + cx*sy*cz, -sx*cz + cx*sy*sz, cx*cy)
Matrix3::new( cy*cz, cy*sz, -sy,
-cx*sz + sx*sy*cz, cx*cz + sx*sy*sz, sx*cy,
sx*sz + cx*sy*cz, -sx*cz + cx*sy*sz, cx*cy)
}
/**
* Construct a matrix from an axis and an angular rotation
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Mat3<T> {
let c = cos(radians);
@ -216,43 +380,51 @@ pub impl<T:Copy Float> Mat3<T> {
let y = axis.y;
let z = axis.z;
Mat3::new(_1_c*x*x + c, _1_c*x*y + s*z, _1_c*x*z - s*y,
_1_c*x*y - s*z, _1_c*y*y + c, _1_c*y*z + s*x,
_1_c*x*z + s*y, _1_c*y*z - s*x, _1_c*z*z + c)
Matrix3::new(_1_c*x*x + c, _1_c*x*y + s*z, _1_c*x*z - s*y,
_1_c*x*y - s*z, _1_c*y*y + c, _1_c*y*z + s*x,
_1_c*x*z + s*y, _1_c*y*z - s*x, _1_c*z*z + c)
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_axes(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> Mat3<T> {
Mat3::from_cols(x, y, z)
Matrix3::from_cols(x, y, z)
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Mat3<T> {
let dir_ = dir.normalize();
let side = dir_.cross(&up.normalize());
let up_ = side.cross(&dir_).normalize();
Mat3::from_axes(up_, side, dir_)
Matrix3::from_axes(up_, side, dir_)
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
/**
* Returns the the matrix with an extra row and column added
* ~~~
* c0 c1 c2 c0 c1 c2 c3
* +----+----+----+ +----+----+----+----+
* r0 | a | b | c | r0 | a | b | c | 0 |
* +----+----+----+ +----+----+----+----+
* r1 | d | e | f | => r1 | d | e | f | 0 |
* +----+----+----+ +----+----+----+----+
* r2 | g | h | i | r2 | g | h | i | 0 |
* +----+----+----+ +----+----+----+----+
* r3 | 0 | 0 | 0 | 1 |
* +----+----+----+----+
* ~~~
*/
#[inline(always)]
pure fn concat(&self, other: &Mat3<T>) -> Mat3<T> { self.mul_m(other) }
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn rotate_vec(&self, vec: &Vec3<T>) -> Vec3<T> { self.mul_v(vec) }
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn to_mat3(&self) -> Mat3<T> { *self }
pure fn to_mat4(&self) -> Mat4<T> {
Matrix4::new(self[0][0], self[0][1], self[0][2], zero(),
self[1][0], self[1][1], self[1][2], zero(),
self[2][0], self[2][1], self[2][2], zero(),
zero(), zero(), zero(), one())
}
/**
* Convert the matrix to a quaternion
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn to_quat(&self) -> Quat<T> {
// Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's
@ -299,182 +471,6 @@ pub impl<T:Copy Float> Mat3<T> {
}
}
pub impl<T:Copy Float> Mat3<T>: Matrix<T, Vec3<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec3<T> { self[i] }
#[inline(always)]
pure fn row(&self, i: uint) -> Vec3<T> {
Vec3::new(self[0][i],
self[1][i],
self[2][i])
}
/**
* Returns the multiplicative identity matrix
* ~~~
* c0 c1 c2
* +----+----+----+
* r0 | 1 | 0 | 0 |
* +----+----+----+
* r1 | 0 | 1 | 0 |
* +----+----+----+
* r2 | 0 | 0 | 1 |
* +----+----+----+
* ~~~
*/
#[inline(always)]
static pure fn identity() -> Mat3<T> {
Mat3::new( one(), zero(), zero(),
zero(), one(), zero(),
zero(), zero(), one())
}
/**
* Returns the additive identity matrix
* ~~~
* c0 c1 c2
* +----+----+----+
* r0 | 0 | 0 | 0 |
* +----+----+----+
* r1 | 0 | 0 | 0 |
* +----+----+----+
* r2 | 0 | 0 | 0 |
* +----+----+----+
* ~~~
*/
#[inline(always)]
static pure fn zero() -> Mat3<T> {
Mat3::new(zero(), zero(), zero(),
zero(), zero(), zero(),
zero(), zero(), zero())
}
#[inline(always)]
pure fn mul_t(&self, value: T) -> Mat3<T> {
Mat3::from_cols(self[0].mul_t(value),
self[1].mul_t(value),
self[2].mul_t(value))
}
#[inline(always)]
pure fn mul_v(&self, vec: &Vec3<T>) -> Vec3<T> {
Vec3::new(self.row(0).dot(vec),
self.row(1).dot(vec),
self.row(2).dot(vec))
}
#[inline(always)]
pure fn add_m(&self, other: &Mat3<T>) -> Mat3<T> {
Mat3::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]),
self[2].add_v(&other[2]))
}
#[inline(always)]
pure fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> {
Mat3::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]),
self[2].sub_v(&other[2]))
}
#[inline(always)]
pure fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> {
Mat3::new(self.row(0).dot(&other.col(0)),
self.row(1).dot(&other.col(0)),
self.row(2).dot(&other.col(0)),
self.row(0).dot(&other.col(1)),
self.row(1).dot(&other.col(1)),
self.row(2).dot(&other.col(1)),
self.row(0).dot(&other.col(2)),
self.row(1).dot(&other.col(2)),
self.row(2).dot(&other.col(2)))
}
pure fn dot(&self, other: &Mat3<T>) -> T {
other.transpose().mul_m(self).trace()
}
pure fn determinant(&self) -> T {
self.col(0).dot(&self.col(1).cross(&self.col(2)))
}
pure fn trace(&self) -> T {
self[0][0] + self[1][1] + self[2][2]
}
// #[inline(always)]
pure fn inverse(&self) -> Option<Mat3<T>> {
let d = self.determinant();
if d.fuzzy_eq(&zero()) {
None
} else {
Some(Mat3::from_cols(self[1].cross(&self[2]).div_t(d),
self[2].cross(&self[0]).div_t(d),
self[0].cross(&self[1]).div_t(d)).transpose())
}
}
#[inline(always)]
pure fn transpose(&self) -> Mat3<T> {
Mat3::new(self[0][0], self[1][0], self[2][0],
self[0][1], self[1][1], self[2][1],
self[0][2], self[1][2], self[2][2])
}
#[inline(always)]
pure fn is_identity(&self) -> bool {
// self.fuzzy_eq(&Matrix::identity()) // FIXME: there's something wrong with static functions here!
self.fuzzy_eq(&Mat3::identity())
}
#[inline(always)]
pure fn is_diagonal(&self) -> bool {
self[0][1].fuzzy_eq(&zero()) &&
self[0][2].fuzzy_eq(&zero()) &&
self[1][0].fuzzy_eq(&zero()) &&
self[1][2].fuzzy_eq(&zero()) &&
self[2][0].fuzzy_eq(&zero()) &&
self[2][1].fuzzy_eq(&zero())
}
#[inline(always)]
pure fn is_rotated(&self) -> bool {
// !self.fuzzy_eq(&Matrix::identity()) // FIXME: there's something wrong with static functions here!
!self.fuzzy_eq(&Mat3::identity())
}
#[inline(always)]
pure fn is_symmetric(&self) -> bool {
self[0][1].fuzzy_eq(&self[1][0]) &&
self[0][2].fuzzy_eq(&self[2][0]) &&
self[1][0].fuzzy_eq(&self[0][1]) &&
self[1][2].fuzzy_eq(&self[2][1]) &&
self[2][0].fuzzy_eq(&self[0][2]) &&
self[2][1].fuzzy_eq(&self[1][2])
}
#[inline(always)]
pure fn is_invertible(&self) -> bool {
!self.determinant().fuzzy_eq(&zero())
}
#[inline(always)]
pure fn to_ptr(&self) -> *T {
unsafe {
transmute::<*Mat3<T>, *T>(
to_unsafe_ptr(self)
)
}
}
}
pub impl<T:Copy Float> Mat3<T>: MutableMatrix<T, Vec3<T>> {
#[inline(always)]
fn col_mut(&mut self, i: uint) -> &self/mut Vec3<T> {
@ -506,12 +502,12 @@ pub impl<T:Copy Float> Mat3<T>: MutableMatrix<T, Vec3<T>> {
#[inline(always)]
fn to_identity(&mut self) {
(*self) = Mat3::identity();
(*self) = Matrix::identity();
}
#[inline(always)]
fn to_zero(&mut self) {
(*self) = Mat3::zero();
(*self) = Matrix::zero();
}
#[inline(always)]
@ -556,16 +552,6 @@ pub impl<T:Copy Float> Mat3<T>: MutableMatrix<T, Vec3<T>> {
}
}
pub impl<T:Copy Float> Mat3<T>: Matrix3<T, Vec3<T>> {
#[inline(always)]
pure fn to_mat4(&self) -> Mat4<T> {
Mat4::new(self[0][0], self[0][1], self[0][2], zero(),
self[1][0], self[1][1], self[1][2], zero(),
self[2][0], self[2][1], self[2][2], zero(),
zero(), zero(), zero(), one())
}
}
pub impl<T:Copy> Mat3<T>: Index<uint, Vec3<T>> {
#[inline(always)]
pure fn index(&self, i: uint) -> Vec3<T> {
@ -579,7 +565,7 @@ pub impl<T:Copy> Mat3<T>: Index<uint, Vec3<T>> {
pub impl<T:Copy Float> Mat3<T>: Neg<Mat3<T>> {
#[inline(always)]
pure fn neg(&self) -> Mat3<T> {
Mat3::from_cols(-self[0], -self[1], -self[2])
Matrix3::from_cols(-self[0], -self[1], -self[2])
}
}
@ -595,28 +581,28 @@ pub impl<T:Copy Float> Mat3<T>: FuzzyEq {
// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification]
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
pub type mat3 = Mat3<f32>; /// a 3×3 single-precision floating-point matrix
pub type dmat3 = Mat3<f64>; /// a 3×3 double-precision floating-point matrix
pub type mat3 = Mat3<f32>; // a 3×3 single-precision floating-point matrix
pub type dmat3 = Mat3<f64>; // a 3×3 double-precision floating-point matrix
// Static method wrappers for GLSL-style types
pub impl mat3 {
#[inline(always)] static pure fn new(c0r0: f32, c0r1: f32, c0r2: f32, c1r0: f32, c1r1: f32, c1r2: f32, c2r0: f32, c2r1: f32, c2r2: f32)
-> mat3 { Mat3::new(c0r0, c0r1, c0r2, c1r0, c1r1, c1r2, c2r0, c2r1, c2r2) }
-> mat3 { Matrix3::new(c0r0, c0r1, c0r2, c1r0, c1r1, c1r2, c2r0, c2r1, c2r2) }
#[inline(always)] static pure fn from_cols(c0: vec3, c1: vec3, c2: vec3)
-> mat3 { Mat3::from_cols(move c0, move c1, move c2) }
#[inline(always)] static pure fn from_value(v: f32) -> mat3 { Mat3::from_value(v) }
-> mat3 { Matrix3::from_cols(move c0, move c1, move c2) }
#[inline(always)] static pure fn from_value(v: f32) -> mat3 { Matrix::from_value(v) }
#[inline(always)] static pure fn identity() -> mat3 { Matrix::identity() }
#[inline(always)] static pure fn zero() -> mat3 { Matrix::zero() }
#[inline(always)] static pure fn from_angle_x(radians: f32) -> mat3 { Mat3::from_angle_x(radians) }
#[inline(always)] static pure fn from_angle_y(radians: f32) -> mat3 { Mat3::from_angle_y(radians) }
#[inline(always)] static pure fn from_angle_z(radians: f32) -> mat3 { Mat3::from_angle_z(radians) }
#[inline(always)] static pure fn from_angle_xyz(radians_x: f32, radians_y: f32, radians_z: f32) -> mat3 { Mat3::from_angle_xyz(radians_x, radians_y, radians_z) }
#[inline(always)] static pure fn from_angle_axis(radians: f32, axis: &vec3) -> mat3 { Mat3::from_angle_axis(radians, axis) }
#[inline(always)] static pure fn from_axes(x: vec3, y: vec3, z: vec3) -> mat3 { Mat3::from_axes(x, y, z) }
#[inline(always)] static pure fn look_at(dir: &vec3, up: &vec3) -> mat3 { Mat3::look_at(dir, up) }
#[inline(always)] static pure fn from_angle_x(radians: f32) -> mat3 { Matrix3::from_angle_x(radians) }
#[inline(always)] static pure fn from_angle_y(radians: f32) -> mat3 { Matrix3::from_angle_y(radians) }
#[inline(always)] static pure fn from_angle_z(radians: f32) -> mat3 { Matrix3::from_angle_z(radians) }
#[inline(always)] static pure fn from_angle_xyz(radians_x: f32, radians_y: f32, radians_z: f32) -> mat3 { Matrix3::from_angle_xyz(radians_x, radians_y, radians_z) }
#[inline(always)] static pure fn from_angle_axis(radians: f32, axis: &vec3) -> mat3 { Matrix3::from_angle_axis(radians, axis) }
#[inline(always)] static pure fn from_axes(x: vec3, y: vec3, z: vec3) -> mat3 { Matrix3::from_axes(x, y, z) }
#[inline(always)] static pure fn look_at(dir: &vec3, up: &vec3) -> mat3 { Matrix3::look_at(dir, up) }
#[inline(always)] static pure fn dim() -> uint { 3 }
#[inline(always)] static pure fn rows() -> uint { 3 }
@ -627,10 +613,10 @@ pub impl mat3 {
pub impl dmat3 {
#[inline(always)] static pure fn new(c0r0: f64, c0r1: f64, c0r2: f64, c1r0: f64, c1r1: f64, c1r2: f64, c2r0: f64, c2r1: f64, c2r2: f64)
-> dmat3 { Mat3::new(c0r0, c0r1, c0r2, c1r0, c1r1, c1r2, c2r0, c2r1, c2r2) }
-> dmat3 { Matrix3::new(c0r0, c0r1, c0r2, c1r0, c1r1, c1r2, c2r0, c2r1, c2r2) }
#[inline(always)] static pure fn from_cols(c0: dvec3, c1: dvec3, c2: dvec3)
-> dmat3 { Mat3::from_cols(move c0, move c1, move c2) }
#[inline(always)] static pure fn from_value(v: f64) -> dmat3 { Mat3::from_value(v) }
-> dmat3 { Matrix3::from_cols(move c0, move c1, move c2) }
#[inline(always)] static pure fn from_value(v: f64) -> dmat3 { Matrix::from_value(v) }
#[inline(always)] static pure fn identity() -> dmat3 { Matrix::identity() }
#[inline(always)] static pure fn zero() -> dmat3 { Matrix::zero() }

View file

@ -11,6 +11,7 @@ use numeric::number::Number::{zero,one};
use vec::{
Vec4,
Vector4,
vec4,
dvec4,
};
@ -18,8 +19,9 @@ use vec::{
use mat::{
Mat3,
Matrix,
MutableMatrix,
Matrix3,
Matrix4,
MutableMatrix,
};
/**
@ -39,70 +41,16 @@ use mat::{
#[deriving_eq]
pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }
pub impl<T:Copy Float> Mat4<T> {
/**
* Construct a 4 x 4 matrix
*
* # Arguments
*
* * `c0r0`, `c0r1`, `c0r2`, `c0r3` - the first column of the matrix
* * `c1r0`, `c1r1`, `c1r2`, `c1r3` - the second column of the matrix
* * `c2r0`, `c2r1`, `c2r2`, `c2r3` - the third column of the matrix
* * `c3r0`, `c3r1`, `c3r2`, `c3r3` - the fourth column of the matrix
*
* ~~~
* c0 c1 c2 c3
* +------+------+------+------+
* r0 | c0r0 | c1r0 | c2r0 | c3r0 |
* +------+------+------+------+
* r1 | c0r1 | c1r1 | c2r1 | c3r1 |
* +------+------+------+------+
* r2 | c0r2 | c1r2 | c2r2 | c3r2 |
* +------+------+------+------+
* r3 | c0r3 | c1r3 | c2r3 | c3r3 |
* +------+------+------+------+
* ~~~
*/
pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)]
static pure fn new(c0r0: T, c0r1: T, c0r2: T, c0r3: T,
c1r0: T, c1r1: T, c1r2: T, c1r3: T,
c2r0: T, c2r1: T, c2r2: T, c2r3: T,
c3r0: T, c3r1: T, c3r2: T, c3r3: T) -> Mat4<T> {
Mat4::from_cols(Vec4::new(c0r0, c0r1, c0r2, c0r3),
Vec4::new(c1r0, c1r1, c1r2, c1r3),
Vec4::new(c2r0, c2r1, c2r2, c2r3),
Vec4::new(c3r0, c3r1, c3r2, c3r3))
}
pure fn col(&self, i: uint) -> Vec4<T> { self[i] }
/**
* Construct a 4 x 4 matrix from column vectors
*
* # Arguments
*
* * `c0` - the first column vector of the matrix
* * `c1` - the second column vector of the matrix
* * `c2` - the third column vector of the matrix
* * `c3` - the fourth column vector of the matrix
*
* ~~~
* c0 c1 c2 c3
* +------+------+------+------+
* r0 | c0.x | c1.x | c2.x | c3.x |
* +------+------+------+------+
* r1 | c0.y | c1.y | c2.y | c3.y |
* +------+------+------+------+
* r2 | c0.z | c1.z | c2.z | c3.z |
* +------+------+------+------+
* r3 | c0.w | c1.w | c2.w | c3.w |
* +------+------+------+------+
* ~~~
*/
#[inline(always)]
static pure fn from_cols(c0: Vec4<T>,
c1: Vec4<T>,
c2: Vec4<T>,
c3: Vec4<T>) -> Mat4<T> {
Mat4 { x: c0, y: c1, z: c2, w: c3 }
pure fn row(&self, i: uint) -> Vec4<T> {
Vector4::new(self[0][i],
self[1][i],
self[2][i],
self[3][i])
}
/**
@ -127,31 +75,10 @@ pub impl<T:Copy Float> Mat4<T> {
*/
#[inline(always)]
static pure fn from_value(value: T) -> Mat4<T> {
Mat4::new(value, zero(), zero(), zero(),
zero(), value, zero(), zero(),
zero(), zero(), value, zero(),
zero(), zero(), zero(), value)
}
/// Wrapper method for `Matrix::identity`
#[inline(always)]
static pure fn identity() -> Mat4<T> { Matrix::identity() }
/// Wrapper method for `Matrix::zero`
#[inline(always)]
static pure fn zero() -> Mat4<T> { Matrix::zero() }
}
pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec4<T> { self[i] }
#[inline(always)]
pure fn row(&self, i: uint) -> Vec4<T> {
Vec4::new(self[0][i],
self[1][i],
self[2][i],
self[3][i])
Matrix4::new(value, zero(), zero(), zero(),
zero(), value, zero(), zero(),
zero(), zero(), value, zero(),
zero(), zero(), zero(), value)
}
/**
@ -171,10 +98,10 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
*/
#[inline(always)]
static pure fn identity() -> Mat4<T> {
Mat4::new( one(), zero(), zero(), zero(),
zero(), one(), zero(), zero(),
zero(), zero(), one(), zero(),
zero(), zero(), zero(), one())
Matrix4::new( one::<T>(), zero::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), one::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), one::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), zero::<T>(), one::<T>())
}
/**
@ -194,65 +121,65 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
*/
#[inline(always)]
static pure fn zero() -> Mat4<T> {
Mat4::new(zero(), zero(), zero(), zero(),
zero(), zero(), zero(), zero(),
zero(), zero(), zero(), zero(),
zero(), zero(), zero(), zero())
Matrix4::new(zero::<T>(), zero::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), zero::<T>(), zero::<T>(),
zero::<T>(), zero::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
pure fn mul_t(&self, value: T) -> Mat4<T> {
Mat4::from_cols(self[0].mul_t(value),
self[1].mul_t(value),
self[2].mul_t(value),
self[3].mul_t(value))
Matrix4::from_cols(self[0].mul_t(value),
self[1].mul_t(value),
self[2].mul_t(value),
self[3].mul_t(value))
}
#[inline(always)]
pure fn mul_v(&self, vec: &Vec4<T>) -> Vec4<T> {
Vec4::new(self.row(0).dot(vec),
self.row(1).dot(vec),
self.row(2).dot(vec),
self.row(3).dot(vec))
Vector4::new(self.row(0).dot(vec),
self.row(1).dot(vec),
self.row(2).dot(vec),
self.row(3).dot(vec))
}
#[inline(always)]
pure fn add_m(&self, other: &Mat4<T>) -> Mat4<T> {
Mat4::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]),
self[2].add_v(&other[2]),
self[3].add_v(&other[3]))
Matrix4::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]),
self[2].add_v(&other[2]),
self[3].add_v(&other[3]))
}
#[inline(always)]
pure fn sub_m(&self, other: &Mat4<T>) -> Mat4<T> {
Mat4::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]),
self[2].sub_v(&other[2]),
self[3].sub_v(&other[3]))
Matrix4::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]),
self[2].sub_v(&other[2]),
self[3].sub_v(&other[3]))
}
#[inline(always)]
pure fn mul_m(&self, other: &Mat4<T>) -> Mat4<T> {
Mat4::new(self.row(0).dot(&other.col(0)),
self.row(1).dot(&other.col(0)),
self.row(2).dot(&other.col(0)),
self.row(3).dot(&other.col(0)),
Matrix4::new(self.row(0).dot(&other.col(0)),
self.row(1).dot(&other.col(0)),
self.row(2).dot(&other.col(0)),
self.row(3).dot(&other.col(0)),
self.row(0).dot(&other.col(1)),
self.row(1).dot(&other.col(1)),
self.row(2).dot(&other.col(1)),
self.row(3).dot(&other.col(1)),
self.row(0).dot(&other.col(1)),
self.row(1).dot(&other.col(1)),
self.row(2).dot(&other.col(1)),
self.row(3).dot(&other.col(1)),
self.row(0).dot(&other.col(2)),
self.row(1).dot(&other.col(2)),
self.row(2).dot(&other.col(2)),
self.row(3).dot(&other.col(2)),
self.row(0).dot(&other.col(2)),
self.row(1).dot(&other.col(2)),
self.row(2).dot(&other.col(2)),
self.row(3).dot(&other.col(2)),
self.row(0).dot(&other.col(3)),
self.row(1).dot(&other.col(3)),
self.row(2).dot(&other.col(3)),
self.row(3).dot(&other.col(3)))
self.row(0).dot(&other.col(3)),
self.row(1).dot(&other.col(3)),
self.row(2).dot(&other.col(3)),
self.row(3).dot(&other.col(3)))
}
@ -261,18 +188,23 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
}
pure fn determinant(&self) -> T {
self[0][0]*Mat3::new(self[1][1], self[2][1], self[3][1],
self[1][2], self[2][2], self[3][2],
self[1][3], self[2][3], self[3][3]).determinant() -
self[1][0]*Mat3::new(self[0][1], self[2][1], self[3][1],
self[0][2], self[2][2], self[3][2],
self[0][3], self[2][3], self[3][3]).determinant() +
self[2][0]*Mat3::new(self[0][1], self[1][1], self[3][1],
self[0][2], self[1][2], self[3][2],
self[0][3], self[1][3], self[3][3]).determinant() -
self[3][0]*Mat3::new(self[0][1], self[1][1], self[2][1],
self[0][2], self[1][2], self[2][2],
self[0][3], self[1][3], self[2][3]).determinant()
let m0: Mat3<T> = Matrix3::new(self[1][1], self[2][1], self[3][1],
self[1][2], self[2][2], self[3][2],
self[1][3], self[2][3], self[3][3]);
let m1: Mat3<T> = Matrix3::new(self[0][1], self[2][1], self[3][1],
self[0][2], self[2][2], self[3][2],
self[0][3], self[2][3], self[3][3]);
let m2: Mat3<T> = Matrix3::new(self[0][1], self[1][1], self[3][1],
self[0][2], self[1][2], self[3][2],
self[0][3], self[1][3], self[3][3]);
let m3: Mat3<T> = Matrix3::new(self[0][1], self[1][1], self[2][1],
self[0][2], self[1][2], self[2][2],
self[0][3], self[1][3], self[2][3]);
self[0][0] * m0.determinant() -
self[1][0] * m1.determinant() +
self[2][0] * m2.determinant() -
self[3][0] * m3.determinant()
}
pure fn trace(&self) -> T {
@ -290,8 +222,7 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
// and essentially reduce [A|I]
let mut A = *self;
// let mut I: Mat4<T> = Matrix::identity(); // FIXME: there's something wrong with static functions here!
let mut I = Mat4::identity();
let mut I: Mat4<T> = Matrix::identity();
for uint::range(0, 4) |j| {
// Find largest element in col j
@ -328,16 +259,15 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)]
pure fn transpose(&self) -> Mat4<T> {
Mat4::new(self[0][0], self[1][0], self[2][0], self[3][0],
self[0][1], self[1][1], self[2][1], self[3][1],
self[0][2], self[1][2], self[2][2], self[3][2],
self[0][3], self[1][3], self[2][3], self[3][3])
Matrix4::new(self[0][0], self[1][0], self[2][0], self[3][0],
self[0][1], self[1][1], self[2][1], self[3][1],
self[0][2], self[1][2], self[2][2], self[3][2],
self[0][3], self[1][3], self[2][3], self[3][3])
}
#[inline(always)]
pure fn is_identity(&self) -> bool {
// self.fuzzy_eq(&Matrix::identity()) // FIXME: there's something wrong with static functions here!
self.fuzzy_eq(&Mat4::identity())
self.fuzzy_eq(&Matrix::identity())
}
#[inline(always)]
@ -361,8 +291,7 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)]
pure fn is_rotated(&self) -> bool {
// !self.fuzzy_eq(&Matrix::identity()) // FIXME: there's something wrong with static functions here!
!self.fuzzy_eq(&Mat4::identity())
!self.fuzzy_eq(&Matrix::identity())
}
#[inline(always)]
@ -399,6 +328,73 @@ pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
}
}
pub impl<T:Copy Float> Mat4<T>: Matrix4<T, Vec4<T>> {
/**
* Construct a 4 x 4 matrix
*
* # Arguments
*
* * `c0r0`, `c0r1`, `c0r2`, `c0r3` - the first column of the matrix
* * `c1r0`, `c1r1`, `c1r2`, `c1r3` - the second column of the matrix
* * `c2r0`, `c2r1`, `c2r2`, `c2r3` - the third column of the matrix
* * `c3r0`, `c3r1`, `c3r2`, `c3r3` - the fourth column of the matrix
*
* ~~~
* c0 c1 c2 c3
* +------+------+------+------+
* r0 | c0r0 | c1r0 | c2r0 | c3r0 |
* +------+------+------+------+
* r1 | c0r1 | c1r1 | c2r1 | c3r1 |
* +------+------+------+------+
* r2 | c0r2 | c1r2 | c2r2 | c3r2 |
* +------+------+------+------+
* r3 | c0r3 | c1r3 | c2r3 | c3r3 |
* +------+------+------+------+
* ~~~
*/
#[inline(always)]
static pure fn new(c0r0: T, c0r1: T, c0r2: T, c0r3: T,
c1r0: T, c1r1: T, c1r2: T, c1r3: T,
c2r0: T, c2r1: T, c2r2: T, c2r3: T,
c3r0: T, c3r1: T, c3r2: T, c3r3: T) -> Mat4<T> {
Matrix4::from_cols(Vector4::new::<T,Vec4<T>>(c0r0, c0r1, c0r2, c0r3),
Vector4::new::<T,Vec4<T>>(c1r0, c1r1, c1r2, c1r3),
Vector4::new::<T,Vec4<T>>(c2r0, c2r1, c2r2, c2r3),
Vector4::new::<T,Vec4<T>>(c3r0, c3r1, c3r2, c3r3))
}
/**
* Construct a 4 x 4 matrix from column vectors
*
* # Arguments
*
* * `c0` - the first column vector of the matrix
* * `c1` - the second column vector of the matrix
* * `c2` - the third column vector of the matrix
* * `c3` - the fourth column vector of the matrix
*
* ~~~
* c0 c1 c2 c3
* +------+------+------+------+
* r0 | c0.x | c1.x | c2.x | c3.x |
* +------+------+------+------+
* r1 | c0.y | c1.y | c2.y | c3.y |
* +------+------+------+------+
* r2 | c0.z | c1.z | c2.z | c3.z |
* +------+------+------+------+
* r3 | c0.w | c1.w | c2.w | c3.w |
* +------+------+------+------+
* ~~~
*/
#[inline(always)]
static pure fn from_cols(c0: Vec4<T>,
c1: Vec4<T>,
c2: Vec4<T>,
c3: Vec4<T>) -> Mat4<T> {
Mat4 { x: c0, y: c1, z: c2, w: c3 }
}
}
pub impl<T:Copy Float> Mat4<T>: MutableMatrix<T, Vec4<T>> {
#[inline(always)]
fn col_mut(&mut self, i: uint) -> &self/mut Vec4<T> {
@ -432,12 +428,12 @@ pub impl<T:Copy Float> Mat4<T>: MutableMatrix<T, Vec4<T>> {
#[inline(always)]
fn to_identity(&mut self) {
(*self) = Mat4::identity();
(*self) = Matrix::identity();
}
#[inline(always)]
fn to_zero(&mut self) {
(*self) = Mat4::zero();
(*self) = Matrix::zero();
}
#[inline(always)]
@ -492,12 +488,10 @@ pub impl<T:Copy Float> Mat4<T>: MutableMatrix<T, Vec4<T>> {
}
}
pub impl<T> Mat4<T>: Matrix4<T, Vec4<T>> {}
pub impl<T:Copy Float> Mat4<T>: Neg<Mat4<T>> {
#[inline(always)]
pure fn neg(&self) -> Mat4<T> {
Mat4::from_cols(-self[0], -self[1], -self[2], -self[3])
Matrix4::from_cols(-self[0], -self[1], -self[2], -self[3])
}
}
@ -524,17 +518,17 @@ pub impl<T:Copy Float> Mat4<T>: FuzzyEq {
// GLSL-style type aliases, corresponding to Section 4.1.6 of the [GLSL 4.30.6 specification]
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
pub type mat4 = Mat4<f32>; /// a 4×4 single-precision floating-point matrix
pub type dmat4 = Mat4<f64>; /// a 4×4 double-precision floating-point matrix
pub type mat4 = Mat4<f32>; // a 4×4 single-precision floating-point matrix
pub type dmat4 = Mat4<f64>; // a 4×4 double-precision floating-point matrix
// Static method wrappers for GLSL-style types
pub impl mat4 {
#[inline(always)] static pure fn new(c0r0: f32, c0r1: f32, c0r2: f32, c0r3: f32, c1r0: f32, c1r1: f32, c1r2: f32, c1r3: f32, c2r0: f32, c2r1: f32, c2r2: f32, c2r3: f32, c3r0: f32, c3r1: f32, c3r2: f32, c3r3: f32)
-> mat4 { Mat4::new(c0r0, c0r1, c0r2, c0r3, c1r0, c1r1, c1r2, c1r3, c2r0, c2r1, c2r2, c2r3, c3r0, c3r1, c3r2, c3r3) }
-> mat4 { Matrix4::new(c0r0, c0r1, c0r2, c0r3, c1r0, c1r1, c1r2, c1r3, c2r0, c2r1, c2r2, c2r3, c3r0, c3r1, c3r2, c3r3) }
#[inline(always)] static pure fn from_cols(c0: vec4, c1: vec4, c2: vec4, c3: vec4)
-> mat4 { Mat4::from_cols(move c0, move c1, move c2, move c3) }
#[inline(always)] static pure fn from_value(v: f32) -> mat4 { Mat4::from_value(v) }
-> mat4 { Matrix4::from_cols(move c0, move c1, move c2, move c3) }
#[inline(always)] static pure fn from_value(v: f32) -> mat4 { Matrix::from_value(v) }
#[inline(always)] static pure fn identity() -> mat4 { Matrix::identity() }
#[inline(always)] static pure fn zero() -> mat4 { Matrix::zero() }
@ -547,10 +541,10 @@ pub impl mat4 {
pub impl dmat4 {
#[inline(always)] static pure fn new(c0r0: f64, c0r1: f64, c0r2: f64, c0r3: f64, c1r0: f64, c1r1: f64, c1r2: f64, c1r3: f64, c2r0: f64, c2r1: f64, c2r2: f64, c2r3: f64, c3r0: f64, c3r1: f64, c3r2: f64, c3r3: f64)
-> dmat4 { Mat4::new(c0r0, c0r1, c0r2, c0r3, c1r0, c1r1, c1r2, c1r3, c2r0, c2r1, c2r2, c2r3, c3r0, c3r1, c3r2, c3r3) }
-> dmat4 { Matrix4::new(c0r0, c0r1, c0r2, c0r3, c1r0, c1r1, c1r2, c1r3, c2r0, c2r1, c2r2, c2r3, c3r0, c3r1, c3r2, c3r3) }
#[inline(always)] static pure fn from_cols(c0: dvec4, c1: dvec4, c2: dvec4, c3: dvec4)
-> dmat4 { Mat4::from_cols(move c0, move c1, move c2, move c3) }
#[inline(always)] static pure fn from_value(v: f64) -> dmat4 { Mat4::from_value(v) }
-> dmat4 { Matrix4::from_cols(move c0, move c1, move c2, move c3) }
#[inline(always)] static pure fn from_value(v: f64) -> dmat4 { Matrix::from_value(v) }
#[inline(always)] static pure fn identity() -> dmat4 { Matrix::identity() }
#[inline(always)] static pure fn zero() -> dmat4 { Matrix::zero() }

View file

@ -1,7 +1,7 @@
use numeric::*;
use numeric::number::Number;
use mat::Mat4;
use mat::{Mat4, Matrix4};
/**
* Create a perspective projection matrix
@ -49,8 +49,8 @@ pub pure fn frustum<T:Copy Float>(left: T, right: T, bottom: T, top: T, near: T,
let c3r2 = -(_2 * far * near) / (far - near);
let c3r3 = _0;
Mat4::new(c0r0, c0r1, c0r2, c0r3,
c1r0, c1r1, c1r2, c1r3,
c2r0, c2r1, c2r2, c2r3,
c3r0, c3r1, c3r2, c3r3)
Matrix4::new(c0r0, c0r1, c0r2, c0r3,
c1r0, c1r1, c1r2, c1r3,
c2r0, c2r1, c2r2, c2r3,
c3r0, c3r1, c3r2, c3r3)
}

View file

@ -18,10 +18,14 @@ use numeric::*;
use numeric::number::Number;
use numeric::number::Number::{zero,one};
use mat::{Mat3, Mat4};
use mat::{
Mat3,
Matrix3
};
use vec::{
Vec3,
Vector3,
vec3,
dvec3,
};
@ -55,7 +59,7 @@ pub impl<T:Copy Float> Quat<T> {
*/
#[inline(always)]
static pure fn new(w: T, xi: T, yj: T, zk: T) -> Quat<T> {
Quat::from_sv(w, Vec3::new(xi, yj, zk))
Quat::from_sv(w, Vector3::new(xi, yj, zk))
}
/**
@ -91,6 +95,57 @@ pub impl<T:Copy Float> Quat<T> {
Quat::new(zero(), zero(), zero(), zero())
}
#[inline(always)]
static pure fn from_angle_x(radians: T) -> Quat<T> {
let _2 = Number::from(2);
Quat::new(cos(radians / _2), sin(radians), zero(), zero())
}
#[inline(always)]
static pure fn from_angle_y(radians: T) -> Quat<T> {
let _2 = Number::from(2);
Quat::new(cos(radians / _2), zero(), sin(radians), zero())
}
#[inline(always)]
static pure fn from_angle_z(radians: T) -> Quat<T> {
let _2 = Number::from(2);
Quat::new(cos(radians / _2), zero(), zero(), sin(radians))
}
#[inline(always)]
static pure fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Quat<T> {
// http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Conversion
let _2 = Number::from(2);
let xdiv2 = radians_x / _2;
let ydiv2 = radians_y / _2;
let zdiv2 = radians_z / _2;
Quat::new(cos(zdiv2) * cos(xdiv2) * cos(ydiv2) + sin(zdiv2) * sin(xdiv2) * sin(ydiv2),
sin(zdiv2) * cos(xdiv2) * cos(ydiv2) - cos(zdiv2) * sin(xdiv2) * sin(ydiv2),
cos(zdiv2) * sin(xdiv2) * cos(ydiv2) + sin(zdiv2) * cos(xdiv2) * sin(ydiv2),
cos(zdiv2) * cos(xdiv2) * sin(ydiv2) - sin(zdiv2) * sin(xdiv2) * cos(ydiv2))
}
#[inline(always)]
static pure fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Quat<T> {
let half = radians / Number::from(2);
Quat::from_sv(cos(half), axis.mul_t(sin(half)))
}
#[inline(always)]
static pure fn from_axes(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> Quat<T> {
let m: Mat3<T> = Matrix3::from_axes(x, y, z); m.to_quat()
}
pure fn get_angle_axis(&self) -> (T, Vec3<T>) {
fail(~"Not yet implemented.")
}
#[inline(always)]
static pure fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Quat<T> {
let m: Mat3<T> = Matrix3::look_at(dir, up); m.to_quat()
}
/**
* # Return value
*
@ -303,76 +358,9 @@ pub impl<T:Copy Float> Quat<T> {
}
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_x(radians: T) -> Quat<T> {
let _2 = Number::from(2);
Quat::new(cos(radians / _2), sin(radians), zero(), zero())
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_y(radians: T) -> Quat<T> {
let _2 = Number::from(2);
Quat::new(cos(radians / _2), zero(), sin(radians), zero())
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_z(radians: T) -> Quat<T> {
let _2 = Number::from(2);
Quat::new(cos(radians / _2), zero(), zero(), sin(radians))
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> Quat<T> {
// http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Conversion
let _2 = Number::from(2);
let xdiv2 = radians_x / _2;
let ydiv2 = radians_y / _2;
let zdiv2 = radians_z / _2;
Quat::new(cos(zdiv2) * cos(xdiv2) * cos(ydiv2) + sin(zdiv2) * sin(xdiv2) * sin(ydiv2),
sin(zdiv2) * cos(xdiv2) * cos(ydiv2) - cos(zdiv2) * sin(xdiv2) * sin(ydiv2),
cos(zdiv2) * sin(xdiv2) * cos(ydiv2) + sin(zdiv2) * cos(xdiv2) * sin(ydiv2),
cos(zdiv2) * cos(xdiv2) * sin(ydiv2) - sin(zdiv2) * sin(xdiv2) * cos(ydiv2))
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_angle_axis(radians: T, axis: &Vec3<T>) -> Quat<T> {
let half = radians / Number::from(2);
Quat::from_sv(cos(half), axis.mul_t(sin(half)))
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn from_axes(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> Quat<T> {
Mat3::from_axes(x, y, z).to_quat()
}
pure fn get_angle_axis(&self) -> (T, Vec3<T>) {
fail(~"Not yet implemented.")
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
static pure fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Quat<T> {
Mat3::look_at(dir, up).to_quat()
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn concat(&self, other: &Quat<T>) -> Quat<T> { self.mul_q(other) }
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn rotate_vec(&self, vec: &Vec3<T>) -> Vec3<T> { self.mul_v(vec) }
/**
* Convert the quaternion to a 3 x 3 rotation matrix
*/
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn to_mat3(&self) -> Mat3<T> {
let x2 = self.v.x + self.v.x;
@ -393,14 +381,10 @@ pub impl<T:Copy Float> Quat<T> {
let _1: T = one();
Mat3::new(_1 - yy2 - zz2, xy2 + sz2, xz2 - sy2,
xy2 - sz2, _1 - xx2 - zz2, yz2 + sx2,
xz2 + sy2, yz2 - sx2, _1 - xx2 - yy2)
Matrix3::new(_1 - yy2 - zz2, xy2 + sz2, xz2 - sy2,
xy2 - sz2, _1 - xx2 - zz2, yz2 + sx2,
xz2 + sy2, yz2 - sx2, _1 - xx2 - yy2)
}
// TODO: Move to Rotation implementation. See: https://github.com/mozilla/rust/issues/4306
#[inline(always)]
pure fn to_quat(&self) -> Quat<T> { *self }
}
pub impl<T:Copy> Quat<T>: Index<uint, T> {

View file

@ -1,25 +0,0 @@
use mat::Mat3;
use quat::Quat;
use vec::Vec3;
/**
* A trait that includes some common rotation methods, constructors and conversions
*/
pub trait Rotation<T> {
static pure fn from<R: Rotation<T>>(rot: R) -> self;
static pure fn from_angle_x(radians: T) -> self;
static pure fn from_angle_y(radians: T) -> self;
static pure fn from_angle_z(radians: T) -> self;
static pure fn from_angle_xyz(radians_x: T, radians_y: T, radians_z: T) -> self;
static pure fn from_angle_axis(radians: T, axis: &Vec3<T>) -> self;
static pure fn from_axes(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> self;
static pure fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> self;
pure fn concat(&self, other: &self) -> self;
pure fn rotate_vec(&self, vec: &Vec3<T>) -> Vec3<T>;
pure fn to_mat3(&self) -> Mat3<T>;
pure fn to_quat(&self) -> Quat<T>;
// pure fn to_euler(&self) -> Euler<T>;
}

View file

@ -5,67 +5,67 @@ use vec::*;
#[test]
fn test_mat2() {
let a = Mat2 { x: Vec2 { x: 1f, y: 3f },
y: Vec2 { x: 2f, y: 4f } };
let b = Mat2 { x: Vec2 { x: 2f, y: 4f },
y: Vec2 { x: 3f, y: 5f } };
let a = Mat2 { x: Vec2 { x: 1.0, y: 3.0 },
y: Vec2 { x: 2.0, y: 4.0 } };
let b = Mat2 { x: Vec2 { x: 2.0, y: 4.0 },
y: Vec2 { x: 3.0, y: 5.0 } };
let v1 = Vec2::new(1f, 2f);
let f1 = 0.5f;
let v1 = vec2::new(1.0, 2.0);
let f1 = 0.5;
assert a == Mat2::new(1f, 3f,
2f, 4f);
assert a == mat2::new(1.0, 3.0,
2.0, 4.0);
assert a == Mat2::from_cols(Vec2::new(1f, 3f),
Vec2::new(2f, 4f));
assert a == mat2::from_cols(vec2::new(1.0, 3.0),
vec2::new(2.0, 4.0));
assert Mat2::from_value(4f64) == Mat2::new(4f64, 0f64,
0f64, 4f64);
assert mat2::from_value(4.0) == mat2::new(4.0, 0.0,
0.0, 4.0);
assert a[0] == Vec2::new(1f, 3f);
assert a[1] == Vec2::new(2f, 4f);
assert a[0] == vec2::new(1.0, 3.0);
assert a[1] == vec2::new(2.0, 4.0);
assert a.row(0) == Vec2::new(1f, 2f);
assert a.row(1) == Vec2::new(3f, 4f);
assert a.row(0) == vec2::new(1.0, 2.0);
assert a.row(1) == vec2::new(3.0, 4.0);
assert a.col(0) == Vec2::new(1f, 3f);
assert a.col(1) == Vec2::new(2f, 4f);
assert a.col(0) == vec2::new(1.0, 3.0);
assert a.col(1) == vec2::new(2.0, 4.0);
assert Mat2::identity() == Mat2::new(1f, 0f,
0f, 1f);
assert mat2::identity() == mat2::new(1.0, 0.0,
0.0, 1.0);
assert Mat2::zero() == Mat2::new(0f, 0f,
0f, 0f);
assert mat2::zero() == mat2::new(0.0, 0.0,
0.0, 0.0);
assert a.determinant() == -2f;
assert a.trace() == 5f;
assert a.determinant() == -2.0;
assert a.trace() == 5.0;
assert a.neg() == Mat2::new(-1f, -3f,
-2f, -4f);
assert a.neg() == mat2::new(-1.0, -3.0,
-2.0, -4.0);
assert -a == a.neg();
assert a.mul_t(f1) == Mat2::new(0.5f, 1.5f,
1.0f, 2.0f);
assert a.mul_v(&v1) == Vec2::new(5f, 11f);
assert a.mul_t(f1) == mat2::new(0.5, 1.5,
1.0, 2.0);
assert a.mul_v(&v1) == vec2::new(5.0, 11.0);
assert a.add_m(&b) == Mat2::new(3f, 7f,
5f, 9f);
assert a.sub_m(&b) == Mat2::new(-1f, -1f,
-1f, -1f);
assert a.mul_m(&b) == Mat2::new(10.0, 22.0,
assert a.add_m(&b) == mat2::new(3.0, 7.0,
5.0, 9.0);
assert a.sub_m(&b) == mat2::new(-1.0, -1.0,
-1.0, -1.0);
assert a.mul_m(&b) == mat2::new(10.0, 22.0,
13.0, 29.0);
assert a.dot(&b) == 40f;
assert a.dot(&b) == 40.0;
assert a.transpose() == Mat2::new(1f, 2f,
3f, 4f);
assert a.transpose() == mat2::new(1.0, 2.0,
3.0, 4.0);
assert option::unwrap(a.inverse()) == Mat2::new(-2f, 1.5f,
1f, -0.5f);
assert option::unwrap(a.inverse()) == mat2::new(-2.0, 1.5,
1.0, -0.5);
assert Mat2::new(0f, 2f,
0f, 5f).inverse().is_none();
assert mat2::new(0.0, 2.0,
0.0, 5.0).inverse().is_none();
let ident: Mat2<float> = Matrix::identity();
let ident = mat2::identity();
assert ident.is_identity();
assert ident.is_symmetric();
@ -79,35 +79,35 @@ fn test_mat2() {
assert a.is_rotated();
assert a.is_invertible();
let c = Mat2::new(2f, 1f,
1f, 2f);
let c = mat2::new(2.0, 1.0,
1.0, 2.0);
assert !c.is_identity();
assert c.is_symmetric();
assert !c.is_diagonal();
assert c.is_rotated();
assert c.is_invertible();
assert Mat2::from_value(6f).is_diagonal();
assert mat2::from_value(6.0).is_diagonal();
assert a.to_mat3() == Mat3::new(1f, 3f, 0f,
2f, 4f, 0f,
0f, 0f, 1f);
assert a.to_mat3() == mat3::new(1.0, 3.0, 0.0,
2.0, 4.0, 0.0,
0.0, 0.0, 1.0);
assert a.to_mat4() == Mat4::new(1f, 3f, 0f, 0f,
2f, 4f, 0f, 0f,
0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f);
assert a.to_mat4() == mat4::new(1.0, 3.0, 0.0, 0.0,
2.0, 4.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
}
fn test_mat2_mut() {
let a = Mat2 { x: Vec2 { x: 1f, y: 3f },
y: Vec2 { x: 2f, y: 4f } };
let b = Mat2 { x: Vec2 { x: 2f, y: 4f },
y: Vec2 { x: 3f, y: 5f } };
let a = Mat2 { x: Vec2 { x: 1.0, y: 3.0 },
y: Vec2 { x: 2.0, y: 4.0 } };
let b = Mat2 { x: Vec2 { x: 2.0, y: 4.0 },
y: Vec2 { x: 3.0, y: 5.0 } };
let f1 = 0.5f;
let f1 = 0.5;
let mut mut_a = a;
let mut mut_a: mat2 = a;
mut_a.swap_cols(0, 1);
assert mut_a.col(0) == a.col(1);
@ -128,7 +128,7 @@ fn test_mat2_mut() {
mut_a = a;
mut_a.to_zero();
assert mut_a == Mat2::zero();
assert mut_a == mat2::zero();
mut_a = a;
mut_a.mul_self_t(f1);
@ -154,88 +154,88 @@ fn test_mat2_mut() {
#[test]
fn test_mat2_fuzzy_eq() {
assert !Mat2::new(0.000001, 0.000001,
0.000001, 0.000001).fuzzy_eq(&Mat2::zero());
assert Mat2::new(0.0000001, 0.0000001,
0.0000001, 0.0000001).fuzzy_eq(&Mat2::zero());
assert !mat2::new(0.000001, 0.000001,
0.000001, 0.000001).fuzzy_eq(&mat2::zero());
assert mat2::new(0.0000001, 0.0000001,
0.0000001, 0.0000001).fuzzy_eq(&mat2::zero());
}
#[test]
fn test_mat3() {
let a = Mat3 { x: Vec3 { x: 1f, y: 4f, z: 7f },
y: Vec3 { x: 2f, y: 5f, z: 8f },
z: Vec3 { x: 3f, y: 6f, z: 9f } };
let b = Mat3 { x: Vec3 { x: 2f, y: 5f, z: 8f },
y: Vec3 { x: 3f, y: 6f, z: 9f },
z: Vec3 { x: 4f, y: 7f, z: 10f } };
let a = Mat3 { x: Vec3 { x: 1.0, y: 4.0, z: 7.0 },
y: Vec3 { x: 2.0, y: 5.0, z: 8.0 },
z: Vec3 { x: 3.0, y: 6.0, z: 9.0 } };
let b = Mat3 { x: Vec3 { x: 2.0, y: 5.0, z: 8.0 },
y: Vec3 { x: 3.0, y: 6.0, z: 9.0 },
z: Vec3 { x: 4.0, y: 7.0, z: 10.0 } };
let v1 = Vec3::new(1f, 2f, 3f);
let f1 = 0.5f;
let v1 = vec3::new(1.0, 2.0, 3.0);
let f1 = 0.5;
assert a == Mat3::new(1f, 4f, 7f,
2f, 5f, 8f,
3f, 6f, 9f);
assert a == mat3::new(1.0, 4.0, 7.0,
2.0, 5.0, 8.0,
3.0, 6.0, 9.0);
assert a == Mat3::from_cols(Vec3::new(1f, 4f, 7f),
Vec3::new(2f, 5f, 8f),
Vec3::new(3f, 6f, 9f));
assert a == mat3::from_cols(vec3::new(1.0, 4.0, 7.0),
vec3::new(2.0, 5.0, 8.0),
vec3::new(3.0, 6.0, 9.0));
assert a[0] == Vec3::new(1f, 4f, 7f);
assert a[1] == Vec3::new(2f, 5f, 8f);
assert a[2] == Vec3::new(3f, 6f, 9f);
assert a[0] == vec3::new(1.0, 4.0, 7.0);
assert a[1] == vec3::new(2.0, 5.0, 8.0);
assert a[2] == vec3::new(3.0, 6.0, 9.0);
assert a.row(0) == Vec3::new(1f, 2f, 3f);
assert a.row(1) == Vec3::new(4f, 5f, 6f);
assert a.row(2) == Vec3::new(7f, 8f, 9f);
assert a.row(0) == vec3::new(1.0, 2.0, 3.0);
assert a.row(1) == vec3::new(4.0, 5.0, 6.0);
assert a.row(2) == vec3::new(7.0, 8.0, 9.0);
assert a.col(0) == Vec3::new(1f, 4f, 7f);
assert a.col(1) == Vec3::new(2f, 5f, 8f);
assert a.col(2) == Vec3::new(3f, 6f, 9f);
assert a.col(0) == vec3::new(1.0, 4.0, 7.0);
assert a.col(1) == vec3::new(2.0, 5.0, 8.0);
assert a.col(2) == vec3::new(3.0, 6.0, 9.0);
assert Mat3::identity() == Mat3::new(1f, 0f, 0f,
0f, 1f, 0f,
0f, 0f, 1f);
assert mat3::identity() == mat3::new(1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0);
assert Mat3::zero() == Mat3::new(0f, 0f, 0f,
0f, 0f, 0f,
0f, 0f, 0f);
assert mat3::zero() == mat3::new(0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0);
assert a.determinant() == 0f;
assert a.trace() == 15f;
assert a.determinant() == 0.0;
assert a.trace() == 15.0;
assert a.neg() == Mat3::new(-1f, -4f, -7f,
-2f, -5f, -8f,
-3f, -6f, -9f);
assert a.neg() == mat3::new(-1.0, -4.0, -7.0,
-2.0, -5.0, -8.0,
-3.0, -6.0, -9.0);
assert -a == a.neg();
assert a.mul_t(f1) == Mat3::new(0.5f, 2.0f, 3.5f,
1.0f, 2.5f, 4.0f,
1.5f, 3.0f, 4.5f);
assert a.mul_v(&v1) == Vec3::new(14f, 32f, 50f);
assert a.mul_t(f1) == mat3::new(0.5, 2.0, 3.5,
1.0, 2.5, 4.0,
1.5, 3.0, 4.5);
assert a.mul_v(&v1) == vec3::new(14.0, 32.0, 50.0);
assert a.add_m(&b) == Mat3::new(3f, 9f, 15f,
5f, 11f, 17f,
7f, 13f, 19f);
assert a.sub_m(&b) == Mat3::new(-1f, -1f, -1f,
-1f, -1f, -1f,
-1f, -1f, -1f);
assert a.mul_m(&b) == Mat3::new(36f, 81f, 126f,
42f, 96f, 150f,
48f, 111f, 174f);
assert a.dot(&b) == 330f;
assert a.add_m(&b) == mat3::new(3.0, 9.0, 15.0,
5.0, 11.0, 17.0,
7.0, 13.0, 19.0);
assert a.sub_m(&b) == mat3::new(-1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, -1.0, -1.0);
assert a.mul_m(&b) == mat3::new(36.0, 81.0, 126.0,
42.0, 96.0, 150.0,
48.0, 111.0, 174.0);
assert a.dot(&b) == 330.0;
assert a.transpose() == Mat3::new(1f, 2f, 3f,
4f, 5f, 6f,
7f, 8f, 9f);
assert a.transpose() == mat3::new(1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0);
assert a.inverse().is_none();
assert option::unwrap(Mat3::new(2f, 4f, 6f,
0f, 2f, 4f,
0f, 0f, 1f).inverse())
== Mat3::new(0.5f, -1f, 1f,
0f, 0.5f, -2f,
0f, 0f, 1f);
assert option::unwrap(mat3::new(2.0, 4.0, 6.0,
0.0, 2.0, 4.0,
0.0, 0.0, 1.0).inverse())
== mat3::new(0.5, -1.0, 1.0,
0.0, 0.5, -2.0,
0.0, 0.0, 1.0);
let ident: Mat3<float> = Matrix::identity();
@ -253,40 +253,40 @@ fn test_mat3() {
assert a.is_rotated();
assert !a.is_invertible();
let c = Mat3::new(3f, 2f, 1f,
2f, 3f, 2f,
1f, 2f, 3f);
let c = mat3::new(3.0, 2.0, 1.0,
2.0, 3.0, 2.0,
1.0, 2.0, 3.0);
assert !c.is_identity();
assert c.is_symmetric();
assert !c.is_diagonal();
assert c.is_rotated();
assert c.is_invertible();
assert Mat3::from_value(6f).is_diagonal();
assert mat3::from_value(6.0).is_diagonal();
assert a.to_mat4() == Mat4::new(1f, 4f, 7f, 0f,
2f, 5f, 8f, 0f,
3f, 6f, 9f, 0f,
0f, 0f, 0f, 1f);
assert a.to_mat4() == mat4::new(1.0, 4.0, 7.0, 0.0,
2.0, 5.0, 8.0, 0.0,
3.0, 6.0, 9.0, 0.0,
0.0, 0.0, 0.0, 1.0);
// to_Quaternion
}
fn test_mat3_mut() {
let a = Mat3 { x: Vec3 { x: 1f, y: 4f, z: 7f },
y: Vec3 { x: 2f, y: 5f, z: 8f },
z: Vec3 { x: 3f, y: 6f, z: 9f } };
let b = Mat3 { x: Vec3 { x: 2f, y: 5f, z: 8f },
y: Vec3 { x: 3f, y: 6f, z: 9f },
z: Vec3 { x: 4f, y: 7f, z: 10f } };
let c = Mat3 { x: Vec3 { x: 2f, y: 4f, z: 6f },
y: Vec3 { x: 0f, y: 2f, z: 4f },
z: Vec3 { x: 0f, y: 0f, z: 1f } };
let a = Mat3 { x: Vec3 { x: 1.0, y: 4.0, z: 7.0 },
y: Vec3 { x: 2.0, y: 5.0, z: 8.0 },
z: Vec3 { x: 3.0, y: 6.0, z: 9.0 } };
let b = Mat3 { x: Vec3 { x: 2.0, y: 5.0, z: 8.0 },
y: Vec3 { x: 3.0, y: 6.0, z: 9.0 },
z: Vec3 { x: 4.0, y: 7.0, z: 10.0 } };
let c = Mat3 { x: Vec3 { x: 2.0, y: 4.0, z: 6.0 },
y: Vec3 { x: 0.0, y: 2.0, z: 4.0 },
z: Vec3 { x: 0.0, y: 0.0, z: 1.0 } };
let f1 = 0.5f;
let f1 = 0.5;
let mut mut_a = a;
let mut mut_c = c;
let mut mut_a: mat3 = a;
let mut mut_c: mat3 = c;
mut_a.swap_cols(0, 2);
assert mut_a.col(0) == a.col(2);
@ -317,7 +317,7 @@ fn test_mat3_mut() {
mut_a = a;
mut_a.to_zero();
assert mut_a == Mat3::zero();
assert mut_a == mat3::zero();
mut_a = a;
mut_a.mul_self_t(f1);
@ -343,115 +343,115 @@ fn test_mat3_mut() {
#[test]
fn test_mat3_fuzzy_eq() {
assert !Mat3::new(0.000001, 0.000001, 0.000001,
assert !mat3::new(0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001).fuzzy_eq(&Mat3::zero());
assert Mat3::new(0.0000001, 0.0000001, 0.0000001,
0.000001, 0.000001, 0.000001).fuzzy_eq(&mat3::zero());
assert mat3::new(0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&Mat3::zero());
0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&mat3::zero());
}
#[test]
fn test_mat4() {
let a = Mat4 { x: Vec4 { x: 1f, y: 5f, z: 9f, w: 13f },
y: Vec4 { x: 2f, y: 6f, z: 10f, w: 14f },
z: Vec4 { x: 3f, y: 7f, z: 11f, w: 15f },
w: Vec4 { x: 4f, y: 8f, z: 12f, w: 16f } };
let b = Mat4 { x: Vec4 { x: 2f, y: 6f, z: 10f, w: 14f },
y: Vec4 { x: 3f, y: 7f, z: 11f, w: 15f },
z: Vec4 { x: 4f, y: 8f, z: 12f, w: 16f },
w: Vec4 { x: 5f, y: 9f, z: 13f, w: 17f } };
let c = Mat4 { x: Vec4 { x: 3f, y: 2f, z: 1f, w: 1f },
y: Vec4 { x: 2f, y: 3f, z: 2f, w: 2f },
z: Vec4 { x: 1f, y: 2f, z: 3f, w: 3f },
w: Vec4 { x: 0f, y: 1f, z: 1f, w: 0f } };
let a: mat4 = Mat4 { x: Vec4 { x: 1.0, y: 5.0, z: 9.0, w: 13.0 },
y: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 },
z: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 },
w: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 } };
let b: mat4 = Mat4 { x: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 },
y: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 },
z: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 },
w: Vec4 { x: 5.0, y: 9.0, z: 13.0, w: 17.0 } };
let c: mat4 = Mat4 { x: Vec4 { x: 3.0, y: 2.0, z: 1.0, w: 1.0 },
y: Vec4 { x: 2.0, y: 3.0, z: 2.0, w: 2.0 },
z: Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 3.0 },
w: Vec4 { x: 0.0, y: 1.0, z: 1.0, w: 0.0 } };
let v1 = Vec4::new(1f, 2f, 3f, 4f);
let f1 = 0.5f;
let v1 = vec4::new(1.0, 2.0, 3.0, 4.0);
let f1 = 0.5;
assert a == Mat4::new(1f, 5f, 9f, 13f,
2f, 6f, 10f, 14f,
3f, 7f, 11f, 15f,
4f, 8f, 12f, 16f);
assert a == mat4::new(1.0, 5.0, 9.0, 13.0,
2.0, 6.0, 10.0, 14.0,
3.0, 7.0, 11.0, 15.0,
4.0, 8.0, 12.0, 16.0);
assert a == Mat4::from_cols(Vec4::new(1f, 5f, 9f, 13f),
Vec4::new(2f, 6f, 10f, 14f),
Vec4::new(3f, 7f, 11f, 15f),
Vec4::new(4f, 8f, 12f, 16f));
assert a == mat4::from_cols(vec4::new(1.0, 5.0, 9.0, 13.0),
vec4::new(2.0, 6.0, 10.0, 14.0),
vec4::new(3.0, 7.0, 11.0, 15.0),
vec4::new(4.0, 8.0, 12.0, 16.0));
assert Mat4::from_value(4f64) == Mat4::new(4f64, 0f64, 0f64, 0f64,
0f64, 4f64, 0f64, 0f64,
0f64, 0f64, 4f64, 0f64,
0f64, 0f64, 0f64, 4f64);
assert mat4::from_value(4.0) == mat4::new(4.0, 0.0, 0.0, 0.0,
0.0, 4.0, 0.0, 0.0,
0.0, 0.0, 4.0, 0.0,
0.0, 0.0, 0.0, 4.0);
assert a[0] == Vec4::new(1f, 5f, 9f, 13f);
assert a[1] == Vec4::new(2f, 6f, 10f, 14f);
assert a[2] == Vec4::new(3f, 7f, 11f, 15f);
assert a[3] == Vec4::new(4f, 8f, 12f, 16f);
assert a[0] == vec4::new(1.0, 5.0, 9.0, 13.0);
assert a[1] == vec4::new(2.0, 6.0, 10.0, 14.0);
assert a[2] == vec4::new(3.0, 7.0, 11.0, 15.0);
assert a[3] == vec4::new(4.0, 8.0, 12.0, 16.0);
assert a.row(0) == Vec4::new( 1f, 2f, 3f, 4f);
assert a.row(1) == Vec4::new( 5f, 6f, 7f, 8f);
assert a.row(2) == Vec4::new( 9f, 10f, 11f, 12f);
assert a.row(3) == Vec4::new(13f, 14f, 15f, 16f);
assert a.row(0) == vec4::new( 1.0, 2.0, 3.0, 4.0);
assert a.row(1) == vec4::new( 5.0, 6.0, 7.0, 8.0);
assert a.row(2) == vec4::new( 9.0, 10.0, 11.0, 12.0);
assert a.row(3) == vec4::new(13.0, 14.0, 15.0, 16.0);
assert a.col(0) == Vec4::new(1f, 5f, 9f, 13f);
assert a.col(1) == Vec4::new(2f, 6f, 10f, 14f);
assert a.col(2) == Vec4::new(3f, 7f, 11f, 15f);
assert a.col(3) == Vec4::new(4f, 8f, 12f, 16f);
assert a.col(0) == vec4::new(1.0, 5.0, 9.0, 13.0);
assert a.col(1) == vec4::new(2.0, 6.0, 10.0, 14.0);
assert a.col(2) == vec4::new(3.0, 7.0, 11.0, 15.0);
assert a.col(3) == vec4::new(4.0, 8.0, 12.0, 16.0);
assert Mat4::identity() == Mat4::new(1f, 0f, 0f, 0f,
0f, 1f, 0f, 0f,
0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f);
assert mat4::identity() == mat4::new(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
assert Mat4::zero() == Mat4::new(0f, 0f, 0f, 0f,
0f, 0f, 0f, 0f,
0f, 0f, 0f, 0f,
0f, 0f, 0f, 0f);
assert mat4::zero() == mat4::new(0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0);
assert a.determinant() == 0f;
assert a.trace() == 34f;
assert a.determinant() == 0.0;
assert a.trace() == 34.0;
assert a.neg() == Mat4::new(-1f, -5f, -9f, -13f,
-2f, -6f, -10f, -14f,
-3f, -7f, -11f, -15f,
-4f, -8f, -12f, -16f);
assert a.neg() == mat4::new(-1.0, -5.0, -9.0, -13.0,
-2.0, -6.0, -10.0, -14.0,
-3.0, -7.0, -11.0, -15.0,
-4.0, -8.0, -12.0, -16.0);
assert -a == a.neg();
assert a.mul_t(f1) == Mat4::new(0.5f, 2.5f, 4.5f, 6.5f,
1.0f, 3.0f, 5.0f, 7.0f,
1.5f, 3.5f, 5.5f, 7.5f,
2.0f, 4.0f, 6.0f, 8.0f);
assert a.mul_v(&v1) == Vec4::new(30.0, 70.0, 110.0, 150.0);
assert a.mul_t(f1) == mat4::new(0.5, 2.5, 4.5, 6.5,
1.0, 3.0, 5.0, 7.0,
1.5, 3.5, 5.5, 7.5,
2.0, 4.0, 6.0, 8.0);
assert a.mul_v(&v1) == vec4::new(30.0, 70.0, 110.0, 150.0);
assert a.add_m(&b) == Mat4::new(3f, 11f, 19f, 27f,
5f, 13f, 21f, 29f,
7f, 15f, 23f, 31f,
9f, 17f, 25f, 33f);
assert a.sub_m(&b) == Mat4::new(-1f, -1f, -1f, -1f,
-1f, -1f, -1f, -1f,
-1f, -1f, -1f, -1f,
-1f, -1f, -1f, -1f);
assert a.mul_m(&b) == Mat4::new(100f, 228f, 356f, 484f,
110f, 254f, 398f, 542f,
120f, 280f, 440f, 600f,
130f, 306f, 482f, 658f);
assert a.dot(&b) == 1632f;
assert a.add_m(&b) == mat4::new(3.0, 11.0, 19.0, 27.0,
5.0, 13.0, 21.0, 29.0,
7.0, 15.0, 23.0, 31.0,
9.0, 17.0, 25.0, 33.0);
assert a.sub_m(&b) == mat4::new(-1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0);
assert a.mul_m(&b) == mat4::new(100.0, 228.0, 356.0, 484.0,
110.0, 254.0, 398.0, 542.0,
120.0, 280.0, 440.0, 600.0,
130.0, 306.0, 482.0, 658.0);
assert a.dot(&b) == 1632.0;
assert a.transpose() == Mat4::new( 1f, 2f, 3f, 4f,
5f, 6f, 7f, 8f,
9f, 10f, 11f, 12f,
13f, 14f, 15f, 16f);
assert a.transpose() == mat4::new( 1.0, 2.0, 3.0, 4.0,
5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0,
13.0, 14.0, 15.0, 16.0);
assert c.inverse().unwrap()
.fuzzy_eq(&mat4::new( 5.0, -4.0, 1.0, 0.0,
-4.0, 8.0, -4.0, 0.0,
4.0, -8.0, 4.0, 8.0,
-3.0, 4.0, 1.0, -8.0).mul_t(0.125));
let ident = mat4::identity();
assert option::unwrap(c.inverse())
.fuzzy_eq(&Mat4::new( 5f, -4f, 1f, 0f,
-4f, 8f, -4f, 0f,
4f, -8f, 4f, 8f,
-3f, 4f, 1f, -8f).mul_t(0.125f));
let ident: Mat4<float> = Matrix::identity();
assert option::unwrap(ident.inverse()) == ident;
assert ident.inverse().unwrap() == ident;
assert ident.is_identity();
assert ident.is_symmetric();
@ -465,37 +465,37 @@ fn test_mat4() {
assert a.is_rotated();
assert !a.is_invertible();
let c = Mat4::new(4f, 3f, 2f, 1f,
3f, 4f, 3f, 2f,
2f, 3f, 4f, 3f,
1f, 2f, 3f, 4f);
let c = mat4::new(4.0, 3.0, 2.0, 1.0,
3.0, 4.0, 3.0, 2.0,
2.0, 3.0, 4.0, 3.0,
1.0, 2.0, 3.0, 4.0);
assert !c.is_identity();
assert c.is_symmetric();
assert !c.is_diagonal();
assert c.is_rotated();
assert c.is_invertible();
assert Mat4::from_value(6f).is_diagonal();
assert mat4::from_value(6.0).is_diagonal();
}
fn test_mat4_mut() {
let a = Mat4 { x: Vec4 { x: 1f, y: 5f, z: 9f, w: 13f },
y: Vec4 { x: 2f, y: 6f, z: 10f, w: 14f },
z: Vec4 { x: 3f, y: 7f, z: 11f, w: 15f },
w: Vec4 { x: 4f, y: 8f, z: 12f, w: 16f } };
let b = Mat4 { x: Vec4 { x: 2f, y: 6f, z: 10f, w: 14f },
y: Vec4 { x: 3f, y: 7f, z: 11f, w: 15f },
z: Vec4 { x: 4f, y: 8f, z: 12f, w: 16f },
w: Vec4 { x: 5f, y: 9f, z: 13f, w: 17f } };
let c = Mat4 { x: Vec4 { x: 3f, y: 2f, z: 1f, w: 1f },
y: Vec4 { x: 2f, y: 3f, z: 2f, w: 2f },
z: Vec4 { x: 1f, y: 2f, z: 3f, w: 3f },
w: Vec4 { x: 0f, y: 1f, z: 1f, w: 0f } };
let a = Mat4 { x: Vec4 { x: 1.0, y: 5.0, z: 9.0, w: 13.0 },
y: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 },
z: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 },
w: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 } };
let b = Mat4 { x: Vec4 { x: 2.0, y: 6.0, z: 10.0, w: 14.0 },
y: Vec4 { x: 3.0, y: 7.0, z: 11.0, w: 15.0 },
z: Vec4 { x: 4.0, y: 8.0, z: 12.0, w: 16.0 },
w: Vec4 { x: 5.0, y: 9.0, z: 13.0, w: 17.0 } };
let c = Mat4 { x: Vec4 { x: 3.0, y: 2.0, z: 1.0, w: 1.0 },
y: Vec4 { x: 2.0, y: 3.0, z: 2.0, w: 2.0 },
z: Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 3.0 },
w: Vec4 { x: 0.0, y: 1.0, z: 1.0, w: 0.0 } };
let f1 = 0.5f;
let f1 = 0.5;
let mut mut_a = a;
let mut mut_c = c;
let mut mut_a: mat4 = a;
let mut mut_c: mat4 = c;
mut_a.swap_cols(0, 3);
assert mut_a.col(0) == a.col(3);
@ -526,7 +526,7 @@ fn test_mat4_mut() {
mut_a = a;
mut_a.to_zero();
assert mut_a == Mat4::zero();
assert mut_a == mat4::zero();
mut_a = a;
mut_a.mul_self_t(f1);
@ -552,12 +552,12 @@ fn test_mat4_mut() {
#[test]
fn test_mat4_fuzzy_eq() {
assert !Mat4::new(0.000001, 0.000001, 0.000001, 0.000001,
assert !mat4::new(0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001,
0.000001, 0.000001, 0.000001, 0.000001).fuzzy_eq(&Mat4::zero());
assert Mat4::new(0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.000001, 0.000001, 0.000001, 0.000001).fuzzy_eq(&mat4::zero());
assert mat4::new(0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001,
0.0000001, 0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&Mat4::zero());
0.0000001, 0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&mat4::zero());
}

View file

@ -8,42 +8,41 @@ use vec::*;
#[test]
fn test_quat() {
let a = Quat { s: 1f, v: Vec3 { x: 2f, y: 3f, z: 4f } };
let a = Quat { s: 1.0, v: Vec3 { x: 2.0, y: 3.0, z: 4.0 } };
assert a == Quat::from_sv(1f, Vec3::new(2f, 3f, 4f));
assert a == Quat::new(1f, 2f, 3f, 4f);
assert a == quat::from_sv(1.0, vec3::new(2.0, 3.0, 4.0));
assert a == quat::new(1.0, 2.0, 3.0, 4.0);
assert Quat::zero() == Quat::new(0f, 0f, 0f, 0f);
assert Quat::identity() == Quat::new(1f, 0f, 0f, 0f);
assert quat::zero() == quat::new(0.0, 0.0, 0.0, 0.0);
assert quat::identity() == quat::new(1.0, 0.0, 0.0, 0.0);
assert a.s == 1f;
assert a.v.x == 2f;
assert a.v.y == 3f;
assert a.v.z == 4f;
assert a[0] == 1f;
assert a[1] == 2f;
assert a[2] == 3f;
assert a[3] == 4f;
assert a.s == 1.0;
assert a.v.x == 2.0;
assert a.v.y == 3.0;
assert a.v.z == 4.0;
assert a[0] == 1.0;
assert a[1] == 2.0;
assert a[2] == 3.0;
assert a[3] == 4.0;
// TODO
}
#[test]
fn test_quat_2() {
let v = Vec3::new(1.0, 0.0, 0.0);
let v = vec3::new(1f32, 0f32, 0f32);
// let q: Quat<float> = rot::Rotation::from_angle_axis(Degrees(-45.0), &Vec3::new(0.0, 0.0, -1.0));
let q = Quat::from_angle_axis(radians(-45.0), &Vec3::new(0.0, 0.0, -1.0));
let q = quat::from_angle_axis(radians(-45f32), &vec3::new(0f32, 0f32, -1f32));
// http://www.wolframalpha.com/input/?i={1,0}+rotate+-45+degrees
assert q.mul_v(&v).fuzzy_eq(&Vec3::new(1.0/sqrt(2.0), 1.0/sqrt(2.0), 0.0));
assert q.mul_v(&v).fuzzy_eq(&vec3::new(1f32/sqrt(2f32), 1f32/sqrt(2f32), 0f32));
assert q.mul_v(&v).length() == v.length();
assert q.to_mat3().fuzzy_eq(&Mat3::new( 1.0/sqrt(2.0), 1.0/sqrt(2.0), 0.0,
-1.0/sqrt(2.0), 1.0/sqrt(2.0), 0.0,
0.0, 0.0, 1.0));
assert q.to_mat3().fuzzy_eq(&mat3::new( 1f32/sqrt(2f32), 1f32/sqrt(2f32), 0f32,
-1f32/sqrt(2f32), 1f32/sqrt(2f32), 0f32,
0f32, 0f32, 1f32));
}
#[test]
fn test_quat_fuzzy_eq() {
assert !Quat::new(0.000001, 0.000001, 0.000001, 0.000001).fuzzy_eq(&Quat::new(0.0, 0.0, 0.0, 0.0));
assert Quat::new(0.0000001, 0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&Quat::new(0.0, 0.0, 0.0, 0.0));
assert !quat::new(0.000001, 0.000001, 0.000001, 0.000001).fuzzy_eq(&quat::new(0.0, 0.0, 0.0, 0.0));
assert quat::new(0.0000001, 0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&quat::new(0.0, 0.0, 0.0, 0.0));
}

View file

@ -8,26 +8,26 @@ use vec::*;
#[test]
fn test_vec2() {
// assert Vec2::dim == 2;
// assert vec2::dim == 2;
let a = Vec2 { x: 1f, y: 2f };
let b = Vec2 { x: 3f, y: 4f };
let f1 = 1.5f;
let f2 = 0.5f;
let a = Vec2 { x: 1.0, y: 2.0 };
let b = Vec2 { x: 3.0, y: 4.0 };
let f1 = 1.5;
let f2 = 0.5;
let mut mut_a = a;
assert Vec2::new(1f, 2f) == a;
// assert Vec2::from_value(1f32) == Vec2::new(1f32, 1f32);
assert vec2::new(1.0, 2.0) == a;
assert vec2::from_value(1.0) == vec2::new(1.0, 1.0);
// assert Vec2::zero() == Vec2::new(0f, 0f);
// assert Vec2::unit_x() == Vec2::new(1f, 0f);
// assert Vec2::unit_y() == Vec2::new(0f, 1f);
// assert Vec2::identity() == Vec2::new(1f, 1f);
assert vec2::zero() == vec2::new(0.0, 0.0);
assert vec2::unit_x() == vec2::new(1.0, 0.0);
assert vec2::unit_y() == vec2::new(0.0, 1.0);
assert vec2::identity() == vec2::new(1.0, 1.0);
*mut_a.index_mut(0) = 42f;
*mut_a.index_mut(1) = 43f;
assert mut_a == Vec2::new(42f, 43f);
*mut_a.index_mut(0) = 42.0;
*mut_a.index_mut(1) = 43.0;
assert mut_a == vec2::new(42.0, 43.0);
mut_a = a;
mut_a.swap(0, 1);
@ -35,24 +35,24 @@ fn test_vec2() {
assert mut_a[1] == a[0];
mut_a = a;
assert a.x == 1f;
assert a.y == 2f;
assert a[0] == 1f;
assert a[1] == 2f;
assert a.x == 1.0;
assert a.y == 2.0;
assert a[0] == 1.0;
assert a[1] == 2.0;
assert -a == Vec2::new(-1f, -2f);
assert a.neg() == Vec2::new(-1f, -2f);
assert -a == vec2::new(-1.0, -2.0);
assert a.neg() == vec2::new(-1.0, -2.0);
assert Vec2::new(0f, 0f).is_zero();
assert !Vec2::new(1f, 1f).is_zero();
assert vec2::new(0.0, 0.0).is_zero();
assert !vec2::new(1.0, 1.0).is_zero();
assert a.mul_t(f1) == Vec2::new( 1.5f, 3.0f);
assert a.div_t(f2) == Vec2::new( 2.0f, 4.0f);
assert a.mul_t(f1) == vec2::new( 1.5, 3.0);
assert a.div_t(f2) == vec2::new( 2.0, 4.0);
assert a.add_v(&b) == Vec2::new( 4f, 6f);
assert a.sub_v(&b) == Vec2::new( -2f, -2f);
assert a.mul_v(&b) == Vec2::new( 3f, 8f);
assert a.div_v(&b) == Vec2::new(1f/3f, 2f/4f);
assert a.add_v(&b) == vec2::new( 4.0, 6.0);
assert a.sub_v(&b) == vec2::new( -2.0, -2.0);
assert a.mul_v(&b) == vec2::new( 3.0, 8.0);
assert a.div_v(&b) == vec2::new(1.0/3.0, 2.0/4.0);
mut_a.neg_self();
assert mut_a == -a;
@ -82,92 +82,92 @@ fn test_vec2() {
assert mut_a == a.div_v(&b);
// mut_a = a;
// assert c.abs() == Vec2::new( 2.0f, 1.0f);
// assert c.min(&d) == Vec2::new(-2.0f, -1.0f);
// assert c.max(&d) == Vec2::new( 1.0f, 0.0f);
// assert c.abs() == vec2::new( 2.0, 1.0);
// assert c.min(&d) == vec2::new(-2.0, -1.0);
// assert c.max(&d) == vec2::new( 1.0, 0.0);
}
#[test]
fn test_vec2_fuzzy_eq() {
assert !Vec2::new(0.000001, 0.000001).fuzzy_eq(&Vec2::new(0.0, 0.0));
assert Vec2::new(0.0000001, 0.0000001).fuzzy_eq(&Vec2::new(0.0, 0.0));
assert !vec2::new(0.000001, 0.000001).fuzzy_eq(&vec2::new(0.0, 0.0));
assert vec2::new(0.0000001, 0.0000001).fuzzy_eq(&vec2::new(0.0, 0.0));
}
#[test]
fn test_vec2_euclidean() {
let a = Vec2::new(5f, 12f); // (5, 12, 13) Pythagorean triple
let b0 = Vec2::new(3f, 4f); // (3, 4, 5) Pythagorean triple
let a = vec2::new(5.0, 12.0); // (5, 12, 13) Pythagorean triple
let b0 = vec2::new(3.0, 4.0); // (3, 4, 5) Pythagorean triple
let b = a.add_v(&b0);
assert a.length() == 13f;
assert a.length2() == 13f * 13f;
assert a.length() == 13.0;
assert a.length2() == 13.0 * 13.0;
assert b0.length() == 5f;
assert b0.length2() == 5f * 5f;
assert b0.length() == 5.0;
assert b0.length2() == 5.0 * 5.0;
assert a.distance(&b) == 5f;
assert a.distance2(&b) == 5f * 5f;
assert a.distance(&b) == 5.0;
assert a.distance2(&b) == 5.0 * 5.0;
assert Vec2::new(1f, 0f).angle(&Vec2::new(0f, 1f)).fuzzy_eq(&Float::frac_pi_2());
assert Vec2::new(10f, 0f).angle(&Vec2::new(0f, 5f)).fuzzy_eq(&Float::frac_pi_2());
assert Vec2::new(-1f, 0f).angle(&Vec2::new(0f, 1f)).fuzzy_eq(&Float::frac_pi_2());
assert vec2::new(1.0, 0.0).angle(&vec2::new(0.0, 1.0)).fuzzy_eq(&Float::frac_pi_2());
assert vec2::new(10.0, 0.0).angle(&vec2::new(0.0, 5.0)).fuzzy_eq(&Float::frac_pi_2());
assert vec2::new(-1.0, 0.0).angle(&vec2::new(0.0, 1.0)).fuzzy_eq(&Float::frac_pi_2());
assert Vec2::new(3f, 4f).normalize().fuzzy_eq(&Vec2::new(3f/5f, 4f/5f));
assert vec2::new(3.0, 4.0).normalize().fuzzy_eq(&vec2::new(3.0/5.0, 4.0/5.0));
// TODO: test normalize_to, normalize_self, and normalize_self_to
let c = Vec2::new(-2.0f, -1.0f);
let d = Vec2::new( 1.0f, 0.0f);
let c = vec2::new(-2.0, -1.0);
let d = vec2::new( 1.0, 0.0);
assert c.lerp(&d, 0.75f) == Vec2::new(0.250f, -0.250f);
assert c.lerp(&d, 0.75) == vec2::new(0.250, -0.250);
let mut mut_c = c;
mut_c.lerp_self(&d, &0.75f);
assert mut_c == c.lerp(&d, 0.75f);
mut_c.lerp_self(&d, &0.75);
assert mut_c == c.lerp(&d, 0.75);
}
#[test]
fn test_vec2_boolean() {
let tf = Vec2::new(true, false);
let ff = Vec2::new(false, false);
let tt = Vec2::new(true, true);
let tf = bvec2::new(true, false);
let ff = bvec2::new(false, false);
let tt = bvec2::new(true, true);
assert tf.any() == true;
assert tf.all() == false;
assert tf.not() == Vec2::new(false, true);
assert tf.not() == bvec2::new(false, true);
assert ff.any() == false;
assert ff.all() == false;
assert ff.not() == Vec2::new(true, true);
assert ff.not() == bvec2::new(true, true);
assert tt.any() == true;
assert tt.all() == true;
assert tt.not() == Vec2::new(false, false);
assert tt.not() == bvec2::new(false, false);
}
#[test]
fn test_vec3() {
// assert Vec3::dim == 3;
let a = Vec3 { x: 1f, y: 2f, z: 3f };
let b = Vec3 { x: 4f, y: 5f, z: 6f };
let f1 = 1.5f;
let f2 = 0.5f;
let a = Vec3 { x: 1.0, y: 2.0, z: 3.0 };
let b = Vec3 { x: 4.0, y: 5.0, z: 6.0 };
let f1 = 1.5;
let f2 = 0.5;
let mut mut_a = a;
assert Vec3::new(1f, 2f, 3f) == a;
// assert Vec3::from_value(1f32) == Vec3::new(1f32, 1f32, 1f32);
assert vec3::new(1.0, 2.0, 3.0) == a;
assert vec3::from_value(1.0) == vec3::new(1.0, 1.0, 1.0);
// assert Vec3::zero() == Vec3::new(0f, 0f, 0f);
// assert Vec3::unit_x() == Vec3::new(1f, 0f, 0f);
// assert Vec3::unit_y() == Vec3::new(0f, 1f, 0f);
// assert Vec3::unit_z() == Vec3::new(0f, 0f, 1f);
// assert Vec3::identity() == Vec3::new(1f, 1f, 1f);
assert vec3::zero() == vec3::new(0.0, 0.0, 0.0);
assert vec3::unit_x() == vec3::new(1.0, 0.0, 0.0);
assert vec3::unit_y() == vec3::new(0.0, 1.0, 0.0);
assert vec3::unit_z() == vec3::new(0.0, 0.0, 1.0);
assert vec3::identity() == vec3::new(1.0, 1.0, 1.0);
*mut_a.index_mut(0) = 42f;
*mut_a.index_mut(1) = 43f;
*mut_a.index_mut(2) = 44f;
assert mut_a == Vec3::new(42f, 43f, 44f);
*mut_a.index_mut(0) = 42.0;
*mut_a.index_mut(1) = 43.0;
*mut_a.index_mut(2) = 44.0;
assert mut_a == vec3::new(42.0, 43.0, 44.0);
mut_a = a;
mut_a.swap(0, 2);
@ -180,32 +180,32 @@ fn test_vec3() {
assert mut_a[2] == a[1];
mut_a = a;
assert a.x == 1f;
assert a.y == 2f;
assert a.z == 3f;
assert a[0] == 1f;
assert a[1] == 2f;
assert a[2] == 3f;
assert a.x == 1.0;
assert a.y == 2.0;
assert a.z == 3.0;
assert a[0] == 1.0;
assert a[1] == 2.0;
assert a[2] == 3.0;
assert a.cross(&b) == Vec3::new(-3f, 6f, -3f);
assert a.cross(&b) == vec3::new(-3.0, 6.0, -3.0);
mut_a.cross_self(&b);
assert mut_a == a.cross(&b);
mut_a = a;
assert -a == Vec3::new(-1f, -2f, -3f);
assert a.neg() == Vec3::new(-1f, -2f, -3f);
assert -a == vec3::new(-1.0, -2.0, -3.0);
assert a.neg() == vec3::new(-1.0, -2.0, -3.0);
assert Vec3::new(0f, 0f, 0f).is_zero();
assert !Vec3::new(1f, 1f, 1f).is_zero();
assert vec3::new(0.0, 0.0, 0.0).is_zero();
assert !vec3::new(1.0, 1.0, 1.0).is_zero();
assert a.mul_t(f1) == Vec3::new( 1.5f, 3.0f, 4.5f);
assert a.div_t(f2) == Vec3::new( 2.0f, 4.0f, 6.0f);
assert a.mul_t(f1) == vec3::new( 1.5, 3.0, 4.5);
assert a.div_t(f2) == vec3::new( 2.0, 4.0, 6.0);
assert a.add_v(&b) == Vec3::new( 5f, 7f, 9f);
assert a.sub_v(&b) == Vec3::new( -3f, -3f, -3f);
assert a.mul_v(&b) == Vec3::new( 4f, 10f, 18f);
assert a.div_v(&b) == Vec3::new(1f/4f, 2f/5f, 3f/6f);
assert a.add_v(&b) == vec3::new( 5.0, 7.0, 9.0);
assert a.sub_v(&b) == vec3::new( -3.0, -3.0, -3.0);
assert a.mul_v(&b) == vec3::new( 4.0, 10.0, 18.0);
assert a.div_v(&b) == vec3::new(1.0/4.0, 2.0/5.0, 3.0/6.0);
mut_a.neg_self();
assert mut_a == -a;
@ -239,87 +239,87 @@ fn test_vec3() {
// fuzzy_eq
// eq
// assert c.abs() == Vec3::new( 2.0f, 1.0f, 1.0f);
// assert c.min(&d) == Vec3::new(-2.0f, -1.0f, 0.5f);
// assert c.max(&d) == Vec3::new( 1.0f, 0.0f, 1.0f);
// assert c.abs() == vec3::new( 2.0, 1.0, 1.0);
// assert c.min(&d) == vec3::new(-2.0, -1.0, 0.5);
// assert c.max(&d) == vec3::new( 1.0, 0.0, 1.0);
}
#[test]
fn test_vec3_fuzzy_eq() {
assert !Vec3::new(0.000001, 0.000001, 0.000001).fuzzy_eq(&Vec3::new(0.0, 0.0, 0.0));
assert Vec3::new(0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&Vec3::new(0.0, 0.0, 0.0));
assert !vec3::new(0.000001, 0.000001, 0.000001).fuzzy_eq(&vec3::new(0.0, 0.0, 0.0));
assert vec3::new(0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&vec3::new(0.0, 0.0, 0.0));
}
#[test]
fn test_vec3_euclidean() {
let a = Vec3::new(2f, 3f, 6f); // (2, 3, 6, 7) Pythagorean quadruple
let b0 = Vec3::new(1f, 4f, 8f); // (1, 4, 8, 9) Pythagorean quadruple
let a = vec3::new(2.0, 3.0, 6.0); // (2, 3, 6, 7) Pythagorean quadruple
let b0 = vec3::new(1.0, 4.0, 8.0); // (1, 4, 8, 9) Pythagorean quadruple
let b = a.add_v(&b0);
assert a.length() == 7f;
assert a.length2() == 7f * 7f;
assert a.length() == 7.0;
assert a.length2() == 7.0 * 7.0;
assert b0.length() == 9f;
assert b0.length2() == 9f * 9f;
assert b0.length() == 9.0;
assert b0.length2() == 9.0 * 9.0;
assert a.distance(&b) == 9f;
assert a.distance2(&b) == 9f * 9f;
assert a.distance(&b) == 9.0;
assert a.distance2(&b) == 9.0 * 9.0;
assert Vec3::new(1f, 0f, 1f).angle(&Vec3::new(1f, 1f, 0f)).fuzzy_eq(&Float::frac_pi_3());
assert Vec3::new(10f, 0f, 10f).angle(&Vec3::new(5f, 5f, 0f)).fuzzy_eq(&Float::frac_pi_3());
assert Vec3::new(-1f, 0f, -1f).angle(&Vec3::new(1f, -1f, 0f)).fuzzy_eq(&(2f * Float::frac_pi_3()));
assert vec3::new(1.0, 0.0, 1.0).angle(&vec3::new(1.0, 1.0, 0.0)).fuzzy_eq(&Float::frac_pi_3());
assert vec3::new(10.0, 0.0, 10.0).angle(&vec3::new(5.0, 5.0, 0.0)).fuzzy_eq(&Float::frac_pi_3());
assert vec3::new(-1.0, 0.0, -1.0).angle(&vec3::new(1.0, -1.0, 0.0)).fuzzy_eq(&(2.0 * Float::frac_pi_3()));
assert Vec3::new(2f, 3f, 6f).normalize().fuzzy_eq(&Vec3::new(2f/7f, 3f/7f, 6f/7f));
assert vec3::new(2.0, 3.0, 6.0).normalize().fuzzy_eq(&vec3::new(2.0/7.0, 3.0/7.0, 6.0/7.0));
// TODO: test normalize_to, normalize_self, and normalize_self_to
let c = Vec3::new(-2.0f, -1.0f, 1.0f);
let d = Vec3::new( 1.0f, 0.0f, 0.5f);
let c = vec3::new(-2.0, -1.0, 1.0);
let d = vec3::new( 1.0, 0.0, 0.5);
assert c.lerp(&d, 0.75f) == Vec3::new(0.250f, -0.250f, 0.625f);
assert c.lerp(&d, 0.75) == vec3::new(0.250, -0.250, 0.625);
let mut mut_c = c;
mut_c.lerp_self(&d, &0.75f);
assert mut_c == c.lerp(&d, 0.75f);
mut_c.lerp_self(&d, &0.75);
assert mut_c == c.lerp(&d, 0.75);
}
#[test]
fn test_vec3_boolean() {
let tft = Vec3::new(true, false, true);
let fff = Vec3::new(false, false, false);
let ttt = Vec3::new(true, true, true);
let tft = bvec3::new(true, false, true);
let fff = bvec3::new(false, false, false);
let ttt = bvec3::new(true, true, true);
assert tft.any() == true;
assert tft.all() == false;
assert tft.not() == Vec3::new(false, true, false);
assert tft.not() == bvec3::new(false, true, false);
assert fff.any() == false;
assert fff.all() == false;
assert fff.not() == Vec3::new(true, true, true);
assert fff.not() == bvec3::new(true, true, true);
assert ttt.any() == true;
assert ttt.all() == true;
assert ttt.not() == Vec3::new(false, false, false);
assert ttt.not() == bvec3::new(false, false, false);
}
#[test]
fn test_vec4() {
// assert Vec4::dim == 4;
let a = Vec4 { x: 1f, y: 2f, z: 3f, w: 4f };
let b = Vec4 { x: 5f, y: 6f, z: 7f, w: 8f };
let f1 = 1.5f;
let f2 = 0.5f;
let a = Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 4.0 };
let b = Vec4 { x: 5.0, y: 6.0, z: 7.0, w: 8.0 };
let f1 = 1.5;
let f2 = 0.5;
let mut mut_a = a;
assert Vec4::new(1f, 2f, 3f, 4f) == a;
// assert Vec4::from_value(1f32) == Vec4::new(1f32, 1f32, 1f32, 1f32);
assert vec4::new(1.0, 2.0, 3.0, 4.0) == a;
assert vec4::from_value(1.0) == vec4::new(1.0, 1.0, 1.0, 1.0);
*mut_a.index_mut(0) = 42f;
*mut_a.index_mut(1) = 43f;
*mut_a.index_mut(2) = 44f;
*mut_a.index_mut(3) = 45f;
assert mut_a == Vec4::new(42f, 43f, 44f, 45f);
*mut_a.index_mut(0) = 42.0;
*mut_a.index_mut(1) = 43.0;
*mut_a.index_mut(2) = 44.0;
*mut_a.index_mut(3) = 45.0;
assert mut_a == vec4::new(42.0, 43.0, 44.0, 45.0);
mut_a = a;
mut_a.swap(0, 3);
@ -332,37 +332,37 @@ fn test_vec4() {
assert mut_a[2] == a[1];
mut_a = a;
// assert Vec4::zero() == Vec4::new(0f, 0f, 0f, 0f);
// assert Vec4::unit_x() == Vec4::new(1f, 0f, 0f, 0f);
// assert Vec4::unit_y() == Vec4::new(0f, 1f, 0f, 0f);
// assert Vec4::unit_z() == Vec4::new(0f, 0f, 1f, 0f);
// assert Vec4::unit_w() == Vec4::new(0f, 0f, 0f, 1f);
// assert Vec4::identity() == Vec4::new(1f, 1f, 1f, 1f);
assert vec4::zero() == vec4::new(0.0, 0.0, 0.0, 0.0);
assert vec4::unit_x() == vec4::new(1.0, 0.0, 0.0, 0.0);
assert vec4::unit_y() == vec4::new(0.0, 1.0, 0.0, 0.0);
assert vec4::unit_z() == vec4::new(0.0, 0.0, 1.0, 0.0);
assert vec4::unit_w() == vec4::new(0.0, 0.0, 0.0, 1.0);
assert vec4::identity() == vec4::new(1.0, 1.0, 1.0, 1.0);
assert a.x == 1f;
assert a.y == 2f;
assert a.z == 3f;
assert a.w == 4f;
assert a[0] == 1f;
assert a[1] == 2f;
assert a[2] == 3f;
assert a[3] == 4f;
assert a.x == 1.0;
assert a.y == 2.0;
assert a.z == 3.0;
assert a.w == 4.0;
assert a[0] == 1.0;
assert a[1] == 2.0;
assert a[2] == 3.0;
assert a[3] == 4.0;
assert -a == Vec4::new(-1f, -2f, -3f, -4f);
assert a.neg() == Vec4::new(-1f, -2f, -3f, -4f);
assert -a == vec4::new(-1.0, -2.0, -3.0, -4.0);
assert a.neg() == vec4::new(-1.0, -2.0, -3.0, -4.0);
assert Vec4::new(0f, 0f, 0f, 0f).is_zero();
assert !Vec4::new(1f, 1f, 1f, 1f).is_zero();
assert vec4::new(0.0, 0.0, 0.0, 0.0).is_zero();
assert !vec4::new(1.0, 1.0, 1.0, 1.0).is_zero();
assert a.mul_t(f1) == Vec4::new( 1.5f, 3.0f, 4.5f, 6.0f);
assert a.div_t(f2) == Vec4::new( 2.0f, 4.0f, 6.0f, 8.0f);
assert a.mul_t(f1) == vec4::new( 1.5, 3.0, 4.5, 6.0);
assert a.div_t(f2) == vec4::new( 2.0, 4.0, 6.0, 8.0);
assert a.add_v(&b) == Vec4::new( 6f, 8f, 10f, 12f);
assert a.sub_v(&b) == Vec4::new( -4f, -4f, -4f, -4f);
assert a.mul_v(&b) == Vec4::new( 5f, 12f, 21f, 32f);
assert a.div_v(&b) == Vec4::new(1f/5f, 2f/6f, 3f/7f, 4f/8f);
assert a.add_v(&b) == vec4::new( 6.0, 8.0, 10.0, 12.0);
assert a.sub_v(&b) == vec4::new( -4.0, -4.0, -4.0, -4.0);
assert a.mul_v(&b) == vec4::new( 5.0, 12.0, 21.0, 32.0);
assert a.div_v(&b) == vec4::new(1.0/5.0, 2.0/6.0, 3.0/7.0, 4.0/8.0);
assert a.dot(&b) == 70f;
assert a.dot(&b) == 70.0;
mut_a.neg_self();
assert mut_a == -a;
@ -392,64 +392,64 @@ fn test_vec4() {
assert mut_a == a.div_v(&b);
// mut_a = a;
// assert c.abs() == Vec4::new( 2.0f, 1.0f, 1.0f, 2.0f);
// assert c.min(&d) == Vec4::new(-2.0f, -1.0f, 0.5f, 1.0f);
// assert c.max(&d) == Vec4::new( 1.0f, 0.0f, 1.0f, 2.0f);
// assert c.abs() == vec4::new( 2.0, 1.0, 1.0, 2.0);
// assert c.min(&d) == vec4::new(-2.0, -1.0, 0.5, 1.0);
// assert c.max(&d) == vec4::new( 1.0, 0.0, 1.0, 2.0);
}
#[test]
fn test_vec4_fuzzy_eq() {
assert !Vec4::new(0.000001, 0.000001, 0.000001, 0.000001).fuzzy_eq(&Vec4::new(0.0, 0.0, 0.0, 0.0));
assert Vec4::new(0.0000001, 0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&Vec4::new(0.0, 0.0, 0.0, 0.0));
assert !vec4::new(0.000001, 0.000001, 0.000001, 0.000001).fuzzy_eq(&vec4::new(0.0, 0.0, 0.0, 0.0));
assert vec4::new(0.0000001, 0.0000001, 0.0000001, 0.0000001).fuzzy_eq(&vec4::new(0.0, 0.0, 0.0, 0.0));
}
#[test]
fn test_vec4_euclidean() {
let a = Vec4::new(1f, 2f, 4f, 10f); // (1, 2, 4, 10, 11) Pythagorean quintuple
let b0 = Vec4::new(1f, 2f, 8f, 10f); // (1, 2, 8, 10, 13) Pythagorean quintuple
let a = vec4::new(1.0, 2.0, 4.0, 10.0); // (1, 2, 4, 10, 11) Pythagorean quintuple
let b0 = vec4::new(1.0, 2.0, 8.0, 10.0); // (1, 2, 8, 10, 13) Pythagorean quintuple
let b = a.add_v(&b0);
assert a.length() == 11f;
assert a.length2() == 11f * 11f;
assert a.length() == 11.0;
assert a.length2() == 11.0 * 11.0;
assert b0.length() == 13f;
assert b0.length2() == 13f * 13f;
assert b0.length() == 13.0;
assert b0.length2() == 13.0 * 13.0;
assert a.distance(&b) == 13f;
assert a.distance2(&b) == 13f * 13f;
assert a.distance(&b) == 13.0;
assert a.distance2(&b) == 13.0 * 13.0;
assert Vec4::new(1f, 0f, 1f, 0f).angle(&Vec4::new(0f, 1f, 0f, 1f)).fuzzy_eq(&Float::frac_pi_2());
assert Vec4::new(10f, 0f, 10f, 0f).angle(&Vec4::new(0f, 5f, 0f, 5f)).fuzzy_eq(&Float::frac_pi_2());
assert Vec4::new(-1f, 0f, -1f, 0f).angle(&Vec4::new(0f, 1f, 0f, 1f)).fuzzy_eq(&Float::frac_pi_2());
assert vec4::new(1.0, 0.0, 1.0, 0.0).angle(&vec4::new(0.0, 1.0, 0.0, 1.0)).fuzzy_eq(&Float::frac_pi_2());
assert vec4::new(10.0, 0.0, 10.0, 0.0).angle(&vec4::new(0.0, 5.0, 0.0, 5.0)).fuzzy_eq(&Float::frac_pi_2());
assert vec4::new(-1.0, 0.0, -1.0, 0.0).angle(&vec4::new(0.0, 1.0, 0.0, 1.0)).fuzzy_eq(&Float::frac_pi_2());
assert Vec4::new(1f, 2f, 4f, 10f).normalize().fuzzy_eq(&Vec4::new(1f/11f, 2f/11f, 4f/11f, 10f/11f));
assert vec4::new(1.0, 2.0, 4.0, 10.0).normalize().fuzzy_eq(&vec4::new(1.0/11.0, 2.0/11.0, 4.0/11.0, 10.0/11.0));
// TODO: test normalize_to, normalize_self, and normalize_self_to
let c = Vec4::new(-2.0f, -1.0f, 1.0f, 2.0f);
let d = Vec4::new( 1.0f, 0.0f, 0.5f, 1.0f);
let c = vec4::new(-2.0, -1.0, 1.0, 2.0);
let d = vec4::new( 1.0, 0.0, 0.5, 1.0);
assert c.lerp(&d, 0.75f) == Vec4::new(0.250f, -0.250f, 0.625f, 1.250f);
assert c.lerp(&d, 0.75) == vec4::new(0.250, -0.250, 0.625, 1.250);
let mut mut_c = c;
mut_c.lerp_self(&d, &0.75f);
assert mut_c == c.lerp(&d, 0.75f);
mut_c.lerp_self(&d, &0.75);
assert mut_c == c.lerp(&d, 0.75);
}
#[test]
fn test_vec4_boolean() {
let tftf = Vec4::new(true, false, true, false);
let ffff = Vec4::new(false, false, false, false);
let tttt = Vec4::new(true, true, true, true);
let tftf = bvec4::new(true, false, true, false);
let ffff = bvec4::new(false, false, false, false);
let tttt = bvec4::new(true, true, true, true);
assert tftf.any() == true;
assert tftf.all() == false;
assert tftf.not() == Vec4::new(false, true, false, true);
assert tftf.not() == bvec4::new(false, true, false, true);
assert ffff.any() == false;
assert ffff.all() == false;
assert ffff.not() == Vec4::new(true, true, true, true);
assert ffff.not() == bvec4::new(true, true, true, true);
assert tttt.any() == true;
assert tttt.all() == true;
assert tttt.not() == Vec4::new(false, false, false, false);
assert tttt.not() == bvec4::new(false, false, false, false);
}

View file

@ -13,6 +13,7 @@ use vec::{
Vec3,
Vector,
Vector2,
Vector3,
MutableVector,
NumericVector,
NumericVector2,
@ -41,17 +42,10 @@ use vec::{
#[deriving_eq]
pub struct Vec2<T> { x: T, y: T }
pub impl<T> Vec2<T> {
#[inline(always)]
static pure fn new(x: T, y: T ) -> Vec2<T> {
Vec2 { x: x, y: y }
}
}
pub impl<T:Copy> Vec2<T>: Vector<T> {
pub impl<T:Copy Eq> Vec2<T>: Vector<T> {
#[inline(always)]
static pure fn from_value(value: T) -> Vec2<T> {
Vec2::new(value, value)
Vector2::new(value, value)
}
#[inline(always)]
@ -71,7 +65,7 @@ pub impl<T> Vec2<T>: Vector2<T> {
}
}
pub impl<T:Copy> Vec2<T>: Index<uint, T> {
pub impl<T:Copy Eq> Vec2<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 2) |slice| { slice[i] } }
@ -98,12 +92,12 @@ pub impl<T:Copy> Vec2<T>: MutableVector<T> {
pub impl<T:Copy Number> Vec2<T>: NumericVector<T> {
#[inline(always)]
static pure fn identity() -> Vec2<T> {
Vec2::new(one(), one())
Vector2::new(one::<T>(), one::<T>())
}
#[inline(always)]
static pure fn zero() -> Vec2<T> {
Vec2::new(zero(), zero())
Vector2::new(zero::<T>(), zero::<T>())
}
#[inline(always)]
@ -114,38 +108,38 @@ pub impl<T:Copy Number> Vec2<T>: NumericVector<T> {
#[inline(always)]
pure fn mul_t(&self, value: T) -> Vec2<T> {
Vec2::new(self[0] * value,
self[1] * value)
Vector2::new(self[0] * value,
self[1] * value)
}
#[inline(always)]
pure fn div_t(&self, value: T) -> Vec2<T> {
Vec2::new(self[0] / value,
self[1] / value)
Vector2::new(self[0] / value,
self[1] / value)
}
#[inline(always)]
pure fn add_v(&self, other: &Vec2<T>) -> Vec2<T> {
Vec2::new(self[0] + other[0],
self[1] + other[1])
Vector2::new(self[0] + other[0],
self[1] + other[1])
}
#[inline(always)]
pure fn sub_v(&self, other: &Vec2<T>) -> Vec2<T> {
Vec2::new(self[0] - other[0],
self[1] - other[1])
Vector2::new(self[0] - other[0],
self[1] - other[1])
}
#[inline(always)]
pure fn mul_v(&self, other: &Vec2<T>) -> Vec2<T> {
Vec2::new(self[0] * other[0],
self[1] * other[1])
Vector2::new(self[0] * other[0],
self[1] * other[1])
}
#[inline(always)]
pure fn div_v(&self, other: &Vec2<T>) -> Vec2<T> {
Vec2::new(self[0] / other[0],
self[1] / other[1])
Vector2::new(self[0] / other[0],
self[1] / other[1])
}
#[inline(always)]
@ -158,19 +152,19 @@ pub impl<T:Copy Number> Vec2<T>: NumericVector<T> {
pub impl<T:Copy Number> Vec2<T>: Neg<Vec2<T>> {
#[inline(always)]
pure fn neg(&self) -> Vec2<T> {
Vec2::new(-self[0], -self[1])
Vector2::new(-self[0], -self[1])
}
}
pub impl<T:Copy Number> Vec2<T>: NumericVector2<T> {
#[inline(always)]
static pure fn unit_x() -> Vec2<T> {
Vec2::new(one(), zero())
Vector2::new(one::<T>(), zero::<T>())
}
#[inline(always)]
static pure fn unit_y() -> Vec2<T> {
Vec2::new(zero(), one())
Vector2::new(zero::<T>(), one::<T>())
}
#[inline(always)]
@ -226,7 +220,7 @@ pub impl<T:Copy Number> Vec2<T>: MutableNumericVector<&self/T> {
pub impl<T:Copy Number> Vec2<T>: ToHomogeneous<Vec3<T>> {
#[inline(always)]
pure fn to_homogeneous(&self) -> Vec3<T> {
Vec3::new(self.x, self.y, zero())
Vector3::new(self.x, self.y, zero())
}
}
@ -290,7 +284,7 @@ pub impl<T:Copy Float> Vec2<T>: MutableEuclideanVector<&self/T> {
}
}
pub impl<T:Copy FuzzyEq> Vec2<T>: FuzzyEq {
pub impl<T:Copy FuzzyEq Eq> Vec2<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Vec2<T>) -> bool {
self[0].fuzzy_eq(&other[0]) &&
@ -298,43 +292,43 @@ pub impl<T:Copy FuzzyEq> Vec2<T>: FuzzyEq {
}
}
pub impl<T:Copy Ord> Vec2<T>: OrdinalVector<T, Vec2<bool>> {
pub impl<T:Copy Ord Eq> Vec2<T>: OrdinalVector<T, Vec2<bool>> {
#[inline(always)]
pure fn less_than(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] < other[0],
self[1] < other[1])
Vector2::new(self[0] < other[0],
self[1] < other[1])
}
#[inline(always)]
pure fn less_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] <= other[0],
self[1] <= other[1])
Vector2::new(self[0] <= other[0],
self[1] <= other[1])
}
#[inline(always)]
pure fn greater_than(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] > other[0],
self[1] > other[1])
Vector2::new(self[0] > other[0],
self[1] > other[1])
}
#[inline(always)]
pure fn greater_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] >= other[0],
self[1] >= other[1])
Vector2::new(self[0] >= other[0],
self[1] >= other[1])
}
}
pub impl<T:Copy Eq> Vec2<T>: EquableVector<T, Vec2<bool>> {
#[inline(always)]
pure fn equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] == other[0],
self[1] == other[1])
Vector2::new(self[0] == other[0],
self[1] == other[1])
}
#[inline(always)]
pure fn not_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] != other[0],
self[1] != other[1])
Vector2::new(self[0] != other[0],
self[1] != other[1])
}
}
@ -351,18 +345,18 @@ pub impl Vec2<bool>: BooleanVector {
#[inline(always)]
pure fn not(&self) -> Vec2<bool> {
Vec2::new(!self[0], !self[1])
Vector2::new(!self[0], !self[1])
}
}
// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification]
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
pub type vec2 = Vec2<f32>; /// a two-component single-precision floating-point vector
pub type dvec2 = Vec2<f64>; /// a two-component double-precision floating-point vector
pub type bvec2 = Vec2<bool>; /// a two-component Boolean vector
pub type ivec2 = Vec2<i32>; /// a two-component signed integer vector
pub type uvec2 = Vec2<u32>; /// a two-component unsigned integer vector
pub type vec2 = Vec2<f32>; // a two-component single-precision floating-point vector
pub type dvec2 = Vec2<f64>; // a two-component double-precision floating-point vector
pub type bvec2 = Vec2<bool>; // a two-component Boolean vector
pub type ivec2 = Vec2<i32>; // a two-component signed integer vector
pub type uvec2 = Vec2<u32>; // a two-component unsigned integer vector
// Static method wrappers for GLSL-style types

View file

@ -13,6 +13,7 @@ use vec::{
Vec4,
Vector,
Vector3,
Vector4,
MutableVector,
NumericVector,
NumericVector3,
@ -43,17 +44,10 @@ use vec::{
#[deriving_eq]
pub struct Vec3<T> { x: T, y: T, z: T }
pub impl<T> Vec3<T> {
#[inline(always)]
static pure fn new(x: T, y: T, z: T) -> Vec3<T> {
Vec3 { x: x, y: y, z: z }
}
}
pub impl<T:Copy> Vec3<T>: Vector<T> {
pub impl<T:Copy Eq> Vec3<T>: Vector<T> {
#[inline(always)]
static pure fn from_value(value: T) -> Vec3<T> {
Vec3::new(value, value, value)
Vector3::new(value, value, value)
}
#[inline(always)]
@ -73,7 +67,7 @@ pub impl<T> Vec3<T>: Vector3<T> {
}
}
pub impl<T:Copy> Vec3<T>: Index<uint, T> {
pub impl<T:Copy Eq> Vec3<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } }
@ -101,12 +95,12 @@ pub impl<T:Copy> Vec3<T>: MutableVector<T> {
pub impl<T:Copy Number> Vec3<T>: NumericVector<T> {
#[inline(always)]
static pure fn identity() -> Vec3<T> {
Vec3::new(one(), one(), one())
Vector3::new(one::<T>(), one::<T>(), one::<T>())
}
#[inline(always)]
static pure fn zero() -> Vec3<T> {
Vec3::new(zero(), zero(), zero())
Vector3::new(zero::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
@ -118,44 +112,44 @@ pub impl<T:Copy Number> Vec3<T>: NumericVector<T> {
#[inline(always)]
pure fn mul_t(&self, value: T) -> Vec3<T> {
Vec3::new(self[0] * value,
self[1] * value,
self[2] * value)
Vector3::new(self[0] * value,
self[1] * value,
self[2] * value)
}
#[inline(always)]
pure fn div_t(&self, value: T) -> Vec3<T> {
Vec3::new(self[0] / value,
self[1] / value,
self[2] / value)
Vector3::new(self[0] / value,
self[1] / value,
self[2] / value)
}
#[inline(always)]
pure fn add_v(&self, other: &Vec3<T>) -> Vec3<T>{
Vec3::new(self[0] + other[0],
self[1] + other[1],
self[2] + other[2])
Vector3::new(self[0] + other[0],
self[1] + other[1],
self[2] + other[2])
}
#[inline(always)]
pure fn sub_v(&self, other: &Vec3<T>) -> Vec3<T>{
Vec3::new(self[0] - other[0],
self[1] - other[1],
self[2] - other[2])
Vector3::new(self[0] - other[0],
self[1] - other[1],
self[2] - other[2])
}
#[inline(always)]
pure fn mul_v(&self, other: &Vec3<T>) -> Vec3<T>{
Vec3::new(self[0] * other[0],
self[1] * other[1],
self[2] * other[2])
Vector3::new(self[0] * other[0],
self[1] * other[1],
self[2] * other[2])
}
#[inline(always)]
pure fn div_v(&self, other: &Vec3<T>) -> Vec3<T>{
Vec3::new(self[0] / other[0],
self[1] / other[1],
self[2] / other[2])
Vector3::new(self[0] / other[0],
self[1] / other[1],
self[2] / other[2])
}
#[inline(always)]
@ -169,31 +163,31 @@ pub impl<T:Copy Number> Vec3<T>: NumericVector<T> {
pub impl<T:Copy Number> Vec3<T>: Neg<Vec3<T>> {
#[inline(always)]
pure fn neg(&self) -> Vec3<T> {
Vec3::new(-self[0], -self[1], -self[2])
Vector3::new(-self[0], -self[1], -self[2])
}
}
pub impl<T:Copy Number> Vec3<T>: NumericVector3<T> {
#[inline(always)]
static pure fn unit_x() -> Vec3<T> {
Vec3::new(one(), zero(), zero())
Vector3::new(one::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
static pure fn unit_y() -> Vec3<T> {
Vec3::new(zero(), one(), zero())
Vector3::new(zero::<T>(), one::<T>(), zero::<T>())
}
#[inline(always)]
static pure fn unit_z() -> Vec3<T> {
Vec3::new(zero(), zero(), one())
Vector3::new(zero::<T>(), zero::<T>(), one::<T>())
}
#[inline(always)]
pure fn cross(&self, other: &Vec3<T>) -> Vec3<T> {
Vec3::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]))
Vector3::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]))
}
}
@ -258,7 +252,7 @@ pub impl<T:Copy Number> Vec3<T>: MutableNumericVector3<&self/T> {
pub impl<T:Copy Number> Vec3<T>: ToHomogeneous<Vec4<T>> {
#[inline(always)]
pure fn to_homogeneous(&self) -> Vec4<T> {
Vec4::new(self.x, self.y, self.z, zero())
Vector4::new(self.x, self.y, self.z, zero())
}
}
@ -322,7 +316,7 @@ pub impl<T:Copy Float> Vec3<T>: MutableEuclideanVector<&self/T> {
}
}
pub impl<T:Copy FuzzyEq> Vec3<T>: FuzzyEq {
pub impl<T:Copy FuzzyEq Eq> Vec3<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Vec3<T>) -> bool {
self[0].fuzzy_eq(&other[0]) &&
@ -331,49 +325,49 @@ pub impl<T:Copy FuzzyEq> Vec3<T>: FuzzyEq {
}
}
pub impl<T:Copy Ord> Vec3<T>: OrdinalVector<T, Vec3<bool>> {
pub impl<T:Copy Ord Eq> Vec3<T>: OrdinalVector<T, Vec3<bool>> {
#[inline(always)]
pure fn less_than(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] < other[0],
self[1] < other[1],
self[2] < other[2])
Vector3::new(self[0] < other[0],
self[1] < other[1],
self[2] < other[2])
}
#[inline(always)]
pure fn less_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] <= other[0],
self[1] <= other[1],
self[2] <= other[2])
Vector3::new(self[0] <= other[0],
self[1] <= other[1],
self[2] <= other[2])
}
#[inline(always)]
pure fn greater_than(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] > other[0],
self[1] > other[1],
self[2] > other[2])
Vector3::new(self[0] > other[0],
self[1] > other[1],
self[2] > other[2])
}
#[inline(always)]
pure fn greater_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2])
Vector3::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2])
}
}
pub impl<T:Copy Eq> Vec3<T>: EquableVector<T, Vec3<bool>> {
#[inline(always)]
pure fn equal(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] == other[0],
self[1] == other[1],
self[2] == other[2])
Vector3::new(self[0] == other[0],
self[1] == other[1],
self[2] == other[2])
}
#[inline(always)]
pure fn not_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2])
Vector3::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2])
}
}
@ -390,18 +384,18 @@ pub impl Vec3<bool>: BooleanVector {
#[inline(always)]
pure fn not(&self) -> Vec3<bool> {
Vec3::new(!self[0], !self[1], !self[2])
Vector3::new(!self[0], !self[1], !self[2])
}
}
// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification]
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
pub type vec3 = Vec3<f32>; /// a three-component single-precision floating-point vector
pub type dvec3 = Vec3<f64>; /// a three-component double-precision floating-point vector
pub type bvec3 = Vec3<bool>; /// a three-component Boolean vector
pub type ivec3 = Vec3<i32>; /// a three-component signed integer vector
pub type uvec3 = Vec3<u32>; /// a three-component unsigned integer vector
pub type vec3 = Vec3<f32>; // a three-component single-precision floating-point vector
pub type dvec3 = Vec3<f64>; // a three-component double-precision floating-point vector
pub type bvec3 = Vec3<bool>; // a three-component Boolean vector
pub type ivec3 = Vec3<i32>; // a three-component signed integer vector
pub type uvec3 = Vec3<u32>; // a three-component unsigned integer vector
// Static method wrappers for GLSL-style types

View file

@ -42,17 +42,10 @@ use vec::{
#[deriving_eq]
pub struct Vec4<T> { x: T, y: T, z: T, w: T }
pub impl<T> Vec4<T> {
#[inline(always)]
static pure fn new(x: T, y: T, z: T, w: T) -> Vec4<T> {
Vec4 { x: x, y: y, z: z, w: w }
}
}
pub impl<T:Copy> Vec4<T>: Vector<T> {
pub impl<T:Copy Eq> Vec4<T>: Vector<T> {
#[inline(always)]
static pure fn from_value(value: T) -> Vec4<T> {
Vec4::new(value, value, value, value)
Vector4::new(value, value, value, value)
}
#[inline(always)]
@ -72,7 +65,7 @@ pub impl<T> Vec4<T>: Vector4<T> {
}
}
pub impl<T:Copy> Vec4<T>: Index<uint, T> {
pub impl<T:Copy Eq> Vec4<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
@ -101,12 +94,12 @@ pub impl<T:Copy> Vec4<T>: MutableVector<T> {
pub impl<T:Copy Number> Vec4<T>: NumericVector<T> {
#[inline(always)]
static pure fn identity() -> Vec4<T> {
Vec4::new(one(), one(), one(), one())
Vector4::new(one::<T>(), one::<T>(), one::<T>(), one::<T>())
}
#[inline(always)]
static pure fn zero() -> Vec4<T> {
Vec4::new(zero(), zero(), zero(), zero())
Vector4::new(zero::<T>(), zero::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
@ -119,50 +112,50 @@ pub impl<T:Copy Number> Vec4<T>: NumericVector<T> {
#[inline(always)]
pure fn mul_t(&self, value: T) -> Vec4<T> {
Vec4::new(self[0] * value,
self[1] * value,
self[2] * value,
self[3] * value)
Vector4::new(self[0] * value,
self[1] * value,
self[2] * value,
self[3] * value)
}
#[inline(always)]
pure fn div_t(&self, value: T) -> Vec4<T> {
Vec4::new(self[0] / value,
self[1] / value,
self[2] / value,
self[3] / value)
Vector4::new(self[0] / value,
self[1] / value,
self[2] / value,
self[3] / value)
}
#[inline(always)]
pure fn add_v(&self, other: &Vec4<T>) -> Vec4<T> {
Vec4::new(self[0] + other[0],
self[1] + other[1],
self[2] + other[2],
self[3] + other[3])
Vector4::new(self[0] + other[0],
self[1] + other[1],
self[2] + other[2],
self[3] + other[3])
}
#[inline(always)]
pure fn sub_v(&self, other: &Vec4<T>) -> Vec4<T> {
Vec4::new(self[0] - other[0],
self[1] - other[1],
self[2] - other[2],
self[3] - other[3])
Vector4::new(self[0] - other[0],
self[1] - other[1],
self[2] - other[2],
self[3] - other[3])
}
#[inline(always)]
pure fn mul_v(&self, other: &Vec4<T>) -> Vec4<T> {
Vec4::new(self[0] * other[0],
self[1] * other[1],
self[2] * other[2],
self[3] * other[3])
Vector4::new(self[0] * other[0],
self[1] * other[1],
self[2] * other[2],
self[3] * other[3])
}
#[inline(always)]
pure fn div_v(&self, other: &Vec4<T>) -> Vec4<T> {
Vec4::new(self[0] / other[0],
self[1] / other[1],
self[2] / other[2],
self[3] / other[3])
Vector4::new(self[0] / other[0],
self[1] / other[1],
self[2] / other[2],
self[3] / other[3])
}
#[inline(always)]
@ -177,29 +170,29 @@ pub impl<T:Copy Number> Vec4<T>: NumericVector<T> {
pub impl<T:Copy Number> Vec4<T>: Neg<Vec4<T>> {
#[inline(always)]
pure fn neg(&self) -> Vec4<T> {
Vec4::new(-self[0], -self[1], -self[2], -self[3])
Vector4::new(-self[0], -self[1], -self[2], -self[3])
}
}
pub impl<T:Copy Number> Vec4<T>: NumericVector4<T> {
#[inline(always)]
static pure fn unit_x() -> Vec4<T> {
Vec4::new(one(), zero(), zero(), zero())
Vector4::new(one::<T>(), zero::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
static pure fn unit_y() -> Vec4<T> {
Vec4::new(zero(), one(), zero(), zero())
Vector4::new(zero::<T>(), one::<T>(), zero::<T>(), zero::<T>())
}
#[inline(always)]
static pure fn unit_z() -> Vec4<T> {
Vec4::new(zero(), zero(), one(), zero())
Vector4::new(zero::<T>(), zero::<T>(), one::<T>(), zero::<T>())
}
#[inline(always)]
static pure fn unit_w() -> Vec4<T> {
Vec4::new(zero(), zero(), zero(), one())
Vector4::new(zero::<T>(), zero::<T>(), zero::<T>(), one::<T>())
}
}
@ -321,7 +314,7 @@ pub impl<T:Copy Float> Vec4<T>: MutableEuclideanVector<&self/T> {
}
}
pub impl<T:Copy FuzzyEq> Vec4<T>: FuzzyEq {
pub impl<T:Copy FuzzyEq Eq> Vec4<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Vec4<T>) -> bool {
self[0].fuzzy_eq(&other[0]) &&
@ -331,55 +324,55 @@ pub impl<T:Copy FuzzyEq> Vec4<T>: FuzzyEq {
}
}
pub impl<T:Copy Ord> Vec4<T>: OrdinalVector<T, Vec4<bool>> {
pub impl<T:Copy Ord Eq> Vec4<T>: OrdinalVector<T, Vec4<bool>> {
#[inline(always)]
pure fn less_than(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] < other[0],
self[1] < other[1],
self[2] < other[2],
self[3] < other[3])
Vector4::new(self[0] < other[0],
self[1] < other[1],
self[2] < other[2],
self[3] < other[3])
}
#[inline(always)]
pure fn less_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] <= other[0],
self[1] <= other[1],
self[2] <= other[2],
self[3] <= other[3])
Vector4::new(self[0] <= other[0],
self[1] <= other[1],
self[2] <= other[2],
self[3] <= other[3])
}
#[inline(always)]
pure fn greater_than(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] > other[0],
self[1] > other[1],
self[2] > other[2],
self[3] > other[3])
Vector4::new(self[0] > other[0],
self[1] > other[1],
self[2] > other[2],
self[3] > other[3])
}
#[inline(always)]
pure fn greater_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2],
self[3] >= other[3])
Vector4::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2],
self[3] >= other[3])
}
}
pub impl<T:Copy Eq> Vec4<T>: EquableVector<T, Vec4<bool>> {
#[inline(always)]
pure fn equal(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] == other[0],
self[1] == other[1],
self[2] == other[2],
self[3] == other[3])
Vector4::new(self[0] == other[0],
self[1] == other[1],
self[2] == other[2],
self[3] == other[3])
}
#[inline(always)]
pure fn not_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
Vec4::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2],
self[3] != other[3])
Vector4::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2],
self[3] != other[3])
}
}
@ -396,18 +389,18 @@ pub impl Vec4<bool>: BooleanVector {
#[inline(always)]
pure fn not(&self) -> Vec4<bool> {
Vec4::new(!self[0], !self[1], !self[2], !self[3])
Vector4::new(!self[0], !self[1], !self[2], !self[3])
}
}
// GLSL-style type aliases, corresponding to Section 4.1.5 of the [GLSL 4.30.6 specification]
// (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
pub type vec4 = Vec4<f32>; /// a four-component single-precision floating-point vector
pub type dvec4 = Vec4<f64>; /// a four-component double-precision floating-point vector
pub type bvec4 = Vec4<bool>; /// a four-component Boolean vector
pub type ivec4 = Vec4<i32>; /// a four-component signed integer vector
pub type uvec4 = Vec4<u32>; /// a four-component unsigned integer vector
pub type vec4 = Vec4<f32>; // a four-component single-precision floating-point vector
pub type dvec4 = Vec4<f64>; // a four-component double-precision floating-point vector
pub type bvec4 = Vec4<bool>; // a four-component Boolean vector
pub type ivec4 = Vec4<i32>; // a four-component signed integer vector
pub type uvec4 = Vec4<u32>; // a four-component unsigned integer vector
// Static method wrappers for GLSL-style types