From e630faf2393335d8f475b9be7880f395574cc493 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Fri, 31 May 2013 21:05:43 +1000 Subject: [PATCH] Remove index operator impls to prevent copying We could re-implement this once the Index trait has been improved --- src/mat.rs | 602 ++++++++++++++++++++++++++-------------------------- src/quat.rs | 64 +++--- src/vec.rs | 226 +++++++++----------- 3 files changed, 434 insertions(+), 458 deletions(-) diff --git a/src/mat.rs b/src/mat.rs index 8e894a9..dc39f84 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -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: Index + Eq + Neg { +pub trait BaseMat: Eq + Neg { /** * # 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 { x: Vec2, y: Vec2 } impl BaseMat> for Mat2 { #[inline(always)] - fn col(&self, i: uint) -> Vec2 { self[i] } + fn col<'a>(&'a self, i: uint) -> &'a Vec2 { + unsafe { &'a transmute::<&'a Mat2, &'a [Vec2,..2]>(self)[i] } + } #[inline(always)] fn row(&self, i: uint) -> Vec2 { - BaseVec2::new(self[0][i], - self[1][i]) + BaseVec2::new(*self.col(0).index(i), + *self.col(1).index(i)) } /** @@ -382,32 +383,32 @@ impl BaseMat> for Mat2 { #[inline(always)] fn mul_t(&self, value: T) -> Mat2 { - 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)] fn mul_v(&self, vec: &Vec2) -> Vec2 { BaseVec2::new(self.row(0).dot(vec), - self.row(1).dot(vec)) + self.row(1).dot(vec)) } #[inline(always)] fn add_m(&self, other: &Mat2) -> Mat2 { - 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) -> Mat2 { - 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) -> Mat2 { - 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 { @@ -415,11 +416,15 @@ impl BaseMat> for Mat2 { } 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 BaseMat> for Mat2 { 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 { - 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 { - unsafe { - &'a mut transmute::< - &'a mut Mat2, - &'a mut [Vec2,..2] - >(self)[i] - } + unsafe { &'a mut transmute::<&'a mut Mat2, &'a mut [Vec2,..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 BaseMat> for Mat2 { #[inline(always)] fn add_self_m(&mut self, other: &Mat2) { - 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) { - 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 BaseMat> for Mat2 { #[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 BaseMat> for Mat2 { #[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 BaseMat> for Mat2 { #[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,9 +619,9 @@ impl BaseMat2> for Mat2 { */ #[inline(always)] fn to_mat3(&self) -> Mat3 { - BaseMat3::new( self[0][0], self[0][1], Zero::zero(), - self[1][0], self[1][1], Zero::zero(), - Zero::zero(), Zero::zero(), One::one()) + 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 BaseMat2> for Mat2 { */ #[inline(always)] fn to_mat4(&self) -> Mat4 { - BaseMat4::new( self[0][0], self[0][1], Zero::zero(), Zero::zero(), - self[1][0], self[1][1], Zero::zero(), Zero::zero(), - Zero::zero(), Zero::zero(), One::one(), Zero::zero(), - Zero::zero(), Zero::zero(), Zero::zero(), One::one()) - } -} - -impl Index> for Mat2 { - #[inline(always)] - fn index(&self, i: &uint) -> Vec2 { - unsafe { transmute::,[Vec2,..2]>(*self)[*i] } + 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 Neg> for Mat2 { #[inline(always)] fn neg(&self) -> Mat2 { - BaseMat2::from_cols(-self[0], -self[1]) + BaseMat2::from_cols(-self.col(0), -self.col(1)) } } -impl> ApproxEq for Mat2 { +impl ApproxEq for Mat2 { #[inline(always)] fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() @@ -675,8 +668,8 @@ impl> ApproxEq for Mat2 { #[inline(always)] fn approx_eq_eps(&self, other: &Mat2, 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 { x: Vec3, y: Vec3, z: Vec3 } impl BaseMat> for Mat3 { #[inline(always)] - fn col(&self, i: uint) -> Vec3 { self[i] } + fn col<'a>(&'a self, i: uint) -> &'a Vec3 { + unsafe { &'a transmute::<&'a Mat3, &'a [Vec3,..3]>(self)[i] } + } #[inline(always)] fn row(&self, i: uint) -> Vec3 { - 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 BaseMat> for Mat3 { #[inline(always)] fn mul_t(&self, value: T) -> Mat3 { - 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 BaseMat> for Mat3 { #[inline(always)] fn add_m(&self, other: &Mat3) -> Mat3 { - 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) -> Mat3 { - 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) -> Mat3 { - 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 { @@ -820,11 +815,13 @@ impl BaseMat> for Mat3 { } 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 BaseMat> for Mat3 { if d.approx_eq(&Zero::zero()) { None } else { - let m: Mat3 = 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 = 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 { - 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 { - unsafe { - &'a mut transmute::< - &'a mut Mat3, - &'a mut [Vec3,..3] - >(self)[i] - } + unsafe { &'a mut transmute::<&'a mut Mat3, &'a mut [Vec3,..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 BaseMat> for Mat3 { #[inline(always)] fn add_self_m(&mut self, other: &Mat3) { - 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) { - 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 BaseMat> for Mat3 { #[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 BaseMat> for Mat3 { #[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 BaseMat> for Mat3 { #[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 BaseMat3> for Mat3 { */ #[inline(always)] fn to_mat4(&self) -> Mat4 { - 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 BaseMat3> for Mat3 { let _1: T = num::cast(1.0); let half: T = num::cast(0.5); - if 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; - } + cond! ( + (trace >= Zero::zero()) { + s = (_1 + trace).sqrt(); + w = half * s; + s = half / 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 Index> for Mat3 { - #[inline(always)] - fn index(&self, i: &uint) -> Vec3 { - unsafe { transmute::,[Vec3,..3]>(*self)[*i] } - } -} - impl Neg> for Mat3 { #[inline(always)] fn neg(&self) -> Mat3 { - BaseMat3::from_cols(-self[0], -self[1], -self[2]) + BaseMat3::from_cols(-self.col(0), -self.col(1), -self.col(2)) } } -impl> ApproxEq for Mat3 { +impl ApproxEq for Mat3 { #[inline(always)] fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() @@ -1236,9 +1233,9 @@ impl> ApproxEq for Mat3 { #[inline(always)] fn approx_eq_eps(&self, other: &Mat3, 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 { x: Vec4, y: Vec4, z: Vec4, w: Vec4 } impl BaseMat> for Mat4 { #[inline(always)] - fn col(&self, i: uint) -> Vec4 { self[i] } + fn col<'a>(&'a self, i: uint) -> &'a Vec4 { + unsafe { &'a transmute::<&'a Mat4, &'a [Vec4,..4]>(self)[i] } + } #[inline(always)] fn row(&self, i: uint) -> Vec4 { - 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 BaseMat> for Mat4 { #[inline(always)] fn mul_t(&self, value: T) -> Mat4 { - 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 BaseMat> for Mat4 { #[inline(always)] fn add_m(&self, other: &Mat4) -> Mat4 { - 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) -> Mat4 { - 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) -> Mat4 { - 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 BaseMat> for Mat4 { } fn determinant(&self) -> T { - let m0: Mat3 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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> { @@ -1446,7 +1448,7 @@ impl BaseMat> for Mat4 { // 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 BaseMat> for Mat4 { 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 BaseMat> for Mat4 { // 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 BaseMat> for Mat4 { #[inline(always)] fn transpose(&self) -> Mat4 { - 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 { - unsafe { - &'a mut transmute::< - &'a mut Mat4, - &'a mut [Vec4,..4] - >(self)[i] - } + unsafe { &'a mut transmute::<&'a mut Mat4, &'a mut [Vec4,..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 BaseMat> for Mat4 { #[inline(always)] fn add_self_m(&mut self, other: &Mat4) { - 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) { - 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 BaseMat> for Mat4 { #[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 BaseMat> for Mat4 { #[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 BaseMat> for Mat4 { #[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 BaseMat4> for Mat4 { impl Neg> for Mat4 { #[inline(always)] fn neg(&self) -> Mat4 { - 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 Index> for Mat4 { - #[inline(always)] - fn index(&self, i: &uint) -> Vec4 { - unsafe { transmute::,[Vec4,..4]>(*self)[*i] } - } -} - -impl> ApproxEq for Mat4 { +impl ApproxEq for Mat4 { #[inline(always)] fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() @@ -1748,9 +1738,9 @@ impl> ApproxEq for Mat4 { #[inline(always)] fn approx_eq_eps(&self, other: &Mat4, 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) } } diff --git a/src/quat.rs b/src/quat.rs index 1ded5c7..f2fa712 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -138,6 +138,16 @@ pub impl Quat { let m: Mat3 = 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, &'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, &'a mut [T,..4]>(self)[i] } + } + fn get_angle_axis(&self) -> (T, Vec3) { fail!(~"Not yet implemented.") } @@ -154,10 +164,10 @@ pub impl Quat { */ #[inline(always)] fn mul_t(&self, value: T) -> Quat { - 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 Quat { */ #[inline(always)] fn div_t(&self, value: T) -> Quat { - 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 Quat { */ #[inline(always)] fn add_q(&self, other: &Quat) -> Quat { - 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 Quat { */ #[inline(always)] fn sub_q(&self, other: &Quat) -> Quat { - 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 Quat { } } -impl Index for Quat { - #[inline(always)] - fn index(&self, i: &uint) -> T { - unsafe { transmute::,[T,..4]>(*self)[*i] } - } -} - impl Neg> for Quat { #[inline(always)] fn neg(&self) -> Quat { - 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> ApproxEq for Quat { +impl ApproxEq for Quat { #[inline(always)] fn approx_epsilon() -> T { ApproxEq::approx_epsilon::() @@ -413,9 +419,9 @@ impl> ApproxEq for Quat { #[inline(always)] fn approx_eq_eps(&self, other: &Quat, 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) } } diff --git a/src/vec.rs b/src/vec.rs index beceb56..5f89676 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -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: Index + Eq { +pub trait BaseVec: Eq { + fn index<'a>(&'a self, i: uint) -> &'a T; + /** * Construct the vector from a single value, copying it to each component */ @@ -460,51 +461,51 @@ pub trait MixVec: BaseVec { 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); }); - ($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 ..2) => ({ $a.index_mut(0).$method(&$b); $a.index_mut(1).$method(&$b); }); + ($a:ident[] $method:ident $b:ident ..3) => ({ zip_assign!($a[] $method $b ..2); $a.index_mut(2).$method(&$b); }); + ($a:ident[] $method:ident $b:ident ..4) => ({ zip_assign!($a[] $method $b ..3); $a.index_mut(3).$method(&$b); }); ) /** @@ -524,6 +525,11 @@ macro_rules! zip_assign( pub struct Vec2 { x: T, y: T } impl BaseVec for Vec2 { + #[inline(always)] + fn index<'a>(&'a self, i: uint) -> &'a T { + unsafe { &'a transmute::<&'a Vec2, &'a [T,..2]>(self)[i] } + } + #[inline(always)] fn from_value(value: T) -> Vec2 { BaseVec2::new(value, value) @@ -536,18 +542,13 @@ impl BaseVec for Vec2 { #[inline(always)] fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { - unsafe { - &mut transmute::< - &'a mut Vec2, - &'a mut [T,..2] - >(self)[i] - } + unsafe { &'a mut transmute::<&'a mut Vec2, &'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 BaseVec2 for Vec2 { } } -impl Index for Vec2 { - #[inline(always)] - fn index(&self, i: &uint) -> T { - unsafe { transmute::,[T,..2]>(*self)[*i] } - } -} - impl NumVec for Vec2 { #[inline(always)] fn identity() -> Vec2 { @@ -581,8 +575,8 @@ impl NumVec for Vec2 { #[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 NumVec for Vec2 { #[inline(always)] fn dot(&self, other: &Vec2) -> 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 NumVec for Vec2 { impl Neg> for Vec2 { #[inline(always)] fn neg(&self) -> Vec2 { - BaseVec2::new(-self[0], -self[1]) + BaseVec2::new(-self.index(0), -self.index(1)) } } @@ -680,7 +674,7 @@ impl NumVec2 for Vec2 { #[inline(always)] fn perp_dot(&self, other: &Vec2) ->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> ApproxEq for Vec2 { #[inline(always)] fn approx_eq_eps(&self, other: &Vec2, 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 EqVec> for Vec2 { impl BoolVec for Vec2 { #[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 { - BaseVec2::new(!self[0], !self[1]) + BaseVec2::new(!*self.index(0), !*self.index(1)) } } @@ -837,6 +831,11 @@ impl BoolVec for Vec2 { pub struct Vec3 { x: T, y: T, z: T } impl BaseVec for Vec3 { + #[inline(always)] + fn index<'a>(&'a self, i: uint) -> &'a T { + unsafe { &'a transmute::<&'a Vec3, &'a [T,..3]>(self)[i] } + } + #[inline(always)] fn from_value(value: T) -> Vec3 { BaseVec3::new(value, value, value) @@ -849,18 +848,13 @@ impl BaseVec for Vec3 { #[inline(always)] fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { - unsafe { - &mut transmute::< - &'a mut Vec3, - &'a mut [T,..3] - >(self)[i] - } + unsafe { &mut transmute::<&'a mut Vec3, &'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 BaseVec3 for Vec3 { } } -impl Index for Vec3 { - #[inline(always)] - fn index(&self, i: &uint) -> T { - unsafe { transmute::,[T,..3]>(*self)[*i] } - } -} - impl NumVec for Vec3 { #[inline(always)] fn identity() -> Vec3 { @@ -896,9 +883,9 @@ impl NumVec for Vec3 { #[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 NumVec for Vec3 { #[inline(always)] fn dot(&self, other: &Vec3) -> 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 NumVec for Vec3 { impl Neg> for Vec3 { #[inline(always)] fn neg(&self) -> Vec3 { - BaseVec3::new(-self[0], -self[1], -self[2]) + BaseVec3::new(-self.index(0), -self.index(1), -self.index(2)) } } @@ -1007,9 +994,9 @@ impl NumVec3 for Vec3 { #[inline(always)] fn cross(&self, other: &Vec3) -> Vec3 { - 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> ApproxEq for Vec3 { #[inline(always)] fn approx_eq_eps(&self, other: &Vec3, 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 EqVec> for Vec3 { impl BoolVec for Vec3 { #[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 { - 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 { pub struct Vec4 { x: T, y: T, z: T, w: T } impl BaseVec for Vec4 { + #[inline(always)] + fn index<'a>(&'a self, i: uint) -> &'a T { + unsafe { &'a transmute::<&'a Vec4, &'a [T,..4]>(self)[i] } + } + #[inline(always)] fn from_value(value: T) -> Vec4 { BaseVec4::new(value, value, value, value) @@ -1185,18 +1177,13 @@ impl BaseVec for Vec4 { #[inline(always)] fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T { - unsafe { - &mut transmute::< - &'a mut Vec4, - &'a mut [T,..4] - >(self)[i] - } + unsafe { &'a mut transmute::< &'a mut Vec4, &'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 BaseVec4 for Vec4 { } } -impl Index for Vec4 { - #[inline(always)] - fn index(&self, i: &uint) -> T { - unsafe { transmute::,[T,..4]>(*self)[*i] } - } -} - impl NumVec for Vec4 { #[inline(always)] fn identity() -> Vec4 { @@ -1234,10 +1214,10 @@ impl NumVec for Vec4 { #[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 NumVec for Vec4 { #[inline(always)] fn dot(&self, other: &Vec4) -> 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 NumVec for Vec4 { impl Neg> for Vec4 { #[inline(always)] fn neg(&self) -> Vec4 { - 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> ApproxEq for Vec4 { #[inline(always)] fn approx_eq_eps(&self, other: &Vec4, 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 EqVec> for Vec4 { impl BoolVec for Vec4 { #[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 { - BaseVec4::new(!self[0], !self[1], !self[2], !self[3]) + BaseVec4::new(!*self.index(0), !*self.index(1), !*self.index(2), !*self.index(3)) } }