Remove index operator impls to prevent copying

We could re-implement this once the Index trait has been improved
This commit is contained in:
Brendan Zabarauskas 2013-05-31 21:05:43 +10:00
parent 86241f69cb
commit e630faf239
3 changed files with 434 additions and 458 deletions

View file

@ -1,7 +1,6 @@
use std::cast::transmute; use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use std::util;
use vec::*; use vec::*;
use quat::Quat; use quat::Quat;
@ -18,13 +17,13 @@ use num::NumAssign;
* floating point type and have the same number of dimensions as the * floating point type and have the same number of dimensions as the
* number of rows and columns in the matrix. * number of rows and columns in the matrix.
*/ */
pub trait BaseMat<T,V>: Index<uint, V> + Eq + Neg<Self> { pub trait BaseMat<T,V>: Eq + Neg<Self> {
/** /**
* # Return value * # Return value
* *
* The column vector at `i` * The column vector at `i`
*/ */
fn col(&self, i: uint) -> V; fn col<'a>(&'a self, i: uint) -> &'a V;
/** /**
* # Return value * # Return value
@ -316,12 +315,14 @@ pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> { impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn col(&self, i: uint) -> Vec2<T> { self[i] } fn col<'a>(&'a self, i: uint) -> &'a Vec2<T> {
unsafe { &'a transmute::<&'a Mat2<T>, &'a [Vec2<T>,..2]>(self)[i] }
}
#[inline(always)] #[inline(always)]
fn row(&self, i: uint) -> Vec2<T> { fn row(&self, i: uint) -> Vec2<T> {
BaseVec2::new(self[0][i], BaseVec2::new(*self.col(0).index(i),
self[1][i]) *self.col(1).index(i))
} }
/** /**
@ -382,32 +383,32 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn mul_t(&self, value: T) -> Mat2<T> { fn mul_t(&self, value: T) -> Mat2<T> {
BaseMat2::from_cols(self[0].mul_t(value), BaseMat2::from_cols(self.col(0).mul_t(value),
self[1].mul_t(value)) self.col(1).mul_t(value))
} }
#[inline(always)] #[inline(always)]
fn mul_v(&self, vec: &Vec2<T>) -> Vec2<T> { fn mul_v(&self, vec: &Vec2<T>) -> Vec2<T> {
BaseVec2::new(self.row(0).dot(vec), BaseVec2::new(self.row(0).dot(vec),
self.row(1).dot(vec)) self.row(1).dot(vec))
} }
#[inline(always)] #[inline(always)]
fn add_m(&self, other: &Mat2<T>) -> Mat2<T> { fn add_m(&self, other: &Mat2<T>) -> Mat2<T> {
BaseMat2::from_cols(self[0].add_v(&other[0]), BaseMat2::from_cols(self.col(0).add_v(other.col(0)),
self[1].add_v(&other[1])) self.col(1).add_v(other.col(1)))
} }
#[inline(always)] #[inline(always)]
fn sub_m(&self, other: &Mat2<T>) -> Mat2<T> { fn sub_m(&self, other: &Mat2<T>) -> Mat2<T> {
BaseMat2::from_cols(self[0].sub_v(&other[0]), BaseMat2::from_cols(self.col(0).sub_v(other.col(0)),
self[1].sub_v(&other[1])) self.col(1).sub_v(other.col(1)))
} }
#[inline(always)] #[inline(always)]
fn mul_m(&self, other: &Mat2<T>) -> Mat2<T> { fn mul_m(&self, other: &Mat2<T>) -> Mat2<T> {
BaseMat2::new(self.row(0).dot(&other.col(0)), self.row(1).dot(&other.col(0)), BaseMat2::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))) self.row(0).dot(other.col(1)), self.row(1).dot(other.col(1)))
} }
fn dot(&self, other: &Mat2<T>) -> T { fn dot(&self, other: &Mat2<T>) -> T {
@ -415,11 +416,15 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
} }
fn determinant(&self) -> T { fn determinant(&self) -> T {
self[0][0] * self[1][1] - self[1][0] * self[0][1] (*self.col(0).index(0)) *
(*self.col(1).index(1)) -
(*self.col(1).index(0)) *
(*self.col(0).index(1))
} }
fn trace(&self) -> T { fn trace(&self) -> T {
self[0][0] + self[1][1] (*self.col(0).index(0)) +
(*self.col(1).index(1))
} }
#[inline(always)] #[inline(always)]
@ -428,31 +433,26 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
if d.approx_eq(&Zero::zero()) { if d.approx_eq(&Zero::zero()) {
None None
} else { } else {
Some(BaseMat2::new( self[1][1]/d, -self[0][1]/d, Some(BaseMat2::new( self.col(1).index(1)/d, -self.col(0).index(1)/d,
-self[1][0]/d, self[0][0]/d)) -self.col(1).index(0)/d, self.col(0).index(0)/d))
} }
} }
#[inline(always)] #[inline(always)]
fn transpose(&self) -> Mat2<T> { fn transpose(&self) -> Mat2<T> {
BaseMat2::new(self[0][0], self[1][0], BaseMat2::new(*self.col(0).index(0), *self.col(1).index(0),
self[0][1], self[1][1]) *self.col(0).index(1), *self.col(1).index(1))
} }
#[inline(always)] #[inline(always)]
fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2<T> { fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2<T> {
unsafe { unsafe { &'a mut transmute::<&'a mut Mat2<T>, &'a mut [Vec2<T>,..2]>(self)[i] }
&'a mut transmute::<
&'a mut Mat2<T>,
&'a mut [Vec2<T>,..2]
>(self)[i]
}
} }
#[inline(always)] #[inline(always)]
fn swap_cols(&mut self, a: uint, b: uint) { fn swap_cols(&mut self, a: uint, b: uint) {
let tmp = self[a]; let tmp = *self.col(a);
*self.col_mut(a) = self[b]; *self.col_mut(a) = *self.col(b);
*self.col_mut(b) = tmp; *self.col_mut(b) = tmp;
} }
@ -485,14 +485,14 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn add_self_m(&mut self, other: &Mat2<T>) { fn add_self_m(&mut self, other: &Mat2<T>) {
self.x.add_self_v(&other[0]); self.x.add_self_v(other.col(0));
self.y.add_self_v(&other[1]); self.y.add_self_v(other.col(1));
} }
#[inline(always)] #[inline(always)]
fn sub_self_m(&mut self, other: &Mat2<T>) { fn sub_self_m(&mut self, other: &Mat2<T>) {
self.x.sub_self_v(&other[0]); self.x.sub_self_v(other.col(0));
self.y.sub_self_v(&other[1]); self.y.sub_self_v(other.col(1));
} }
#[inline(always)] #[inline(always)]
@ -505,11 +505,11 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn transpose_self(&mut self) { fn transpose_self(&mut self) {
let tmp01 = self[0][1]; let tmp01 = *self.col(0).index(1);
let tmp10 = self[1][0]; let tmp10 = *self.col(1).index(0);
*self.col_mut(0).index_mut(1) = self[1][0]; *self.col_mut(0).index_mut(1) = *self.col(1).index(0);
*self.col_mut(1).index_mut(0) = self[0][1]; *self.col_mut(1).index_mut(0) = *self.col(0).index(1);
*self.col_mut(1).index_mut(0) = tmp01; *self.col_mut(1).index_mut(0) = tmp01;
*self.col_mut(0).index_mut(1) = tmp10; *self.col_mut(0).index_mut(1) = tmp10;
@ -522,8 +522,8 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn is_diagonal(&self) -> bool { fn is_diagonal(&self) -> bool {
self[0][1].approx_eq(&Zero::zero()) && self.col(0).index(1).approx_eq(&Zero::zero()) &&
self[1][0].approx_eq(&Zero::zero()) self.col(1).index(0).approx_eq(&Zero::zero())
} }
#[inline(always)] #[inline(always)]
@ -533,8 +533,8 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn is_symmetric(&self) -> bool { fn is_symmetric(&self) -> bool {
self[0][1].approx_eq(&self[1][0]) && self.col(0).index(1).approx_eq(self.col(1).index(0)) &&
self[1][0].approx_eq(&self[0][1]) self.col(1).index(0).approx_eq(self.col(0).index(1))
} }
#[inline(always)] #[inline(always)]
@ -619,9 +619,9 @@ impl<T:Copy + Float + NumAssign> BaseMat2<T, Vec2<T>> for Mat2<T> {
*/ */
#[inline(always)] #[inline(always)]
fn to_mat3(&self) -> Mat3<T> { fn to_mat3(&self) -> Mat3<T> {
BaseMat3::new( self[0][0], self[0][1], Zero::zero(), BaseMat3::new(*self.col(0).index(0), *self.col(0).index(1), Zero::zero(),
self[1][0], self[1][1], Zero::zero(), *self.col(1).index(0), *self.col(1).index(1), Zero::zero(),
Zero::zero(), Zero::zero(), One::one()) Zero::zero(), Zero::zero(), One::one())
} }
/** /**
@ -641,28 +641,21 @@ impl<T:Copy + Float + NumAssign> BaseMat2<T, Vec2<T>> for Mat2<T> {
*/ */
#[inline(always)] #[inline(always)]
fn to_mat4(&self) -> Mat4<T> { fn to_mat4(&self) -> Mat4<T> {
BaseMat4::new( self[0][0], self[0][1], Zero::zero(), Zero::zero(), BaseMat4::new(*self.col(0).index(0), *self.col(0).index(1), Zero::zero(), Zero::zero(),
self[1][0], self[1][1], Zero::zero(), Zero::zero(), *self.col(1).index(0), *self.col(1).index(1), Zero::zero(), Zero::zero(),
Zero::zero(), Zero::zero(), One::one(), Zero::zero(), Zero::zero(), Zero::zero(), One::one(), Zero::zero(),
Zero::zero(), Zero::zero(), Zero::zero(), One::one()) Zero::zero(), Zero::zero(), Zero::zero(), One::one())
}
}
impl<T:Copy> Index<uint, Vec2<T>> for Mat2<T> {
#[inline(always)]
fn index(&self, i: &uint) -> Vec2<T> {
unsafe { transmute::<Mat2<T>,[Vec2<T>,..2]>(*self)[*i] }
} }
} }
impl<T:Copy + Float + NumAssign> Neg<Mat2<T>> for Mat2<T> { impl<T:Copy + Float + NumAssign> Neg<Mat2<T>> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Mat2<T> { fn neg(&self) -> Mat2<T> {
BaseMat2::from_cols(-self[0], -self[1]) BaseMat2::from_cols(-self.col(0), -self.col(1))
} }
} }
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat2<T> { impl<T:Copy + Float + NumAssign> ApproxEq<T> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn approx_epsilon() -> T { fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>() ApproxEq::approx_epsilon::<T,T>()
@ -675,8 +668,8 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat2<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Mat2<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Mat2<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.col(0).approx_eq_eps(other.col(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) self.col(1).approx_eq_eps(other.col(1), epsilon)
} }
} }
@ -698,13 +691,15 @@ pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> { impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn col(&self, i: uint) -> Vec3<T> { self[i] } fn col<'a>(&'a self, i: uint) -> &'a Vec3<T> {
unsafe { &'a transmute::<&'a Mat3<T>, &'a [Vec3<T>,..3]>(self)[i] }
}
#[inline(always)] #[inline(always)]
fn row(&self, i: uint) -> Vec3<T> { fn row(&self, i: uint) -> Vec3<T> {
BaseVec3::new(self[0][i], BaseVec3::new(*self.col(0).index(i),
self[1][i], *self.col(1).index(i),
self[2][i]) *self.col(2).index(i))
} }
/** /**
@ -774,9 +769,9 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn mul_t(&self, value: T) -> Mat3<T> { fn mul_t(&self, value: T) -> Mat3<T> {
BaseMat3::from_cols(self[0].mul_t(value), BaseMat3::from_cols(self.col(0).mul_t(value),
self[1].mul_t(value), self.col(1).mul_t(value),
self[2].mul_t(value)) self.col(2).mul_t(value))
} }
#[inline(always)] #[inline(always)]
@ -788,31 +783,31 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn add_m(&self, other: &Mat3<T>) -> Mat3<T> { fn add_m(&self, other: &Mat3<T>) -> Mat3<T> {
BaseMat3::from_cols(self[0].add_v(&other[0]), BaseMat3::from_cols(self.col(0).add_v(other.col(0)),
self[1].add_v(&other[1]), self.col(1).add_v(other.col(1)),
self[2].add_v(&other[2])) self.col(2).add_v(other.col(2)))
} }
#[inline(always)] #[inline(always)]
fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> { fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> {
BaseMat3::from_cols(self[0].sub_v(&other[0]), BaseMat3::from_cols(self.col(0).sub_v(other.col(0)),
self[1].sub_v(&other[1]), self.col(1).sub_v(other.col(1)),
self[2].sub_v(&other[2])) self.col(2).sub_v(other.col(2)))
} }
#[inline(always)] #[inline(always)]
fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> { fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> {
BaseMat3::new(self.row(0).dot(&other.col(0)), BaseMat3::new(self.row(0).dot(other.col(0)),
self.row(1).dot(&other.col(0)), self.row(1).dot(other.col(0)),
self.row(2).dot(&other.col(0)), self.row(2).dot(other.col(0)),
self.row(0).dot(&other.col(1)), self.row(0).dot(other.col(1)),
self.row(1).dot(&other.col(1)), self.row(1).dot(other.col(1)),
self.row(2).dot(&other.col(1)), self.row(2).dot(other.col(1)),
self.row(0).dot(&other.col(2)), self.row(0).dot(other.col(2)),
self.row(1).dot(&other.col(2)), self.row(1).dot(other.col(2)),
self.row(2).dot(&other.col(2))) self.row(2).dot(other.col(2)))
} }
fn dot(&self, other: &Mat3<T>) -> T { fn dot(&self, other: &Mat3<T>) -> T {
@ -820,11 +815,13 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
} }
fn determinant(&self) -> T { fn determinant(&self) -> T {
self.col(0).dot(&self.col(1).cross(&self.col(2))) self.col(0).dot(&self.col(1).cross(self.col(2)))
} }
fn trace(&self) -> T { fn trace(&self) -> T {
self[0][0] + self[1][1] + self[2][2] *self.col(0).index(0) +
*self.col(1).index(1) +
*self.col(2).index(2)
} }
// #[inline(always)] // #[inline(always)]
@ -833,34 +830,29 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
if d.approx_eq(&Zero::zero()) { if d.approx_eq(&Zero::zero()) {
None None
} else { } else {
let m: Mat3<T> = BaseMat3::from_cols(self[1].cross(&self[2]).div_t(d), let m: Mat3<T> = BaseMat3::from_cols(self.col(1).cross(self.col(2)).div_t(d),
self[2].cross(&self[0]).div_t(d), self.col(2).cross(self.col(0)).div_t(d),
self[0].cross(&self[1]).div_t(d)); self.col(0).cross(self.col(1)).div_t(d));
Some(m.transpose()) Some(m.transpose())
} }
} }
#[inline(always)] #[inline(always)]
fn transpose(&self) -> Mat3<T> { fn transpose(&self) -> Mat3<T> {
BaseMat3::new(self[0][0], self[1][0], self[2][0], BaseMat3::new(*self.col(0).index(0), *self.col(1).index(0), *self.col(2).index(0),
self[0][1], self[1][1], self[2][1], *self.col(0).index(1), *self.col(1).index(1), *self.col(2).index(1),
self[0][2], self[1][2], self[2][2]) *self.col(0).index(2), *self.col(1).index(2), *self.col(2).index(2))
} }
#[inline(always)] #[inline(always)]
fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3<T> { fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3<T> {
unsafe { unsafe { &'a mut transmute::<&'a mut Mat3<T>, &'a mut [Vec3<T>,..3]>(self)[i] }
&'a mut transmute::<
&'a mut Mat3<T>,
&'a mut [Vec3<T>,..3]
>(self)[i]
}
} }
#[inline(always)] #[inline(always)]
fn swap_cols(&mut self, a: uint, b: uint) { fn swap_cols(&mut self, a: uint, b: uint) {
let tmp = self[a]; let tmp = *self.col(a);
*self.col_mut(a) = self[b]; *self.col_mut(a) = *self.col(b);
*self.col_mut(b) = tmp; *self.col_mut(b) = tmp;
} }
@ -895,16 +887,16 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn add_self_m(&mut self, other: &Mat3<T>) { fn add_self_m(&mut self, other: &Mat3<T>) {
self.col_mut(0).add_self_v(&other[0]); self.col_mut(0).add_self_v(other.col(0));
self.col_mut(1).add_self_v(&other[1]); self.col_mut(1).add_self_v(other.col(1));
self.col_mut(2).add_self_v(&other[2]); self.col_mut(2).add_self_v(other.col(2));
} }
#[inline(always)] #[inline(always)]
fn sub_self_m(&mut self, other: &Mat3<T>) { fn sub_self_m(&mut self, other: &Mat3<T>) {
self.col_mut(0).sub_self_v(&other[0]); self.col_mut(0).sub_self_v(other.col(0));
self.col_mut(1).sub_self_v(&other[1]); self.col_mut(1).sub_self_v(other.col(1));
self.col_mut(2).sub_self_v(&other[2]); self.col_mut(2).sub_self_v(other.col(2));
} }
#[inline(always)] #[inline(always)]
@ -917,19 +909,19 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn transpose_self(&mut self) { fn transpose_self(&mut self) {
let tmp01 = self[0][1]; let tmp01 = *self.col(0).index(1);
let tmp02 = self[0][2]; let tmp02 = *self.col(0).index(2);
let tmp10 = self[1][0]; let tmp10 = *self.col(1).index(0);
let tmp12 = self[1][2]; let tmp12 = *self.col(1).index(2);
let tmp20 = self[2][0]; let tmp20 = *self.col(2).index(0);
let tmp21 = self[2][1]; let tmp21 = *self.col(2).index(1);
*self.col_mut(0).index_mut(1) = self[1][0]; *self.col_mut(0).index_mut(1) = *self.col(1).index(0);
*self.col_mut(0).index_mut(2) = self[2][0]; *self.col_mut(0).index_mut(2) = *self.col(2).index(0);
*self.col_mut(1).index_mut(0) = self[0][1]; *self.col_mut(1).index_mut(0) = *self.col(0).index(1);
*self.col_mut(1).index_mut(2) = self[2][1]; *self.col_mut(1).index_mut(2) = *self.col(2).index(1);
*self.col_mut(2).index_mut(0) = self[0][2]; *self.col_mut(2).index_mut(0) = *self.col(0).index(2);
*self.col_mut(2).index_mut(1) = self[1][2]; *self.col_mut(2).index_mut(1) = *self.col(1).index(2);
*self.col_mut(1).index_mut(0) = tmp01; *self.col_mut(1).index_mut(0) = tmp01;
*self.col_mut(2).index_mut(0) = tmp02; *self.col_mut(2).index_mut(0) = tmp02;
@ -946,14 +938,14 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn is_diagonal(&self) -> bool { fn is_diagonal(&self) -> bool {
self[0][1].approx_eq(&Zero::zero()) && self.col(0).index(1).approx_eq(&Zero::zero()) &&
self[0][2].approx_eq(&Zero::zero()) && self.col(0).index(2).approx_eq(&Zero::zero()) &&
self[1][0].approx_eq(&Zero::zero()) && self.col(1).index(0).approx_eq(&Zero::zero()) &&
self[1][2].approx_eq(&Zero::zero()) && self.col(1).index(2).approx_eq(&Zero::zero()) &&
self[2][0].approx_eq(&Zero::zero()) && self.col(2).index(0).approx_eq(&Zero::zero()) &&
self[2][1].approx_eq(&Zero::zero()) self.col(2).index(1).approx_eq(&Zero::zero())
} }
#[inline(always)] #[inline(always)]
@ -963,14 +955,14 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn is_symmetric(&self) -> bool { fn is_symmetric(&self) -> bool {
self[0][1].approx_eq(&self[1][0]) && self.col(0).index(1).approx_eq(self.col(1).index(0)) &&
self[0][2].approx_eq(&self[2][0]) && self.col(0).index(2).approx_eq(self.col(2).index(0)) &&
self[1][0].approx_eq(&self[0][1]) && self.col(1).index(0).approx_eq(self.col(0).index(1)) &&
self[1][2].approx_eq(&self[2][1]) && self.col(1).index(2).approx_eq(self.col(2).index(1)) &&
self[2][0].approx_eq(&self[0][2]) && self.col(2).index(0).approx_eq(self.col(0).index(2)) &&
self[2][1].approx_eq(&self[1][2]) self.col(2).index(1).approx_eq(self.col(1).index(2))
} }
#[inline(always)] #[inline(always)]
@ -1154,9 +1146,9 @@ impl<T:Copy + Float + NumAssign> BaseMat3<T, Vec3<T>> for Mat3<T> {
*/ */
#[inline(always)] #[inline(always)]
fn to_mat4(&self) -> Mat4<T> { fn to_mat4(&self) -> Mat4<T> {
BaseMat4::new( self[0][0], self[0][1], self[0][2], Zero::zero(), BaseMat4::new(*self.col(0).index(0), *self.col(0).index(1), *self.col(0).index(2), Zero::zero(),
self[1][0], self[1][1], self[1][2], Zero::zero(), *self.col(1).index(0), *self.col(1).index(1), *self.col(1).index(2), Zero::zero(),
self[2][0], self[2][1], self[2][2], Zero::zero(), *self.col(2).index(0), *self.col(2).index(1), *self.col(2).index(2), Zero::zero(),
Zero::zero(), Zero::zero(), Zero::zero(), One::one()) Zero::zero(), Zero::zero(), Zero::zero(), One::one())
} }
@ -1175,55 +1167,60 @@ impl<T:Copy + Float + NumAssign> BaseMat3<T, Vec3<T>> for Mat3<T> {
let _1: T = num::cast(1.0); let _1: T = num::cast(1.0);
let half: T = num::cast(0.5); let half: T = num::cast(0.5);
if trace >= Zero::zero() { cond! (
s = (_1 + trace).sqrt(); (trace >= Zero::zero()) {
w = half * s; s = (_1 + trace).sqrt();
s = half / s; w = half * s;
x = (self[1][2] - self[2][1]) * s; s = half / s;
y = (self[2][0] - self[0][2]) * s; x = (*self.col(1).index(2) - *self.col(2).index(1)) * s;
z = (self[0][1] - self[1][0]) * s; y = (*self.col(2).index(0) - *self.col(0).index(2)) * s;
} else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) { z = (*self.col(0).index(1) - *self.col(1).index(0)) * s;
s = (half + (self[0][0] - self[1][1] - self[2][2])).sqrt(); }
w = half * s; ((*self.col(0).index(0) > *self.col(1).index(1))
s = half / s; && (*self.col(0).index(0) > *self.col(2).index(2))) {
x = (self[0][1] - self[1][0]) * s; s = (half + (*self.col(0).index(0) -
y = (self[2][0] - self[0][2]) * s; *self.col(1).index(1) -
z = (self[1][2] - self[2][1]) * s; *self.col(2).index(2))).sqrt();
} else if self[1][1] > self[2][2] { w = half * s;
s = (half + (self[1][1] - self[0][0] - self[2][2])).sqrt(); s = half / s;
w = half * s; x = (*self.col(0).index(1) - *self.col(1).index(0)) * s;
s = half / s; y = (*self.col(2).index(0) - *self.col(0).index(2)) * s;
x = (self[0][1] - self[1][0]) * s; z = (*self.col(1).index(2) - *self.col(2).index(1)) * s;
y = (self[1][2] - self[2][1]) * s; }
z = (self[2][0] - self[0][2]) * s; (*self.col(1).index(1) > *self.col(2).index(2)) {
} else { s = (half + (*self.col(1).index(1) -
s = (half + (self[2][2] - self[0][0] - self[1][1])).sqrt(); *self.col(0).index(0) -
w = half * s; *self.col(2).index(2))).sqrt();
s = half / s; w = half * s;
x = (self[2][0] - self[0][2]) * s; s = half / s;
y = (self[1][2] - self[2][1]) * s; x = (*self.col(0).index(1) - *self.col(1).index(0)) * s;
z = (self[0][1] - self[1][0]) * s; y = (*self.col(1).index(2) - *self.col(2).index(1)) * s;
} z = (*self.col(2).index(0) - *self.col(0).index(2)) * s;
}
_ {
s = (half + (*self.col(2).index(2) -
*self.col(0).index(0) -
*self.col(1).index(1))).sqrt();
w = half * s;
s = half / s;
x = (*self.col(2).index(0) - *self.col(0).index(2)) * s;
y = (*self.col(1).index(2) - *self.col(2).index(1)) * s;
z = (*self.col(0).index(1) - *self.col(1).index(0)) * s;
}
)
Quat::new(w, x, y, z) Quat::new(w, x, y, z)
} }
} }
impl<T:Copy> Index<uint, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn index(&self, i: &uint) -> Vec3<T> {
unsafe { transmute::<Mat3<T>,[Vec3<T>,..3]>(*self)[*i] }
}
}
impl<T:Copy + Float + NumAssign> Neg<Mat3<T>> for Mat3<T> { impl<T:Copy + Float + NumAssign> Neg<Mat3<T>> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Mat3<T> { fn neg(&self) -> Mat3<T> {
BaseMat3::from_cols(-self[0], -self[1], -self[2]) BaseMat3::from_cols(-self.col(0), -self.col(1), -self.col(2))
} }
} }
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat3<T> { impl<T:Copy + Float + NumAssign> ApproxEq<T> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn approx_epsilon() -> T { fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>() ApproxEq::approx_epsilon::<T,T>()
@ -1236,9 +1233,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat3<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Mat3<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Mat3<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.col(0).approx_eq_eps(other.col(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) && self.col(1).approx_eq_eps(other.col(1), epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) self.col(2).approx_eq_eps(other.col(2), epsilon)
} }
} }
@ -1261,14 +1258,16 @@ pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }
impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> { impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn col(&self, i: uint) -> Vec4<T> { self[i] } fn col<'a>(&'a self, i: uint) -> &'a Vec4<T> {
unsafe { &'a transmute::<&'a Mat4<T>, &'a [Vec4<T>,..4]>(self)[i] }
}
#[inline(always)] #[inline(always)]
fn row(&self, i: uint) -> Vec4<T> { fn row(&self, i: uint) -> Vec4<T> {
BaseVec4::new(self[0][i], BaseVec4::new(*self.col(0).index(i),
self[1][i], *self.col(1).index(i),
self[2][i], *self.col(2).index(i),
self[3][i]) *self.col(3).index(i))
} }
/** /**
@ -1347,10 +1346,10 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn mul_t(&self, value: T) -> Mat4<T> { fn mul_t(&self, value: T) -> Mat4<T> {
BaseMat4::from_cols(self[0].mul_t(value), BaseMat4::from_cols(self.col(0).mul_t(value),
self[1].mul_t(value), self.col(1).mul_t(value),
self[2].mul_t(value), self.col(2).mul_t(value),
self[3].mul_t(value)) self.col(3).mul_t(value))
} }
#[inline(always)] #[inline(always)]
@ -1363,41 +1362,41 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn add_m(&self, other: &Mat4<T>) -> Mat4<T> { fn add_m(&self, other: &Mat4<T>) -> Mat4<T> {
BaseMat4::from_cols(self[0].add_v(&other[0]), BaseMat4::from_cols(self.col(0).add_v(other.col(0)),
self[1].add_v(&other[1]), self.col(1).add_v(other.col(1)),
self[2].add_v(&other[2]), self.col(2).add_v(other.col(2)),
self[3].add_v(&other[3])) self.col(3).add_v(other.col(3)))
} }
#[inline(always)] #[inline(always)]
fn sub_m(&self, other: &Mat4<T>) -> Mat4<T> { fn sub_m(&self, other: &Mat4<T>) -> Mat4<T> {
BaseMat4::from_cols(self[0].sub_v(&other[0]), BaseMat4::from_cols(self.col(0).sub_v(other.col(0)),
self[1].sub_v(&other[1]), self.col(1).sub_v(other.col(1)),
self[2].sub_v(&other[2]), self.col(2).sub_v(other.col(2)),
self[3].sub_v(&other[3])) self.col(3).sub_v(other.col(3)))
} }
#[inline(always)] #[inline(always)]
fn mul_m(&self, other: &Mat4<T>) -> Mat4<T> { fn mul_m(&self, other: &Mat4<T>) -> Mat4<T> {
BaseMat4::new(self.row(0).dot(&other.col(0)), BaseMat4::new(self.row(0).dot(other.col(0)),
self.row(1).dot(&other.col(0)), self.row(1).dot(other.col(0)),
self.row(2).dot(&other.col(0)), self.row(2).dot(other.col(0)),
self.row(3).dot(&other.col(0)), self.row(3).dot(other.col(0)),
self.row(0).dot(&other.col(1)), self.row(0).dot(other.col(1)),
self.row(1).dot(&other.col(1)), self.row(1).dot(other.col(1)),
self.row(2).dot(&other.col(1)), self.row(2).dot(other.col(1)),
self.row(3).dot(&other.col(1)), self.row(3).dot(other.col(1)),
self.row(0).dot(&other.col(2)), self.row(0).dot(other.col(2)),
self.row(1).dot(&other.col(2)), self.row(1).dot(other.col(2)),
self.row(2).dot(&other.col(2)), self.row(2).dot(other.col(2)),
self.row(3).dot(&other.col(2)), self.row(3).dot(other.col(2)),
self.row(0).dot(&other.col(3)), self.row(0).dot(other.col(3)),
self.row(1).dot(&other.col(3)), self.row(1).dot(other.col(3)),
self.row(2).dot(&other.col(3)), self.row(2).dot(other.col(3)),
self.row(3).dot(&other.col(3))) self.row(3).dot(other.col(3)))
} }
@ -1406,27 +1405,30 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
} }
fn determinant(&self) -> T { fn determinant(&self) -> T {
let m0: Mat3<T> = BaseMat3::new(self[1][1], self[2][1], self[3][1], let m0: Mat3<T> = BaseMat3::new(*self.col(1).index(1), *self.col(2).index(1), *self.col(3).index(1),
self[1][2], self[2][2], self[3][2], *self.col(1).index(2), *self.col(2).index(2), *self.col(3).index(2),
self[1][3], self[2][3], self[3][3]); *self.col(1).index(3), *self.col(2).index(3), *self.col(3).index(3));
let m1: Mat3<T> = BaseMat3::new(self[0][1], self[2][1], self[3][1], let m1: Mat3<T> = BaseMat3::new(*self.col(0).index(1), *self.col(2).index(1), *self.col(3).index(1),
self[0][2], self[2][2], self[3][2], *self.col(0).index(2), *self.col(2).index(2), *self.col(3).index(2),
self[0][3], self[2][3], self[3][3]); *self.col(0).index(3), *self.col(2).index(3), *self.col(3).index(3));
let m2: Mat3<T> = BaseMat3::new(self[0][1], self[1][1], self[3][1], let m2: Mat3<T> = BaseMat3::new(*self.col(0).index(1), *self.col(1).index(1), *self.col(3).index(1),
self[0][2], self[1][2], self[3][2], *self.col(0).index(2), *self.col(1).index(2), *self.col(3).index(2),
self[0][3], self[1][3], self[3][3]); *self.col(0).index(3), *self.col(1).index(3), *self.col(3).index(3));
let m3: Mat3<T> = BaseMat3::new(self[0][1], self[1][1], self[2][1], let m3: Mat3<T> = BaseMat3::new(*self.col(0).index(1), *self.col(1).index(1), *self.col(2).index(1),
self[0][2], self[1][2], self[2][2], *self.col(0).index(2), *self.col(1).index(2), *self.col(2).index(2),
self[0][3], self[1][3], self[2][3]); *self.col(0).index(3), *self.col(1).index(3), *self.col(2).index(3));
self[0][0] * m0.determinant() - self.col(0).index(0) * m0.determinant() -
self[1][0] * m1.determinant() + self.col(1).index(0) * m1.determinant() +
self[2][0] * m2.determinant() - self.col(2).index(0) * m2.determinant() -
self[3][0] * m3.determinant() self.col(3).index(0) * m3.determinant()
} }
fn trace(&self) -> T { fn trace(&self) -> T {
self[0][0] + self[1][1] + self[2][2] + self[3][3] *self.col(0).index(0) +
*self.col(1).index(1) +
*self.col(2).index(2) +
*self.col(3).index(3)
} }
fn inverse(&self) -> Option<Mat4<T>> { fn inverse(&self) -> Option<Mat4<T>> {
@ -1446,7 +1448,7 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
// Find largest element in col j // Find largest element in col j
let mut i1 = j; let mut i1 = j;
for uint::range(j + 1, 4) |i| { for uint::range(j + 1, 4) |i| {
if A[j][i].abs() > A[j][i1].abs() { if A.col(j).index(i).abs() > A.col(j).index(i1).abs() {
i1 = i; i1 = i;
} }
} }
@ -1457,7 +1459,7 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
I.swap_cols(i1, j); I.swap_cols(i1, j);
// Scale col j to have a unit diagonal // Scale col j to have a unit diagonal
let ajj = A[j][j]; let ajj = *A.col(j).index(j);
I.col_mut(j).div_self_t(ajj); I.col_mut(j).div_self_t(ajj);
A.col_mut(j).div_self_t(ajj); A.col_mut(j).div_self_t(ajj);
@ -1465,8 +1467,8 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
// doing identical ops to I // doing identical ops to I
for uint::range(0, 4) |i| { for uint::range(0, 4) |i| {
if i != j { if i != j {
let ij_mul_aij = I[j].mul_t(A[i][j]); let ij_mul_aij = I.col(j).mul_t(*A.col(i).index(j));
let aj_mul_aij = A[j].mul_t(A[i][j]); let aj_mul_aij = A.col(j).mul_t(*A.col(i).index(j));
I.col_mut(i).sub_self_v(&ij_mul_aij); I.col_mut(i).sub_self_v(&ij_mul_aij);
A.col_mut(i).sub_self_v(&aj_mul_aij); A.col_mut(i).sub_self_v(&aj_mul_aij);
} }
@ -1478,26 +1480,21 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn transpose(&self) -> Mat4<T> { fn transpose(&self) -> Mat4<T> {
BaseMat4::new(self[0][0], self[1][0], self[2][0], self[3][0], BaseMat4::new(*self.col(0).index(0), *self.col(1).index(0), *self.col(2).index(0), *self.col(3).index(0),
self[0][1], self[1][1], self[2][1], self[3][1], *self.col(0).index(1), *self.col(1).index(1), *self.col(2).index(1), *self.col(3).index(1),
self[0][2], self[1][2], self[2][2], self[3][2], *self.col(0).index(2), *self.col(1).index(2), *self.col(2).index(2), *self.col(3).index(2),
self[0][3], self[1][3], self[2][3], self[3][3]) *self.col(0).index(3), *self.col(1).index(3), *self.col(2).index(3), *self.col(3).index(3))
} }
#[inline(always)] #[inline(always)]
fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4<T> { fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4<T> {
unsafe { unsafe { &'a mut transmute::<&'a mut Mat4<T>, &'a mut [Vec4<T>,..4]>(self)[i] }
&'a mut transmute::<
&'a mut Mat4<T>,
&'a mut [Vec4<T>,..4]
>(self)[i]
}
} }
#[inline(always)] #[inline(always)]
fn swap_cols(&mut self, a: uint, b: uint) { fn swap_cols(&mut self, a: uint, b: uint) {
let tmp = self[a]; let tmp = *self.col(a);
*self.col_mut(a) = self[b]; *self.col_mut(a) = *self.col(b);
*self.col_mut(b) = tmp; *self.col_mut(b) = tmp;
} }
@ -1534,18 +1531,18 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn add_self_m(&mut self, other: &Mat4<T>) { fn add_self_m(&mut self, other: &Mat4<T>) {
self.col_mut(0).add_self_v(&other[0]); self.col_mut(0).add_self_v(other.col(0));
self.col_mut(1).add_self_v(&other[1]); self.col_mut(1).add_self_v(other.col(1));
self.col_mut(2).add_self_v(&other[2]); self.col_mut(2).add_self_v(other.col(2));
self.col_mut(3).add_self_v(&other[3]); self.col_mut(3).add_self_v(other.col(3));
} }
#[inline(always)] #[inline(always)]
fn sub_self_m(&mut self, other: &Mat4<T>) { fn sub_self_m(&mut self, other: &Mat4<T>) {
self.col_mut(0).sub_self_v(&other[0]); self.col_mut(0).sub_self_v(other.col(0));
self.col_mut(1).sub_self_v(&other[1]); self.col_mut(1).sub_self_v(other.col(1));
self.col_mut(2).sub_self_v(&other[2]); self.col_mut(2).sub_self_v(other.col(2));
self.col_mut(3).sub_self_v(&other[3]); self.col_mut(3).sub_self_v(other.col(3));
} }
#[inline(always)] #[inline(always)]
@ -1558,31 +1555,31 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn transpose_self(&mut self) { fn transpose_self(&mut self) {
let tmp01 = self[0][1]; let tmp01 = *self.col(0).index(1);
let tmp02 = self[0][2]; let tmp02 = *self.col(0).index(2);
let tmp03 = self[0][3]; let tmp03 = *self.col(0).index(3);
let tmp10 = self[1][0]; let tmp10 = *self.col(1).index(0);
let tmp12 = self[1][2]; let tmp12 = *self.col(1).index(2);
let tmp13 = self[1][3]; let tmp13 = *self.col(1).index(3);
let tmp20 = self[2][0]; let tmp20 = *self.col(2).index(0);
let tmp21 = self[2][1]; let tmp21 = *self.col(2).index(1);
let tmp23 = self[2][3]; let tmp23 = *self.col(2).index(3);
let tmp30 = self[3][0]; let tmp30 = *self.col(3).index(0);
let tmp31 = self[3][1]; let tmp31 = *self.col(3).index(1);
let tmp32 = self[3][2]; let tmp32 = *self.col(3).index(2);
*self.col_mut(0).index_mut(1) = self[1][0]; *self.col_mut(0).index_mut(1) = *self.col(1).index(0);
*self.col_mut(0).index_mut(2) = self[2][0]; *self.col_mut(0).index_mut(2) = *self.col(2).index(0);
*self.col_mut(0).index_mut(3) = self[3][0]; *self.col_mut(0).index_mut(3) = *self.col(3).index(0);
*self.col_mut(1).index_mut(0) = self[0][1]; *self.col_mut(1).index_mut(0) = *self.col(0).index(1);
*self.col_mut(1).index_mut(2) = self[2][1]; *self.col_mut(1).index_mut(2) = *self.col(2).index(1);
*self.col_mut(1).index_mut(3) = self[3][1]; *self.col_mut(1).index_mut(3) = *self.col(3).index(1);
*self.col_mut(2).index_mut(0) = self[0][2]; *self.col_mut(2).index_mut(0) = *self.col(0).index(2);
*self.col_mut(2).index_mut(1) = self[1][2]; *self.col_mut(2).index_mut(1) = *self.col(1).index(2);
*self.col_mut(2).index_mut(3) = self[3][2]; *self.col_mut(2).index_mut(3) = *self.col(3).index(2);
*self.col_mut(3).index_mut(0) = self[0][3]; *self.col_mut(3).index_mut(0) = *self.col(0).index(3);
*self.col_mut(3).index_mut(1) = self[1][3]; *self.col_mut(3).index_mut(1) = *self.col(1).index(3);
*self.col_mut(3).index_mut(2) = self[2][3]; *self.col_mut(3).index_mut(2) = *self.col(2).index(3);
*self.col_mut(1).index_mut(0) = tmp01; *self.col_mut(1).index_mut(0) = tmp01;
*self.col_mut(2).index_mut(0) = tmp02; *self.col_mut(2).index_mut(0) = tmp02;
@ -1605,21 +1602,21 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn is_diagonal(&self) -> bool { fn is_diagonal(&self) -> bool {
self[0][1].approx_eq(&Zero::zero()) && self.col(0).index(1).approx_eq(&Zero::zero()) &&
self[0][2].approx_eq(&Zero::zero()) && self.col(0).index(2).approx_eq(&Zero::zero()) &&
self[0][3].approx_eq(&Zero::zero()) && self.col(0).index(3).approx_eq(&Zero::zero()) &&
self[1][0].approx_eq(&Zero::zero()) && self.col(1).index(0).approx_eq(&Zero::zero()) &&
self[1][2].approx_eq(&Zero::zero()) && self.col(1).index(2).approx_eq(&Zero::zero()) &&
self[1][3].approx_eq(&Zero::zero()) && self.col(1).index(3).approx_eq(&Zero::zero()) &&
self[2][0].approx_eq(&Zero::zero()) && self.col(2).index(0).approx_eq(&Zero::zero()) &&
self[2][1].approx_eq(&Zero::zero()) && self.col(2).index(1).approx_eq(&Zero::zero()) &&
self[2][3].approx_eq(&Zero::zero()) && self.col(2).index(3).approx_eq(&Zero::zero()) &&
self[3][0].approx_eq(&Zero::zero()) && self.col(3).index(0).approx_eq(&Zero::zero()) &&
self[3][1].approx_eq(&Zero::zero()) && self.col(3).index(1).approx_eq(&Zero::zero()) &&
self[3][2].approx_eq(&Zero::zero()) self.col(3).index(2).approx_eq(&Zero::zero())
} }
#[inline(always)] #[inline(always)]
@ -1629,21 +1626,21 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn is_symmetric(&self) -> bool { fn is_symmetric(&self) -> bool {
self[0][1].approx_eq(&self[1][0]) && self.col(0).index(1).approx_eq(self.col(1).index(0)) &&
self[0][2].approx_eq(&self[2][0]) && self.col(0).index(2).approx_eq(self.col(2).index(0)) &&
self[0][3].approx_eq(&self[3][0]) && self.col(0).index(3).approx_eq(self.col(3).index(0)) &&
self[1][0].approx_eq(&self[0][1]) && self.col(1).index(0).approx_eq(self.col(0).index(1)) &&
self[1][2].approx_eq(&self[2][1]) && self.col(1).index(2).approx_eq(self.col(2).index(1)) &&
self[1][3].approx_eq(&self[3][1]) && self.col(1).index(3).approx_eq(self.col(3).index(1)) &&
self[2][0].approx_eq(&self[0][2]) && self.col(2).index(0).approx_eq(self.col(0).index(2)) &&
self[2][1].approx_eq(&self[1][2]) && self.col(2).index(1).approx_eq(self.col(1).index(2)) &&
self[2][3].approx_eq(&self[3][2]) && self.col(2).index(3).approx_eq(self.col(3).index(2)) &&
self[3][0].approx_eq(&self[0][3]) && self.col(3).index(0).approx_eq(self.col(0).index(3)) &&
self[3][1].approx_eq(&self[1][3]) && self.col(3).index(1).approx_eq(self.col(1).index(3)) &&
self[3][2].approx_eq(&self[2][3]) self.col(3).index(2).approx_eq(self.col(2).index(3))
} }
#[inline(always)] #[inline(always)]
@ -1724,18 +1721,11 @@ impl<T:Copy + Float + NumAssign> BaseMat4<T, Vec4<T>> for Mat4<T> {
impl<T:Copy + Float + NumAssign> Neg<Mat4<T>> for Mat4<T> { impl<T:Copy + Float + NumAssign> Neg<Mat4<T>> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Mat4<T> { fn neg(&self) -> Mat4<T> {
BaseMat4::from_cols(-self[0], -self[1], -self[2], -self[3]) BaseMat4::from_cols(-self.col(0), -self.col(1), -self.col(2), -self.col(3))
} }
} }
impl<T:Copy> Index<uint, Vec4<T>> for Mat4<T> { impl<T:Copy + Float + NumAssign> ApproxEq<T> for Mat4<T> {
#[inline(always)]
fn index(&self, i: &uint) -> Vec4<T> {
unsafe { transmute::<Mat4<T>,[Vec4<T>,..4]>(*self)[*i] }
}
}
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn approx_epsilon() -> T { fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>() ApproxEq::approx_epsilon::<T,T>()
@ -1748,9 +1738,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat4<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Mat4<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Mat4<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.col(0).approx_eq_eps(other.col(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) && self.col(1).approx_eq_eps(other.col(1), epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) && self.col(2).approx_eq_eps(other.col(2), epsilon) &&
self[3].approx_eq_eps(&other[3], epsilon) self.col(3).approx_eq_eps(other.col(3), epsilon)
} }
} }

View file

@ -138,6 +138,16 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
let m: Mat3<T> = BaseMat3::from_axes(x, y, z); m.to_quat() let m: Mat3<T> = BaseMat3::from_axes(x, y, z); m.to_quat()
} }
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Quat<T>, &'a [T,..4]>(self)[i] }
}
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { &'a mut transmute::< &'a mut Quat<T>, &'a mut [T,..4]>(self)[i] }
}
fn get_angle_axis(&self) -> (T, Vec3<T>) { fn get_angle_axis(&self) -> (T, Vec3<T>) {
fail!(~"Not yet implemented.") fail!(~"Not yet implemented.")
} }
@ -154,10 +164,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/ */
#[inline(always)] #[inline(always)]
fn mul_t(&self, value: T) -> Quat<T> { fn mul_t(&self, value: T) -> Quat<T> {
Quat::new(self[0] * value, Quat::new(*self.index(0) * value,
self[1] * value, *self.index(1) * value,
self[2] * value, *self.index(2) * value,
self[3] * value) *self.index(3) * value)
} }
/** /**
@ -167,10 +177,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/ */
#[inline(always)] #[inline(always)]
fn div_t(&self, value: T) -> Quat<T> { fn div_t(&self, value: T) -> Quat<T> {
Quat::new(self[0] / value, Quat::new(*self.index(0) / value,
self[1] / value, *self.index(1) / value,
self[2] / value, *self.index(2) / value,
self[3] / value) *self.index(3) / value)
} }
/** /**
@ -191,10 +201,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/ */
#[inline(always)] #[inline(always)]
fn add_q(&self, other: &Quat<T>) -> Quat<T> { fn add_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(self[0] + other[0], Quat::new(*self.index(0) + *other.index(0),
self[1] + other[1], *self.index(1) + *other.index(1),
self[2] + other[2], *self.index(2) + *other.index(2),
self[3] + other[3]) *self.index(3) + *other.index(3))
} }
/** /**
@ -204,10 +214,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/ */
#[inline(always)] #[inline(always)]
fn sub_q(&self, other: &Quat<T>) -> Quat<T> { fn sub_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(self[0] - other[0], Quat::new(*self.index(0) - *other.index(0),
self[1] - other[1], *self.index(1) - *other.index(1),
self[2] - other[2], *self.index(2) - *other.index(2),
self[3] - other[3]) *self.index(3) - *other.index(3))
} }
/** /**
@ -386,21 +396,17 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
} }
} }
impl<T:Copy> Index<uint, T> for Quat<T> {
#[inline(always)]
fn index(&self, i: &uint) -> T {
unsafe { transmute::<Quat<T>,[T,..4]>(*self)[*i] }
}
}
impl<T:Copy + Float + NumAssign> Neg<Quat<T>> for Quat<T> { impl<T:Copy + Float + NumAssign> Neg<Quat<T>> for Quat<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Quat<T> { fn neg(&self) -> Quat<T> {
Quat::new(-self[0], -self[1], -self[2], -self[3]) Quat::new(-*self.index(0),
-*self.index(1),
-*self.index(2),
-*self.index(3))
} }
} }
impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Quat<T> { impl<T:Copy + Eq + Float + NumAssign> ApproxEq<T> for Quat<T> {
#[inline(always)] #[inline(always)]
fn approx_epsilon() -> T { fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>() ApproxEq::approx_epsilon::<T,T>()
@ -413,9 +419,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Quat<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Quat<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Quat<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) && self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) && self.index(2).approx_eq_eps(other.index(2), epsilon) &&
self[3].approx_eq_eps(&other[3], epsilon) self.index(3).approx_eq_eps(other.index(3), epsilon)
} }
} }

View file

@ -1,7 +1,6 @@
use std::cast::transmute; use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use std::util;
use num::NumAssign; use num::NumAssign;
@ -13,7 +12,9 @@ use num::NumAssign;
* * `T` - The type of the components. This is intended to support boolean, * * `T` - The type of the components. This is intended to support boolean,
* integer, unsigned integer, and floating point types. * integer, unsigned integer, and floating point types.
*/ */
pub trait BaseVec<T>: Index<uint,T> + Eq { pub trait BaseVec<T>: Eq {
fn index<'a>(&'a self, i: uint) -> &'a T;
/** /**
* Construct the vector from a single value, copying it to each component * Construct the vector from a single value, copying it to each component
*/ */
@ -460,51 +461,51 @@ pub trait MixVec<T>: BaseVec<T> {
macro_rules! zip_vec2( macro_rules! zip_vec2(
($a:ident[] $method:ident $b:ident[]) => ( ($a:ident[] $method:ident $b:ident[]) => (
BaseVec2::new($a[0].$method(&($b[0])), BaseVec2::new($a.index(0).$method($b.index(0)),
$a[1].$method(&($b[1]))) $a.index(1).$method($b.index(1)))
); );
($a:ident[] $method:ident $b:ident) => ( ($a:ident[] $method:ident $b:ident) => (
BaseVec2::new($a[0].$method(&($b)), BaseVec2::new($a.index(0).$method(&$b),
$a[1].$method(&($b))) $a.index(1).$method(&$b))
); );
) )
macro_rules! zip_vec3( macro_rules! zip_vec3(
($a:ident[] $method:ident $b:ident[]) => ( ($a:ident[] $method:ident $b:ident[]) => (
BaseVec3::new($a[0].$method(&($b[0])), BaseVec3::new($a.index(0).$method($b.index(0)),
$a[1].$method(&($b[1])), $a.index(1).$method($b.index(1)),
$a[2].$method(&($b[2]))) $a.index(2).$method($b.index(2)))
); );
($a:ident[] $method:ident $b:ident) => ( ($a:ident[] $method:ident $b:ident) => (
BaseVec3::new($a[0].$method(&($b)), BaseVec3::new($a.index(0).$method(&$b),
$a[1].$method(&($b)), $a.index(1).$method(&$b),
$a[2].$method(&($b))) $a.index(2).$method(&$b))
); );
) )
macro_rules! zip_vec4( macro_rules! zip_vec4(
($a:ident[] $method:ident $b:ident[]) => ( ($a:ident[] $method:ident $b:ident[]) => (
BaseVec4::new($a[0].$method(&($b[0])), BaseVec4::new($a.index(0).$method($b.index(0)),
$a[1].$method(&($b[1])), $a.index(1).$method($b.index(1)),
$a[2].$method(&($b[2])), $a.index(2).$method($b.index(2)),
$a[3].$method(&($b[3]))) $a.index(3).$method($b.index(3)))
); );
($a:ident[] $method:ident $b:ident) => ( ($a:ident[] $method:ident $b:ident) => (
BaseVec4::new($a[0].$method(&($b)), BaseVec4::new($a.index(0).$method(&$b),
$a[1].$method(&($b)), $a.index(1).$method(&$b),
$a[2].$method(&($b)), $a.index(2).$method(&$b),
$a[3].$method(&($b))) $a.index(3).$method(&$b))
); );
) )
macro_rules! zip_assign( macro_rules! zip_assign(
($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method(&$b[0]); $a.index_mut(1).$method(&$b[1]); }); ($a:ident[] $method:ident $b:ident[] ..2) => ({ $a.index_mut(0).$method($b.index(0)); $a.index_mut(1).$method($b.index(1)); });
($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method(&$b[2]); }); ($a:ident[] $method:ident $b:ident[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method($b.index(2)); });
($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method(&$b[3]); }); ($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method($b.index(3)); });
($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method(&$b); $a.index_mut(1).$method(&$b); }); ($a:ident[] $method:ident $b:ident ..2) => ({ $a.index_mut(0).$method(&$b); $a.index_mut(1).$method(&$b); });
($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); }); ($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); });
($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method(&$b); }); ($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method(&$b); });
) )
/** /**
@ -524,6 +525,11 @@ macro_rules! zip_assign(
pub struct Vec2<T> { x: T, y: T } pub struct Vec2<T> { x: T, y: T }
impl<T:Copy + Eq> BaseVec<T> for Vec2<T> { impl<T:Copy + Eq> BaseVec<T> for Vec2<T> {
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Vec2<T>, &'a [T,..2]>(self)[i] }
}
#[inline(always)] #[inline(always)]
fn from_value(value: T) -> Vec2<T> { fn from_value(value: T) -> Vec2<T> {
BaseVec2::new(value, value) BaseVec2::new(value, value)
@ -536,18 +542,13 @@ impl<T:Copy + Eq> BaseVec<T> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { unsafe { &'a mut transmute::<&'a mut Vec2<T>, &'a mut [T,..2]>(self)[i] }
&mut transmute::<
&'a mut Vec2<T>,
&'a mut [T,..2]
>(self)[i]
}
} }
#[inline(always)] #[inline(always)]
fn swap(&mut self, a: uint, b: uint) { fn swap(&mut self, a: uint, b: uint) {
let tmp = self[a]; let tmp = *self.index(a);
*self.index_mut(a) = self[b]; *self.index_mut(a) = *self.index(b);
*self.index_mut(b) = tmp; *self.index_mut(b) = tmp;
} }
} }
@ -559,13 +560,6 @@ impl<T> BaseVec2<T> for Vec2<T> {
} }
} }
impl<T:Copy + Eq> Index<uint, T> for Vec2<T> {
#[inline(always)]
fn index(&self, i: &uint) -> T {
unsafe { transmute::<Vec2<T>,[T,..2]>(*self)[*i] }
}
}
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> { impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn identity() -> Vec2<T> { fn identity() -> Vec2<T> {
@ -581,8 +575,8 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn is_zero(&self) -> bool { fn is_zero(&self) -> bool {
self[0] == Zero::zero() && *self.index(0) == Zero::zero() &&
self[1] == Zero::zero() *self.index(1) == Zero::zero()
} }
#[inline(always)] #[inline(always)]
@ -617,14 +611,14 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn dot(&self, other: &Vec2<T>) -> T { fn dot(&self, other: &Vec2<T>) -> T {
self[0] * other[0] + (*self.index(0)) * (*other.index(0)) +
self[1] * other[1] (*self.index(1)) * (*other.index(1))
} }
#[inline(always)] #[inline(always)]
fn neg_self(&mut self) { fn neg_self(&mut self) {
*self.index_mut(0) = -self[0]; *self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self[1]; *self.index_mut(1) = -self.index(1);
} }
#[inline(always)] #[inline(always)]
@ -661,7 +655,7 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
impl<T:Copy + Num> Neg<Vec2<T>> for Vec2<T> { impl<T:Copy + Num> Neg<Vec2<T>> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Vec2<T> { fn neg(&self) -> Vec2<T> {
BaseVec2::new(-self[0], -self[1]) BaseVec2::new(-self.index(0), -self.index(1))
} }
} }
@ -680,7 +674,7 @@ impl<T:Copy + Num> NumVec2<T> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn perp_dot(&self, other: &Vec2<T>) ->T { fn perp_dot(&self, other: &Vec2<T>) ->T {
(self[0] * other[1]) - (self[1] * other[0]) (*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0))
} }
} }
@ -763,8 +757,8 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec2<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Vec2<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Vec2<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) self.index(1).approx_eq_eps(other.index(1), epsilon)
} }
} }
@ -805,17 +799,17 @@ impl<T:Copy + Eq> EqVec<T, Vec2<bool>> for Vec2<T> {
impl BoolVec for Vec2<bool> { impl BoolVec for Vec2<bool> {
#[inline(always)] #[inline(always)]
fn any(&self) -> bool { fn any(&self) -> bool {
self[0] || self[1] *self.index(0) || *self.index(1)
} }
#[inline(always)] #[inline(always)]
fn all(&self) -> bool { fn all(&self) -> bool {
self[0] && self[1] *self.index(0) && *self.index(1)
} }
#[inline(always)] #[inline(always)]
fn not(&self) -> Vec2<bool> { fn not(&self) -> Vec2<bool> {
BaseVec2::new(!self[0], !self[1]) BaseVec2::new(!*self.index(0), !*self.index(1))
} }
} }
@ -837,6 +831,11 @@ impl BoolVec for Vec2<bool> {
pub struct Vec3<T> { x: T, y: T, z: T } pub struct Vec3<T> { x: T, y: T, z: T }
impl<T:Copy + Eq> BaseVec<T> for Vec3<T> { impl<T:Copy + Eq> BaseVec<T> for Vec3<T> {
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Vec3<T>, &'a [T,..3]>(self)[i] }
}
#[inline(always)] #[inline(always)]
fn from_value(value: T) -> Vec3<T> { fn from_value(value: T) -> Vec3<T> {
BaseVec3::new(value, value, value) BaseVec3::new(value, value, value)
@ -849,18 +848,13 @@ impl<T:Copy + Eq> BaseVec<T> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { unsafe { &mut transmute::<&'a mut Vec3<T>, &'a mut [T,..3]>(self)[i] }
&mut transmute::<
&'a mut Vec3<T>,
&'a mut [T,..3]
>(self)[i]
}
} }
#[inline(always)] #[inline(always)]
fn swap(&mut self, a: uint, b: uint) { fn swap(&mut self, a: uint, b: uint) {
let tmp = self[a]; let tmp = *self.index(a);
*self.index_mut(a) = self[b]; *self.index_mut(a) = *self.index(b);
*self.index_mut(b) = tmp; *self.index_mut(b) = tmp;
} }
} }
@ -872,13 +866,6 @@ impl<T> BaseVec3<T> for Vec3<T> {
} }
} }
impl<T:Copy + Eq> Index<uint, T> for Vec3<T> {
#[inline(always)]
fn index(&self, i: &uint) -> T {
unsafe { transmute::<Vec3<T>,[T,..3]>(*self)[*i] }
}
}
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> { impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn identity() -> Vec3<T> { fn identity() -> Vec3<T> {
@ -896,9 +883,9 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn is_zero(&self) -> bool { fn is_zero(&self) -> bool {
self[0] == Zero::zero() && *self.index(0) == Zero::zero() &&
self[1] == Zero::zero() && *self.index(1) == Zero::zero() &&
self[2] == Zero::zero() *self.index(2) == Zero::zero()
} }
#[inline(always)] #[inline(always)]
@ -933,16 +920,16 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn dot(&self, other: &Vec3<T>) -> T { fn dot(&self, other: &Vec3<T>) -> T {
self[0] * other[0] + (*self.index(0)) * (*other.index(0)) +
self[1] * other[1] + (*self.index(1)) * (*other.index(1)) +
self[2] * other[2] (*self.index(2)) * (*other.index(2))
} }
#[inline(always)] #[inline(always)]
fn neg_self(&mut self) { fn neg_self(&mut self) {
*self.index_mut(0) = -self[0]; *self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self[1]; *self.index_mut(1) = -self.index(1);
*self.index_mut(2) = -self[2]; *self.index_mut(2) = -self.index(2);
} }
#[inline(always)] #[inline(always)]
@ -979,7 +966,7 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
impl<T:Copy + Num> Neg<Vec3<T>> for Vec3<T> { impl<T:Copy + Num> Neg<Vec3<T>> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Vec3<T> { fn neg(&self) -> Vec3<T> {
BaseVec3::new(-self[0], -self[1], -self[2]) BaseVec3::new(-self.index(0), -self.index(1), -self.index(2))
} }
} }
@ -1007,9 +994,9 @@ impl<T:Copy + Num> NumVec3<T> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn cross(&self, other: &Vec3<T>) -> Vec3<T> { fn cross(&self, other: &Vec3<T>) -> Vec3<T> {
BaseVec3::new((self[1] * other[2]) - (self[2] * other[1]), BaseVec3::new((*self.index(1) * *other.index(2)) - (*self.index(2) * *other.index(1)),
(self[2] * other[0]) - (self[0] * other[2]), (*self.index(2) * *other.index(0)) - (*self.index(0) * *other.index(2)),
(self[0] * other[1]) - (self[1] * other[0])) (*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0)))
} }
#[inline(always)] #[inline(always)]
@ -1097,9 +1084,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec3<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Vec3<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Vec3<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) && self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) self.index(2).approx_eq_eps(other.index(2), epsilon)
} }
} }
@ -1140,17 +1127,17 @@ impl<T:Copy + Eq> EqVec<T, Vec3<bool>> for Vec3<T> {
impl BoolVec for Vec3<bool> { impl BoolVec for Vec3<bool> {
#[inline(always)] #[inline(always)]
fn any(&self) -> bool { fn any(&self) -> bool {
self[0] || self[1] || self[2] *self.index(0) || *self.index(1) || *self.index(2)
} }
#[inline(always)] #[inline(always)]
fn all(&self) -> bool { fn all(&self) -> bool {
self[0] && self[1] && self[2] *self.index(0) && *self.index(1) && *self.index(2)
} }
#[inline(always)] #[inline(always)]
fn not(&self) -> Vec3<bool> { fn not(&self) -> Vec3<bool> {
BaseVec3::new(!self[0], !self[1], !self[2]) BaseVec3::new(!*self.index(0), !*self.index(1), !*self.index(2))
} }
} }
@ -1173,6 +1160,11 @@ impl BoolVec for Vec3<bool> {
pub struct Vec4<T> { x: T, y: T, z: T, w: T } pub struct Vec4<T> { x: T, y: T, z: T, w: T }
impl<T:Copy + Eq> BaseVec<T> for Vec4<T> { impl<T:Copy + Eq> BaseVec<T> for Vec4<T> {
#[inline(always)]
fn index<'a>(&'a self, i: uint) -> &'a T {
unsafe { &'a transmute::<&'a Vec4<T>, &'a [T,..4]>(self)[i] }
}
#[inline(always)] #[inline(always)]
fn from_value(value: T) -> Vec4<T> { fn from_value(value: T) -> Vec4<T> {
BaseVec4::new(value, value, value, value) BaseVec4::new(value, value, value, value)
@ -1185,18 +1177,13 @@ impl<T:Copy + Eq> BaseVec<T> for Vec4<T> {
#[inline(always)] #[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe { unsafe { &'a mut transmute::< &'a mut Vec4<T>, &'a mut [T,..4]>(self)[i] }
&mut transmute::<
&'a mut Vec4<T>,
&'a mut [T,..4]
>(self)[i]
}
} }
#[inline(always)] #[inline(always)]
fn swap(&mut self, a: uint, b: uint) { fn swap(&mut self, a: uint, b: uint) {
let tmp = self[a]; let tmp = *self.index(a);
*self.index_mut(a) = self[b]; *self.index_mut(a) = *self.index(b);
*self.index_mut(b) = tmp; *self.index_mut(b) = tmp;
} }
} }
@ -1208,13 +1195,6 @@ impl<T> BaseVec4<T> for Vec4<T> {
} }
} }
impl<T:Copy + Eq> Index<uint, T> for Vec4<T> {
#[inline(always)]
fn index(&self, i: &uint) -> T {
unsafe { transmute::<Vec4<T>,[T,..4]>(*self)[*i] }
}
}
impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> { impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
#[inline(always)] #[inline(always)]
fn identity() -> Vec4<T> { fn identity() -> Vec4<T> {
@ -1234,10 +1214,10 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
#[inline(always)] #[inline(always)]
fn is_zero(&self) -> bool { fn is_zero(&self) -> bool {
self[0] == Zero::zero() && *self.index(0) == Zero::zero() &&
self[1] == Zero::zero() && *self.index(1) == Zero::zero() &&
self[2] == Zero::zero() && *self.index(2) == Zero::zero() &&
self[3] == Zero::zero() *self.index(3) == Zero::zero()
} }
#[inline(always)] #[inline(always)]
@ -1272,18 +1252,18 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
#[inline(always)] #[inline(always)]
fn dot(&self, other: &Vec4<T>) -> T { fn dot(&self, other: &Vec4<T>) -> T {
self[0] * other[0] + (*self.index(0)) * (*other.index(0)) +
self[1] * other[1] + (*self.index(1)) * (*other.index(1)) +
self[2] * other[2] + (*self.index(2)) * (*other.index(2)) +
self[3] * other[3] (*self.index(3)) * (*other.index(3))
} }
#[inline(always)] #[inline(always)]
fn neg_self(&mut self) { fn neg_self(&mut self) {
*self.index_mut(0) = -self[0]; *self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self[1]; *self.index_mut(1) = -self.index(1);
*self.index_mut(2) = -self[2]; *self.index_mut(2) = -self.index(2);
*self.index_mut(3) = -self[3]; *self.index_mut(3) = -self.index(3);
} }
#[inline(always)] #[inline(always)]
@ -1320,7 +1300,7 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
impl<T:Copy + Num> Neg<Vec4<T>> for Vec4<T> { impl<T:Copy + Num> Neg<Vec4<T>> for Vec4<T> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> Vec4<T> { fn neg(&self) -> Vec4<T> {
BaseVec4::new(-self[0], -self[1], -self[2], -self[3]) BaseVec4::new(-self.index(0), -self.index(1), -self.index(2), -self.index(3))
} }
} }
@ -1430,10 +1410,10 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec4<T> {
#[inline(always)] #[inline(always)]
fn approx_eq_eps(&self, other: &Vec4<T>, epsilon: &T) -> bool { fn approx_eq_eps(&self, other: &Vec4<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) && self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) && self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) && self.index(2).approx_eq_eps(other.index(2), epsilon) &&
self[3].approx_eq_eps(&other[3], epsilon) self.index(3).approx_eq_eps(other.index(3), epsilon)
} }
} }
@ -1474,16 +1454,16 @@ impl<T:Copy + Eq> EqVec<T, Vec4<bool>> for Vec4<T> {
impl BoolVec for Vec4<bool> { impl BoolVec for Vec4<bool> {
#[inline(always)] #[inline(always)]
fn any(&self) -> bool { fn any(&self) -> bool {
self[0] || self[1] || self[2] || self[3] *self.index(0) || *self.index(1) || *self.index(2) || *self.index(3)
} }
#[inline(always)] #[inline(always)]
fn all(&self) -> bool { fn all(&self) -> bool {
self[0] && self[1] && self[2] && self[3] *self.index(0) && *self.index(1) && *self.index(2) && *self.index(3)
} }
#[inline(always)] #[inline(always)]
fn not(&self) -> Vec4<bool> { fn not(&self) -> Vec4<bool> {
BaseVec4::new(!self[0], !self[1], !self[2], !self[3]) BaseVec4::new(!*self.index(0), !*self.index(1), !*self.index(2), !*self.index(3))
} }
} }