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::cmp::ApproxEq;
use std::num::{Zero, One};
use std::util;
use vec::*;
use quat::Quat;
@ -18,13 +17,13 @@ use num::NumAssign;
* floating point type and have the same number of dimensions as the
* 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
*
* The column vector at `i`
*/
fn col(&self, i: uint) -> V;
fn col<'a>(&'a self, i: uint) -> &'a V;
/**
* # 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> {
#[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)]
fn row(&self, i: uint) -> Vec2<T> {
BaseVec2::new(self[0][i],
self[1][i])
BaseVec2::new(*self.col(0).index(i),
*self.col(1).index(i))
}
/**
@ -382,8 +383,8 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)]
fn mul_t(&self, value: T) -> Mat2<T> {
BaseMat2::from_cols(self[0].mul_t(value),
self[1].mul_t(value))
BaseMat2::from_cols(self.col(0).mul_t(value),
self.col(1).mul_t(value))
}
#[inline(always)]
@ -394,20 +395,20 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)]
fn add_m(&self, other: &Mat2<T>) -> Mat2<T> {
BaseMat2::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]))
BaseMat2::from_cols(self.col(0).add_v(other.col(0)),
self.col(1).add_v(other.col(1)))
}
#[inline(always)]
fn sub_m(&self, other: &Mat2<T>) -> Mat2<T> {
BaseMat2::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]))
BaseMat2::from_cols(self.col(0).sub_v(other.col(0)),
self.col(1).sub_v(other.col(1)))
}
#[inline(always)]
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)),
self.row(0).dot(&other.col(1)), self.row(1).dot(&other.col(1)))
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)))
}
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 {
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 {
self[0][0] + self[1][1]
(*self.col(0).index(0)) +
(*self.col(1).index(1))
}
#[inline(always)]
@ -428,31 +433,26 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
if d.approx_eq(&Zero::zero()) {
None
} else {
Some(BaseMat2::new( self[1][1]/d, -self[0][1]/d,
-self[1][0]/d, self[0][0]/d))
Some(BaseMat2::new( self.col(1).index(1)/d, -self.col(0).index(1)/d,
-self.col(1).index(0)/d, self.col(0).index(0)/d))
}
}
#[inline(always)]
fn transpose(&self) -> Mat2<T> {
BaseMat2::new(self[0][0], self[1][0],
self[0][1], self[1][1])
BaseMat2::new(*self.col(0).index(0), *self.col(1).index(0),
*self.col(0).index(1), *self.col(1).index(1))
}
#[inline(always)]
fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2<T> {
unsafe {
&'a mut transmute::<
&'a mut Mat2<T>,
&'a mut [Vec2<T>,..2]
>(self)[i]
}
unsafe { &'a mut transmute::<&'a mut Mat2<T>, &'a mut [Vec2<T>,..2]>(self)[i] }
}
#[inline(always)]
fn swap_cols(&mut self, a: uint, b: uint) {
let tmp = self[a];
*self.col_mut(a) = self[b];
let tmp = *self.col(a);
*self.col_mut(a) = *self.col(b);
*self.col_mut(b) = tmp;
}
@ -485,14 +485,14 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)]
fn add_self_m(&mut self, other: &Mat2<T>) {
self.x.add_self_v(&other[0]);
self.y.add_self_v(&other[1]);
self.x.add_self_v(other.col(0));
self.y.add_self_v(other.col(1));
}
#[inline(always)]
fn sub_self_m(&mut self, other: &Mat2<T>) {
self.x.sub_self_v(&other[0]);
self.y.sub_self_v(&other[1]);
self.x.sub_self_v(other.col(0));
self.y.sub_self_v(other.col(1));
}
#[inline(always)]
@ -505,11 +505,11 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)]
fn transpose_self(&mut self) {
let tmp01 = self[0][1];
let tmp10 = self[1][0];
let tmp01 = *self.col(0).index(1);
let tmp10 = *self.col(1).index(0);
*self.col_mut(0).index_mut(1) = self[1][0];
*self.col_mut(1).index_mut(0) = self[0][1];
*self.col_mut(0).index_mut(1) = *self.col(1).index(0);
*self.col_mut(1).index_mut(0) = *self.col(0).index(1);
*self.col_mut(1).index_mut(0) = tmp01;
*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)]
fn is_diagonal(&self) -> bool {
self[0][1].approx_eq(&Zero::zero()) &&
self[1][0].approx_eq(&Zero::zero())
self.col(0).index(1).approx_eq(&Zero::zero()) &&
self.col(1).index(0).approx_eq(&Zero::zero())
}
#[inline(always)]
@ -533,8 +533,8 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec2<T>> for Mat2<T> {
#[inline(always)]
fn is_symmetric(&self) -> bool {
self[0][1].approx_eq(&self[1][0]) &&
self[1][0].approx_eq(&self[0][1])
self.col(0).index(1).approx_eq(self.col(1).index(0)) &&
self.col(1).index(0).approx_eq(self.col(0).index(1))
}
#[inline(always)]
@ -619,8 +619,8 @@ impl<T:Copy + Float + NumAssign> BaseMat2<T, Vec2<T>> for Mat2<T> {
*/
#[inline(always)]
fn to_mat3(&self) -> Mat3<T> {
BaseMat3::new( self[0][0], self[0][1], Zero::zero(),
self[1][0], self[1][1], Zero::zero(),
BaseMat3::new(*self.col(0).index(0), *self.col(0).index(1), Zero::zero(),
*self.col(1).index(0), *self.col(1).index(1), Zero::zero(),
Zero::zero(), Zero::zero(), One::one())
}
@ -641,28 +641,21 @@ impl<T:Copy + Float + NumAssign> BaseMat2<T, Vec2<T>> for Mat2<T> {
*/
#[inline(always)]
fn to_mat4(&self) -> Mat4<T> {
BaseMat4::new( self[0][0], self[0][1], Zero::zero(), Zero::zero(),
self[1][0], self[1][1], Zero::zero(), Zero::zero(),
BaseMat4::new(*self.col(0).index(0), *self.col(0).index(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(), 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> {
#[inline(always)]
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)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
@ -675,8 +668,8 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat2<T> {
#[inline(always)]
fn approx_eq_eps(&self, other: &Mat2<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon)
self.col(0).approx_eq_eps(other.col(0), 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> {
#[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)]
fn row(&self, i: uint) -> Vec3<T> {
BaseVec3::new(self[0][i],
self[1][i],
self[2][i])
BaseVec3::new(*self.col(0).index(i),
*self.col(1).index(i),
*self.col(2).index(i))
}
/**
@ -774,9 +769,9 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn mul_t(&self, value: T) -> Mat3<T> {
BaseMat3::from_cols(self[0].mul_t(value),
self[1].mul_t(value),
self[2].mul_t(value))
BaseMat3::from_cols(self.col(0).mul_t(value),
self.col(1).mul_t(value),
self.col(2).mul_t(value))
}
#[inline(always)]
@ -788,31 +783,31 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn add_m(&self, other: &Mat3<T>) -> Mat3<T> {
BaseMat3::from_cols(self[0].add_v(&other[0]),
self[1].add_v(&other[1]),
self[2].add_v(&other[2]))
BaseMat3::from_cols(self.col(0).add_v(other.col(0)),
self.col(1).add_v(other.col(1)),
self.col(2).add_v(other.col(2)))
}
#[inline(always)]
fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> {
BaseMat3::from_cols(self[0].sub_v(&other[0]),
self[1].sub_v(&other[1]),
self[2].sub_v(&other[2]))
BaseMat3::from_cols(self.col(0).sub_v(other.col(0)),
self.col(1).sub_v(other.col(1)),
self.col(2).sub_v(other.col(2)))
}
#[inline(always)]
fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> {
BaseMat3::new(self.row(0).dot(&other.col(0)),
self.row(1).dot(&other.col(0)),
self.row(2).dot(&other.col(0)),
BaseMat3::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(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)))
self.row(0).dot(other.col(2)),
self.row(1).dot(other.col(2)),
self.row(2).dot(other.col(2)))
}
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 {
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 {
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)]
@ -833,34 +830,29 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
if d.approx_eq(&Zero::zero()) {
None
} else {
let m: Mat3<T> = BaseMat3::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));
let m: Mat3<T> = BaseMat3::from_cols(self.col(1).cross(self.col(2)).div_t(d),
self.col(2).cross(self.col(0)).div_t(d),
self.col(0).cross(self.col(1)).div_t(d));
Some(m.transpose())
}
}
#[inline(always)]
fn transpose(&self) -> Mat3<T> {
BaseMat3::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])
BaseMat3::new(*self.col(0).index(0), *self.col(1).index(0), *self.col(2).index(0),
*self.col(0).index(1), *self.col(1).index(1), *self.col(2).index(1),
*self.col(0).index(2), *self.col(1).index(2), *self.col(2).index(2))
}
#[inline(always)]
fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3<T> {
unsafe {
&'a mut transmute::<
&'a mut Mat3<T>,
&'a mut [Vec3<T>,..3]
>(self)[i]
}
unsafe { &'a mut transmute::<&'a mut Mat3<T>, &'a mut [Vec3<T>,..3]>(self)[i] }
}
#[inline(always)]
fn swap_cols(&mut self, a: uint, b: uint) {
let tmp = self[a];
*self.col_mut(a) = self[b];
let tmp = *self.col(a);
*self.col_mut(a) = *self.col(b);
*self.col_mut(b) = tmp;
}
@ -895,16 +887,16 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn add_self_m(&mut self, other: &Mat3<T>) {
self.col_mut(0).add_self_v(&other[0]);
self.col_mut(1).add_self_v(&other[1]);
self.col_mut(2).add_self_v(&other[2]);
self.col_mut(0).add_self_v(other.col(0));
self.col_mut(1).add_self_v(other.col(1));
self.col_mut(2).add_self_v(other.col(2));
}
#[inline(always)]
fn sub_self_m(&mut self, other: &Mat3<T>) {
self.col_mut(0).sub_self_v(&other[0]);
self.col_mut(1).sub_self_v(&other[1]);
self.col_mut(2).sub_self_v(&other[2]);
self.col_mut(0).sub_self_v(other.col(0));
self.col_mut(1).sub_self_v(other.col(1));
self.col_mut(2).sub_self_v(other.col(2));
}
#[inline(always)]
@ -917,19 +909,19 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn transpose_self(&mut self) {
let tmp01 = self[0][1];
let tmp02 = self[0][2];
let tmp10 = self[1][0];
let tmp12 = self[1][2];
let tmp20 = self[2][0];
let tmp21 = self[2][1];
let tmp01 = *self.col(0).index(1);
let tmp02 = *self.col(0).index(2);
let tmp10 = *self.col(1).index(0);
let tmp12 = *self.col(1).index(2);
let tmp20 = *self.col(2).index(0);
let tmp21 = *self.col(2).index(1);
*self.col_mut(0).index_mut(1) = self[1][0];
*self.col_mut(0).index_mut(2) = self[2][0];
*self.col_mut(1).index_mut(0) = self[0][1];
*self.col_mut(1).index_mut(2) = self[2][1];
*self.col_mut(2).index_mut(0) = self[0][2];
*self.col_mut(2).index_mut(1) = self[1][2];
*self.col_mut(0).index_mut(1) = *self.col(1).index(0);
*self.col_mut(0).index_mut(2) = *self.col(2).index(0);
*self.col_mut(1).index_mut(0) = *self.col(0).index(1);
*self.col_mut(1).index_mut(2) = *self.col(2).index(1);
*self.col_mut(2).index_mut(0) = *self.col(0).index(2);
*self.col_mut(2).index_mut(1) = *self.col(1).index(2);
*self.col_mut(1).index_mut(0) = tmp01;
*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)]
fn is_diagonal(&self) -> bool {
self[0][1].approx_eq(&Zero::zero()) &&
self[0][2].approx_eq(&Zero::zero()) &&
self.col(0).index(1).approx_eq(&Zero::zero()) &&
self.col(0).index(2).approx_eq(&Zero::zero()) &&
self[1][0].approx_eq(&Zero::zero()) &&
self[1][2].approx_eq(&Zero::zero()) &&
self.col(1).index(0).approx_eq(&Zero::zero()) &&
self.col(1).index(2).approx_eq(&Zero::zero()) &&
self[2][0].approx_eq(&Zero::zero()) &&
self[2][1].approx_eq(&Zero::zero())
self.col(2).index(0).approx_eq(&Zero::zero()) &&
self.col(2).index(1).approx_eq(&Zero::zero())
}
#[inline(always)]
@ -963,14 +955,14 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec3<T>> for Mat3<T> {
#[inline(always)]
fn is_symmetric(&self) -> bool {
self[0][1].approx_eq(&self[1][0]) &&
self[0][2].approx_eq(&self[2][0]) &&
self.col(0).index(1).approx_eq(self.col(1).index(0)) &&
self.col(0).index(2).approx_eq(self.col(2).index(0)) &&
self[1][0].approx_eq(&self[0][1]) &&
self[1][2].approx_eq(&self[2][1]) &&
self.col(1).index(0).approx_eq(self.col(0).index(1)) &&
self.col(1).index(2).approx_eq(self.col(2).index(1)) &&
self[2][0].approx_eq(&self[0][2]) &&
self[2][1].approx_eq(&self[1][2])
self.col(2).index(0).approx_eq(self.col(0).index(2)) &&
self.col(2).index(1).approx_eq(self.col(1).index(2))
}
#[inline(always)]
@ -1154,9 +1146,9 @@ impl<T:Copy + Float + NumAssign> BaseMat3<T, Vec3<T>> for Mat3<T> {
*/
#[inline(always)]
fn to_mat4(&self) -> Mat4<T> {
BaseMat4::new( self[0][0], self[0][1], self[0][2], Zero::zero(),
self[1][0], self[1][1], self[1][2], Zero::zero(),
self[2][0], self[2][1], self[2][2], Zero::zero(),
BaseMat4::new(*self.col(0).index(0), *self.col(0).index(1), *self.col(0).index(2), Zero::zero(),
*self.col(1).index(0), *self.col(1).index(1), *self.col(1).index(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())
}
@ -1175,55 +1167,60 @@ impl<T:Copy + Float + NumAssign> BaseMat3<T, Vec3<T>> for Mat3<T> {
let _1: T = num::cast(1.0);
let half: T = num::cast(0.5);
if trace >= Zero::zero() {
cond! (
(trace >= Zero::zero()) {
s = (_1 + trace).sqrt();
w = half * s;
s = half / s;
x = (self[1][2] - self[2][1]) * s;
y = (self[2][0] - self[0][2]) * s;
z = (self[0][1] - self[1][0]) * s;
} else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) {
s = (half + (self[0][0] - self[1][1] - self[2][2])).sqrt();
w = half * s;
s = half / s;
x = (self[0][1] - self[1][0]) * s;
y = (self[2][0] - self[0][2]) * s;
z = (self[1][2] - self[2][1]) * s;
} else if self[1][1] > self[2][2] {
s = (half + (self[1][1] - self[0][0] - self[2][2])).sqrt();
w = half * s;
s = half / s;
x = (self[0][1] - self[1][0]) * s;
y = (self[1][2] - self[2][1]) * s;
z = (self[2][0] - self[0][2]) * s;
} else {
s = (half + (self[2][2] - self[0][0] - self[1][1])).sqrt();
w = half * s;
s = half / s;
x = (self[2][0] - self[0][2]) * s;
y = (self[1][2] - self[2][1]) * s;
z = (self[0][1] - self[1][0]) * s;
x = (*self.col(1).index(2) - *self.col(2).index(1)) * s;
y = (*self.col(2).index(0) - *self.col(0).index(2)) * s;
z = (*self.col(0).index(1) - *self.col(1).index(0)) * s;
}
((*self.col(0).index(0) > *self.col(1).index(1))
&& (*self.col(0).index(0) > *self.col(2).index(2))) {
s = (half + (*self.col(0).index(0) -
*self.col(1).index(1) -
*self.col(2).index(2))).sqrt();
w = half * s;
s = half / s;
x = (*self.col(0).index(1) - *self.col(1).index(0)) * s;
y = (*self.col(2).index(0) - *self.col(0).index(2)) * s;
z = (*self.col(1).index(2) - *self.col(2).index(1)) * s;
}
(*self.col(1).index(1) > *self.col(2).index(2)) {
s = (half + (*self.col(1).index(1) -
*self.col(0).index(0) -
*self.col(2).index(2))).sqrt();
w = half * s;
s = half / s;
x = (*self.col(0).index(1) - *self.col(1).index(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)
}
}
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> {
#[inline(always)]
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)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
@ -1236,9 +1233,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat3<T> {
#[inline(always)]
fn approx_eq_eps(&self, other: &Mat3<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon)
self.col(0).approx_eq_eps(other.col(0), epsilon) &&
self.col(1).approx_eq_eps(other.col(1), 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> {
#[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)]
fn row(&self, i: uint) -> Vec4<T> {
BaseVec4::new(self[0][i],
self[1][i],
self[2][i],
self[3][i])
BaseVec4::new(*self.col(0).index(i),
*self.col(1).index(i),
*self.col(2).index(i),
*self.col(3).index(i))
}
/**
@ -1347,10 +1346,10 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)]
fn mul_t(&self, value: T) -> Mat4<T> {
BaseMat4::from_cols(self[0].mul_t(value),
self[1].mul_t(value),
self[2].mul_t(value),
self[3].mul_t(value))
BaseMat4::from_cols(self.col(0).mul_t(value),
self.col(1).mul_t(value),
self.col(2).mul_t(value),
self.col(3).mul_t(value))
}
#[inline(always)]
@ -1363,41 +1362,41 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)]
fn add_m(&self, other: &Mat4<T>) -> Mat4<T> {
BaseMat4::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]))
BaseMat4::from_cols(self.col(0).add_v(other.col(0)),
self.col(1).add_v(other.col(1)),
self.col(2).add_v(other.col(2)),
self.col(3).add_v(other.col(3)))
}
#[inline(always)]
fn sub_m(&self, other: &Mat4<T>) -> Mat4<T> {
BaseMat4::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]))
BaseMat4::from_cols(self.col(0).sub_v(other.col(0)),
self.col(1).sub_v(other.col(1)),
self.col(2).sub_v(other.col(2)),
self.col(3).sub_v(other.col(3)))
}
#[inline(always)]
fn mul_m(&self, other: &Mat4<T>) -> Mat4<T> {
BaseMat4::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)),
BaseMat4::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)))
}
@ -1406,27 +1405,30 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
}
fn determinant(&self) -> T {
let m0: Mat3<T> = BaseMat3::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> = BaseMat3::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> = BaseMat3::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> = BaseMat3::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]);
let m0: Mat3<T> = BaseMat3::new(*self.col(1).index(1), *self.col(2).index(1), *self.col(3).index(1),
*self.col(1).index(2), *self.col(2).index(2), *self.col(3).index(2),
*self.col(1).index(3), *self.col(2).index(3), *self.col(3).index(3));
let m1: Mat3<T> = BaseMat3::new(*self.col(0).index(1), *self.col(2).index(1), *self.col(3).index(1),
*self.col(0).index(2), *self.col(2).index(2), *self.col(3).index(2),
*self.col(0).index(3), *self.col(2).index(3), *self.col(3).index(3));
let m2: Mat3<T> = BaseMat3::new(*self.col(0).index(1), *self.col(1).index(1), *self.col(3).index(1),
*self.col(0).index(2), *self.col(1).index(2), *self.col(3).index(2),
*self.col(0).index(3), *self.col(1).index(3), *self.col(3).index(3));
let m3: Mat3<T> = BaseMat3::new(*self.col(0).index(1), *self.col(1).index(1), *self.col(2).index(1),
*self.col(0).index(2), *self.col(1).index(2), *self.col(2).index(2),
*self.col(0).index(3), *self.col(1).index(3), *self.col(2).index(3));
self[0][0] * m0.determinant() -
self[1][0] * m1.determinant() +
self[2][0] * m2.determinant() -
self[3][0] * m3.determinant()
self.col(0).index(0) * m0.determinant() -
self.col(1).index(0) * m1.determinant() +
self.col(2).index(0) * m2.determinant() -
self.col(3).index(0) * m3.determinant()
}
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>> {
@ -1446,7 +1448,7 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
// Find largest element in col j
let mut i1 = j;
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;
}
}
@ -1457,7 +1459,7 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
I.swap_cols(i1, j);
// 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);
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
for uint::range(0, 4) |i| {
if i != j {
let ij_mul_aij = I[j].mul_t(A[i][j]);
let aj_mul_aij = A[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.col(j).mul_t(*A.col(i).index(j));
I.col_mut(i).sub_self_v(&ij_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)]
fn transpose(&self) -> Mat4<T> {
BaseMat4::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])
BaseMat4::new(*self.col(0).index(0), *self.col(1).index(0), *self.col(2).index(0), *self.col(3).index(0),
*self.col(0).index(1), *self.col(1).index(1), *self.col(2).index(1), *self.col(3).index(1),
*self.col(0).index(2), *self.col(1).index(2), *self.col(2).index(2), *self.col(3).index(2),
*self.col(0).index(3), *self.col(1).index(3), *self.col(2).index(3), *self.col(3).index(3))
}
#[inline(always)]
fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4<T> {
unsafe {
&'a mut transmute::<
&'a mut Mat4<T>,
&'a mut [Vec4<T>,..4]
>(self)[i]
}
unsafe { &'a mut transmute::<&'a mut Mat4<T>, &'a mut [Vec4<T>,..4]>(self)[i] }
}
#[inline(always)]
fn swap_cols(&mut self, a: uint, b: uint) {
let tmp = self[a];
*self.col_mut(a) = self[b];
let tmp = *self.col(a);
*self.col_mut(a) = *self.col(b);
*self.col_mut(b) = tmp;
}
@ -1534,18 +1531,18 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)]
fn add_self_m(&mut self, other: &Mat4<T>) {
self.col_mut(0).add_self_v(&other[0]);
self.col_mut(1).add_self_v(&other[1]);
self.col_mut(2).add_self_v(&other[2]);
self.col_mut(3).add_self_v(&other[3]);
self.col_mut(0).add_self_v(other.col(0));
self.col_mut(1).add_self_v(other.col(1));
self.col_mut(2).add_self_v(other.col(2));
self.col_mut(3).add_self_v(other.col(3));
}
#[inline(always)]
fn sub_self_m(&mut self, other: &Mat4<T>) {
self.col_mut(0).sub_self_v(&other[0]);
self.col_mut(1).sub_self_v(&other[1]);
self.col_mut(2).sub_self_v(&other[2]);
self.col_mut(3).sub_self_v(&other[3]);
self.col_mut(0).sub_self_v(other.col(0));
self.col_mut(1).sub_self_v(other.col(1));
self.col_mut(2).sub_self_v(other.col(2));
self.col_mut(3).sub_self_v(other.col(3));
}
#[inline(always)]
@ -1558,31 +1555,31 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)]
fn transpose_self(&mut self) {
let tmp01 = self[0][1];
let tmp02 = self[0][2];
let tmp03 = self[0][3];
let tmp10 = self[1][0];
let tmp12 = self[1][2];
let tmp13 = self[1][3];
let tmp20 = self[2][0];
let tmp21 = self[2][1];
let tmp23 = self[2][3];
let tmp30 = self[3][0];
let tmp31 = self[3][1];
let tmp32 = self[3][2];
let tmp01 = *self.col(0).index(1);
let tmp02 = *self.col(0).index(2);
let tmp03 = *self.col(0).index(3);
let tmp10 = *self.col(1).index(0);
let tmp12 = *self.col(1).index(2);
let tmp13 = *self.col(1).index(3);
let tmp20 = *self.col(2).index(0);
let tmp21 = *self.col(2).index(1);
let tmp23 = *self.col(2).index(3);
let tmp30 = *self.col(3).index(0);
let tmp31 = *self.col(3).index(1);
let tmp32 = *self.col(3).index(2);
*self.col_mut(0).index_mut(1) = self[1][0];
*self.col_mut(0).index_mut(2) = self[2][0];
*self.col_mut(0).index_mut(3) = self[3][0];
*self.col_mut(1).index_mut(0) = self[0][1];
*self.col_mut(1).index_mut(2) = self[2][1];
*self.col_mut(1).index_mut(3) = self[3][1];
*self.col_mut(2).index_mut(0) = self[0][2];
*self.col_mut(2).index_mut(1) = self[1][2];
*self.col_mut(2).index_mut(3) = self[3][2];
*self.col_mut(3).index_mut(0) = self[0][3];
*self.col_mut(3).index_mut(1) = self[1][3];
*self.col_mut(3).index_mut(2) = self[2][3];
*self.col_mut(0).index_mut(1) = *self.col(1).index(0);
*self.col_mut(0).index_mut(2) = *self.col(2).index(0);
*self.col_mut(0).index_mut(3) = *self.col(3).index(0);
*self.col_mut(1).index_mut(0) = *self.col(0).index(1);
*self.col_mut(1).index_mut(2) = *self.col(2).index(1);
*self.col_mut(1).index_mut(3) = *self.col(3).index(1);
*self.col_mut(2).index_mut(0) = *self.col(0).index(2);
*self.col_mut(2).index_mut(1) = *self.col(1).index(2);
*self.col_mut(2).index_mut(3) = *self.col(3).index(2);
*self.col_mut(3).index_mut(0) = *self.col(0).index(3);
*self.col_mut(3).index_mut(1) = *self.col(1).index(3);
*self.col_mut(3).index_mut(2) = *self.col(2).index(3);
*self.col_mut(1).index_mut(0) = tmp01;
*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)]
fn is_diagonal(&self) -> bool {
self[0][1].approx_eq(&Zero::zero()) &&
self[0][2].approx_eq(&Zero::zero()) &&
self[0][3].approx_eq(&Zero::zero()) &&
self.col(0).index(1).approx_eq(&Zero::zero()) &&
self.col(0).index(2).approx_eq(&Zero::zero()) &&
self.col(0).index(3).approx_eq(&Zero::zero()) &&
self[1][0].approx_eq(&Zero::zero()) &&
self[1][2].approx_eq(&Zero::zero()) &&
self[1][3].approx_eq(&Zero::zero()) &&
self.col(1).index(0).approx_eq(&Zero::zero()) &&
self.col(1).index(2).approx_eq(&Zero::zero()) &&
self.col(1).index(3).approx_eq(&Zero::zero()) &&
self[2][0].approx_eq(&Zero::zero()) &&
self[2][1].approx_eq(&Zero::zero()) &&
self[2][3].approx_eq(&Zero::zero()) &&
self.col(2).index(0).approx_eq(&Zero::zero()) &&
self.col(2).index(1).approx_eq(&Zero::zero()) &&
self.col(2).index(3).approx_eq(&Zero::zero()) &&
self[3][0].approx_eq(&Zero::zero()) &&
self[3][1].approx_eq(&Zero::zero()) &&
self[3][2].approx_eq(&Zero::zero())
self.col(3).index(0).approx_eq(&Zero::zero()) &&
self.col(3).index(1).approx_eq(&Zero::zero()) &&
self.col(3).index(2).approx_eq(&Zero::zero())
}
#[inline(always)]
@ -1629,21 +1626,21 @@ impl<T:Copy + Float + NumAssign> BaseMat<T, Vec4<T>> for Mat4<T> {
#[inline(always)]
fn is_symmetric(&self) -> bool {
self[0][1].approx_eq(&self[1][0]) &&
self[0][2].approx_eq(&self[2][0]) &&
self[0][3].approx_eq(&self[3][0]) &&
self.col(0).index(1).approx_eq(self.col(1).index(0)) &&
self.col(0).index(2).approx_eq(self.col(2).index(0)) &&
self.col(0).index(3).approx_eq(self.col(3).index(0)) &&
self[1][0].approx_eq(&self[0][1]) &&
self[1][2].approx_eq(&self[2][1]) &&
self[1][3].approx_eq(&self[3][1]) &&
self.col(1).index(0).approx_eq(self.col(0).index(1)) &&
self.col(1).index(2).approx_eq(self.col(2).index(1)) &&
self.col(1).index(3).approx_eq(self.col(3).index(1)) &&
self[2][0].approx_eq(&self[0][2]) &&
self[2][1].approx_eq(&self[1][2]) &&
self[2][3].approx_eq(&self[3][2]) &&
self.col(2).index(0).approx_eq(self.col(0).index(2)) &&
self.col(2).index(1).approx_eq(self.col(1).index(2)) &&
self.col(2).index(3).approx_eq(self.col(3).index(2)) &&
self[3][0].approx_eq(&self[0][3]) &&
self[3][1].approx_eq(&self[1][3]) &&
self[3][2].approx_eq(&self[2][3])
self.col(3).index(0).approx_eq(self.col(0).index(3)) &&
self.col(3).index(1).approx_eq(self.col(1).index(3)) &&
self.col(3).index(2).approx_eq(self.col(2).index(3))
}
#[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> {
#[inline(always)]
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> {
#[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> {
impl<T:Copy + Float + NumAssign> ApproxEq<T> for Mat4<T> {
#[inline(always)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
@ -1748,9 +1738,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Mat4<T> {
#[inline(always)]
fn approx_eq_eps(&self, other: &Mat4<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) &&
self[3].approx_eq_eps(&other[3], epsilon)
self.col(0).approx_eq_eps(other.col(0), epsilon) &&
self.col(1).approx_eq_eps(other.col(1), epsilon) &&
self.col(2).approx_eq_eps(other.col(2), 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()
}
#[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>) {
fail!(~"Not yet implemented.")
}
@ -154,10 +164,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/
#[inline(always)]
fn mul_t(&self, value: T) -> Quat<T> {
Quat::new(self[0] * value,
self[1] * value,
self[2] * value,
self[3] * value)
Quat::new(*self.index(0) * value,
*self.index(1) * value,
*self.index(2) * value,
*self.index(3) * value)
}
/**
@ -167,10 +177,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/
#[inline(always)]
fn div_t(&self, value: T) -> Quat<T> {
Quat::new(self[0] / value,
self[1] / value,
self[2] / value,
self[3] / value)
Quat::new(*self.index(0) / value,
*self.index(1) / value,
*self.index(2) / value,
*self.index(3) / value)
}
/**
@ -191,10 +201,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/
#[inline(always)]
fn add_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(self[0] + other[0],
self[1] + other[1],
self[2] + other[2],
self[3] + other[3])
Quat::new(*self.index(0) + *other.index(0),
*self.index(1) + *other.index(1),
*self.index(2) + *other.index(2),
*self.index(3) + *other.index(3))
}
/**
@ -204,10 +214,10 @@ pub impl<T:Copy + Float + NumAssign> Quat<T> {
*/
#[inline(always)]
fn sub_q(&self, other: &Quat<T>) -> Quat<T> {
Quat::new(self[0] - other[0],
self[1] - other[1],
self[2] - other[2],
self[3] - other[3])
Quat::new(*self.index(0) - *other.index(0),
*self.index(1) - *other.index(1),
*self.index(2) - *other.index(2),
*self.index(3) - *other.index(3))
}
/**
@ -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> {
#[inline(always)]
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)]
fn approx_epsilon() -> T {
ApproxEq::approx_epsilon::<T,T>()
@ -413,9 +419,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Quat<T> {
#[inline(always)]
fn approx_eq_eps(&self, other: &Quat<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) &&
self[3].approx_eq_eps(&other[3], epsilon)
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self.index(2).approx_eq_eps(other.index(2), epsilon) &&
self.index(3).approx_eq_eps(other.index(3), epsilon)
}
}

View file

@ -1,7 +1,6 @@
use std::cast::transmute;
use std::cmp::ApproxEq;
use std::num::{Zero, One};
use std::util;
use num::NumAssign;
@ -13,7 +12,9 @@ use num::NumAssign;
* * `T` - The type of the components. This is intended to support boolean,
* 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
*/
@ -460,47 +461,47 @@ pub trait MixVec<T>: BaseVec<T> {
macro_rules! zip_vec2(
($a:ident[] $method:ident $b:ident[]) => (
BaseVec2::new($a[0].$method(&($b[0])),
$a[1].$method(&($b[1])))
BaseVec2::new($a.index(0).$method($b.index(0)),
$a.index(1).$method($b.index(1)))
);
($a:ident[] $method:ident $b:ident) => (
BaseVec2::new($a[0].$method(&($b)),
$a[1].$method(&($b)))
BaseVec2::new($a.index(0).$method(&$b),
$a.index(1).$method(&$b))
);
)
macro_rules! zip_vec3(
($a:ident[] $method:ident $b:ident[]) => (
BaseVec3::new($a[0].$method(&($b[0])),
$a[1].$method(&($b[1])),
$a[2].$method(&($b[2])))
BaseVec3::new($a.index(0).$method($b.index(0)),
$a.index(1).$method($b.index(1)),
$a.index(2).$method($b.index(2)))
);
($a:ident[] $method:ident $b:ident) => (
BaseVec3::new($a[0].$method(&($b)),
$a[1].$method(&($b)),
$a[2].$method(&($b)))
BaseVec3::new($a.index(0).$method(&$b),
$a.index(1).$method(&$b),
$a.index(2).$method(&$b))
);
)
macro_rules! zip_vec4(
($a:ident[] $method:ident $b:ident[]) => (
BaseVec4::new($a[0].$method(&($b[0])),
$a[1].$method(&($b[1])),
$a[2].$method(&($b[2])),
$a[3].$method(&($b[3])))
BaseVec4::new($a.index(0).$method($b.index(0)),
$a.index(1).$method($b.index(1)),
$a.index(2).$method($b.index(2)),
$a.index(3).$method($b.index(3)))
);
($a:ident[] $method:ident $b:ident) => (
BaseVec4::new($a[0].$method(&($b)),
$a[1].$method(&($b)),
$a[2].$method(&($b)),
$a[3].$method(&($b)))
BaseVec4::new($a.index(0).$method(&$b),
$a.index(1).$method(&$b),
$a.index(2).$method(&$b),
$a.index(3).$method(&$b))
);
)
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[] ..3) => ({ zip_assign!($a[] $method $b[] ..2); $a.index_mut(2).$method(&$b[2]); });
($a:ident[] $method:ident $b:ident[] ..4) => ({ zip_assign!($a[] $method $b[] ..3); $a.index_mut(3).$method(&$b[3]); });
($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.index(2)); });
($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 ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); });
@ -524,6 +525,11 @@ macro_rules! zip_assign(
pub struct Vec2<T> { x: T, y: 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)]
fn from_value(value: T) -> Vec2<T> {
BaseVec2::new(value, value)
@ -536,18 +542,13 @@ impl<T:Copy + Eq> BaseVec<T> for Vec2<T> {
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe {
&mut transmute::<
&'a mut Vec2<T>,
&'a mut [T,..2]
>(self)[i]
}
unsafe { &'a mut transmute::<&'a mut Vec2<T>, &'a mut [T,..2]>(self)[i] }
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
let tmp = self[a];
*self.index_mut(a) = self[b];
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
*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> {
#[inline(always)]
fn identity() -> Vec2<T> {
@ -581,8 +575,8 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
#[inline(always)]
fn is_zero(&self) -> bool {
self[0] == Zero::zero() &&
self[1] == Zero::zero()
*self.index(0) == Zero::zero() &&
*self.index(1) == Zero::zero()
}
#[inline(always)]
@ -617,14 +611,14 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec2<T> {
#[inline(always)]
fn dot(&self, other: &Vec2<T>) -> T {
self[0] * other[0] +
self[1] * other[1]
(*self.index(0)) * (*other.index(0)) +
(*self.index(1)) * (*other.index(1))
}
#[inline(always)]
fn neg_self(&mut self) {
*self.index_mut(0) = -self[0];
*self.index_mut(1) = -self[1];
*self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self.index(1);
}
#[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> {
#[inline(always)]
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)]
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)]
fn approx_eq_eps(&self, other: &Vec2<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon)
self.index(0).approx_eq_eps(other.index(0), 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> {
#[inline(always)]
fn any(&self) -> bool {
self[0] || self[1]
*self.index(0) || *self.index(1)
}
#[inline(always)]
fn all(&self) -> bool {
self[0] && self[1]
*self.index(0) && *self.index(1)
}
#[inline(always)]
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 }
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)]
fn from_value(value: T) -> Vec3<T> {
BaseVec3::new(value, value, value)
@ -849,18 +848,13 @@ impl<T:Copy + Eq> BaseVec<T> for Vec3<T> {
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe {
&mut transmute::<
&'a mut Vec3<T>,
&'a mut [T,..3]
>(self)[i]
}
unsafe { &mut transmute::<&'a mut Vec3<T>, &'a mut [T,..3]>(self)[i] }
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
let tmp = self[a];
*self.index_mut(a) = self[b];
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
*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> {
#[inline(always)]
fn identity() -> Vec3<T> {
@ -896,9 +883,9 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
#[inline(always)]
fn is_zero(&self) -> bool {
self[0] == Zero::zero() &&
self[1] == Zero::zero() &&
self[2] == Zero::zero()
*self.index(0) == Zero::zero() &&
*self.index(1) == Zero::zero() &&
*self.index(2) == Zero::zero()
}
#[inline(always)]
@ -933,16 +920,16 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec3<T> {
#[inline(always)]
fn dot(&self, other: &Vec3<T>) -> T {
self[0] * other[0] +
self[1] * other[1] +
self[2] * other[2]
(*self.index(0)) * (*other.index(0)) +
(*self.index(1)) * (*other.index(1)) +
(*self.index(2)) * (*other.index(2))
}
#[inline(always)]
fn neg_self(&mut self) {
*self.index_mut(0) = -self[0];
*self.index_mut(1) = -self[1];
*self.index_mut(2) = -self[2];
*self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self.index(1);
*self.index_mut(2) = -self.index(2);
}
#[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> {
#[inline(always)]
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)]
fn cross(&self, other: &Vec3<T>) -> Vec3<T> {
BaseVec3::new((self[1] * other[2]) - (self[2] * other[1]),
(self[2] * other[0]) - (self[0] * other[2]),
(self[0] * other[1]) - (self[1] * other[0]))
BaseVec3::new((*self.index(1) * *other.index(2)) - (*self.index(2) * *other.index(1)),
(*self.index(2) * *other.index(0)) - (*self.index(0) * *other.index(2)),
(*self.index(0) * *other.index(1)) - (*self.index(1) * *other.index(0)))
}
#[inline(always)]
@ -1097,9 +1084,9 @@ impl<T:Copy + Eq + ApproxEq<T>> ApproxEq<T> for Vec3<T> {
#[inline(always)]
fn approx_eq_eps(&self, other: &Vec3<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon)
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self.index(2).approx_eq_eps(other.index(2), epsilon)
}
}
@ -1140,17 +1127,17 @@ impl<T:Copy + Eq> EqVec<T, Vec3<bool>> for Vec3<T> {
impl BoolVec for Vec3<bool> {
#[inline(always)]
fn any(&self) -> bool {
self[0] || self[1] || self[2]
*self.index(0) || *self.index(1) || *self.index(2)
}
#[inline(always)]
fn all(&self) -> bool {
self[0] && self[1] && self[2]
*self.index(0) && *self.index(1) && *self.index(2)
}
#[inline(always)]
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 }
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)]
fn from_value(value: T) -> Vec4<T> {
BaseVec4::new(value, value, value, value)
@ -1185,18 +1177,13 @@ impl<T:Copy + Eq> BaseVec<T> for Vec4<T> {
#[inline(always)]
fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
unsafe {
&mut transmute::<
&'a mut Vec4<T>,
&'a mut [T,..4]
>(self)[i]
}
unsafe { &'a mut transmute::< &'a mut Vec4<T>, &'a mut [T,..4]>(self)[i] }
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
let tmp = self[a];
*self.index_mut(a) = self[b];
let tmp = *self.index(a);
*self.index_mut(a) = *self.index(b);
*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> {
#[inline(always)]
fn identity() -> Vec4<T> {
@ -1234,10 +1214,10 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
#[inline(always)]
fn is_zero(&self) -> bool {
self[0] == Zero::zero() &&
self[1] == Zero::zero() &&
self[2] == Zero::zero() &&
self[3] == Zero::zero()
*self.index(0) == Zero::zero() &&
*self.index(1) == Zero::zero() &&
*self.index(2) == Zero::zero() &&
*self.index(3) == Zero::zero()
}
#[inline(always)]
@ -1272,18 +1252,18 @@ impl<T:Copy + Num + NumAssign> NumVec<T> for Vec4<T> {
#[inline(always)]
fn dot(&self, other: &Vec4<T>) -> T {
self[0] * other[0] +
self[1] * other[1] +
self[2] * other[2] +
self[3] * other[3]
(*self.index(0)) * (*other.index(0)) +
(*self.index(1)) * (*other.index(1)) +
(*self.index(2)) * (*other.index(2)) +
(*self.index(3)) * (*other.index(3))
}
#[inline(always)]
fn neg_self(&mut self) {
*self.index_mut(0) = -self[0];
*self.index_mut(1) = -self[1];
*self.index_mut(2) = -self[2];
*self.index_mut(3) = -self[3];
*self.index_mut(0) = -self.index(0);
*self.index_mut(1) = -self.index(1);
*self.index_mut(2) = -self.index(2);
*self.index_mut(3) = -self.index(3);
}
#[inline(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> {
#[inline(always)]
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)]
fn approx_eq_eps(&self, other: &Vec4<T>, epsilon: &T) -> bool {
self[0].approx_eq_eps(&other[0], epsilon) &&
self[1].approx_eq_eps(&other[1], epsilon) &&
self[2].approx_eq_eps(&other[2], epsilon) &&
self[3].approx_eq_eps(&other[3], epsilon)
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
self.index(2).approx_eq_eps(other.index(2), epsilon) &&
self.index(3).approx_eq_eps(other.index(3), epsilon)
}
}
@ -1474,16 +1454,16 @@ impl<T:Copy + Eq> EqVec<T, Vec4<bool>> for Vec4<T> {
impl BoolVec for Vec4<bool> {
#[inline(always)]
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)]
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)]
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))
}
}