This commit is contained in:
Brendan Zabarauskas 2012-12-10 10:32:29 +10:00
commit 1a55784c81
6 changed files with 54 additions and 68 deletions

View file

@ -69,8 +69,8 @@ pub impl<T:Copy Float> Radians<T>: Angle<T> {
pub impl<T:Copy Float> Radians<T>: Add<Radians<T>, Radians<T>> { pub impl<T:Copy Float> Radians<T>: Add<Radians<T>, Radians<T>> {
#[inline(always)] #[inline(always)]
pure fn add(rhs: &Radians<T>) -> Radians<T> { pure fn add(&self, rhs: &Radians<T>) -> Radians<T> {
Radians(*self + **rhs) Radians(**self + **rhs)
} }
} }
@ -170,8 +170,8 @@ pub impl<T:Copy Float> Degrees<T>: Angle<T> {
pub impl<T:Copy Float> Degrees<T>: Add<Degrees<T>, Degrees<T>> { pub impl<T:Copy Float> Degrees<T>: Add<Degrees<T>, Degrees<T>> {
#[inline(always)] #[inline(always)]
pure fn add(rhs: &Degrees<T>) -> Degrees<T> { pure fn add(&self, rhs: &Degrees<T>) -> Degrees<T> {
Degrees(*self + **rhs) Degrees(**self + **rhs)
} }
} }

View file

@ -267,7 +267,7 @@ pub impl<T> RGB<T>: Dimensional<T> {
pub impl<T:Copy> RGB<T>: Index<uint, T> { pub impl<T:Copy> RGB<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } }
} }
} }
@ -277,7 +277,7 @@ pub impl<T:Copy> RGB<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*RGB<T>, *T>( transmute::<*RGB<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -429,7 +429,7 @@ pub impl<T> RGBA<T>: Dimensional<T> {
pub impl<T:Copy> RGBA<T>: Index<uint, T> { pub impl<T:Copy> RGBA<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
} }
} }
@ -439,7 +439,7 @@ pub impl<T:Copy> RGBA<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*RGBA<T>, *T>( transmute::<*RGBA<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -587,7 +587,7 @@ pub impl<T> HSV<T>: Dimensional<T> {
pub impl<T:Copy> HSV<T>: Index<uint, T> { pub impl<T:Copy> HSV<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } }
} }
} }
@ -597,7 +597,7 @@ pub impl<T:Copy> HSV<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*HSV<T>, *T>( transmute::<*HSV<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -725,7 +725,7 @@ pub impl<T> HSVA<T>: Dimensional<T> {
pub impl<T:Copy> HSVA<T>: Index<uint, T> { pub impl<T:Copy> HSVA<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
} }
} }
@ -735,7 +735,7 @@ pub impl<T:Copy> HSVA<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*HSVA<T>, *T>( transmute::<*HSVA<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }

View file

@ -139,7 +139,7 @@ pub impl f32: Approx {
#[inline(always)] pure fn round(&self) -> f32 { f32::round(*self) } #[inline(always)] pure fn round(&self) -> f32 { f32::round(*self) }
// #[inline(always)] pure fn roundEven(&self) -> f32 {} // #[inline(always)] pure fn roundEven(&self) -> f32 {}
#[inline(always)] pure fn ceil(&self) -> f32 { f32::ceil(*self) } #[inline(always)] pure fn ceil(&self) -> f32 { f32::ceil(*self) }
#[inline(always)] pure fn fract(&self) -> f32 { (*self) - floor(&*self) } #[inline(always)] pure fn fract(&self) -> f32 { (*self) - floor(self) }
} }
pub impl f64: Approx { pub impl f64: Approx {
@ -148,7 +148,7 @@ pub impl f64: Approx {
#[inline(always)] pure fn round(&self) -> f64 { f64::round(*self) } #[inline(always)] pure fn round(&self) -> f64 { f64::round(*self) }
// #[inline(always)] pure fn roundEven(&self) -> f64 {} // #[inline(always)] pure fn roundEven(&self) -> f64 {}
#[inline(always)] pure fn ceil(&self) -> f64 { f64::ceil(*self) } #[inline(always)] pure fn ceil(&self) -> f64 { f64::ceil(*self) }
#[inline(always)] pure fn fract(&self) -> f64 { (*self) - floor(&*self) } #[inline(always)] pure fn fract(&self) -> f64 { (*self) - floor(self) }
} }
pub impl float: Approx { pub impl float: Approx {
@ -157,7 +157,7 @@ pub impl float: Approx {
#[inline(always)] pure fn round(&self) -> float { f64::round(*self as f64) as float } #[inline(always)] pure fn round(&self) -> float { f64::round(*self as f64) as float }
// #[inline(always)] pure fn roundEven(&self) -> float {} // #[inline(always)] pure fn roundEven(&self) -> float {}
#[inline(always)] pure fn ceil(&self) -> float { f64::ceil(*self as f64) as float } #[inline(always)] pure fn ceil(&self) -> float { f64::ceil(*self as f64) as float }
#[inline(always)] pure fn fract(&self) -> float { (*self) - floor(&*self) } #[inline(always)] pure fn fract(&self) -> float { (*self) - floor(self) }
} }

View file

@ -611,10 +611,10 @@ pub impl<T:Copy> Mat2<T>: Dimensional<Vec2<T>> {
pub impl<T:Copy> Mat2<T>: Index<uint, Vec2<T>> { pub impl<T:Copy> Mat2<T>: Index<uint, Vec2<T>> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> Vec2<T> { pure fn index(&self, i: uint) -> Vec2<T> {
unsafe { do buf_as_slice( unsafe { do buf_as_slice(
transmute::<*Mat2<T>, *Vec2<T>>( transmute::<*Mat2<T>, *Vec2<T>>(
to_unsafe_ptr(&self)), 2) |slice| { slice[i] } to_unsafe_ptr(self)), 2) |slice| { slice[i] }
} }
} }
} }
@ -624,7 +624,7 @@ pub impl<T:Copy> Mat2<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Mat2<T>, *T>( transmute::<*Mat2<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -1127,10 +1127,10 @@ pub impl<T:Copy> Mat3<T>: Dimensional<Vec3<T>> {
pub impl<T:Copy> Mat3<T>: Index<uint, Vec3<T>> { pub impl<T:Copy> Mat3<T>: Index<uint, Vec3<T>> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> Vec3<T> { pure fn index(&self, i: uint) -> Vec3<T> {
unsafe { do buf_as_slice( unsafe { do buf_as_slice(
transmute::<*Mat3<T>, *Vec3<T>>( transmute::<*Mat3<T>, *Vec3<T>>(
to_unsafe_ptr(&self)), 3) |slice| { slice[i] } to_unsafe_ptr(self)), 3) |slice| { slice[i] }
} }
} }
} }
@ -1140,7 +1140,7 @@ pub impl<T:Copy> Mat3<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Mat3<T>, *T>( transmute::<*Mat3<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -1461,7 +1461,7 @@ pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
self[0][0] + self[1][1] + self[2][2] + self[3][3] self[0][0] + self[1][1] + self[2][2] + self[3][3]
} }
pure fn inverse(&self) -> Option<Mat4<T>> { pure fn inverse(&self) -> Option<Mat4<T>> unsafe {
let d = self.determinant(); let d = self.determinant();
// let _0 = Number::from(0); // FIXME: Triggers ICE // let _0 = Number::from(0); // FIXME: Triggers ICE
let _0 = cast(0); let _0 = cast(0);
@ -1470,55 +1470,41 @@ pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
} else { } else {
// Gauss Jordan Elimination with partial pivoting // Gauss Jordan Elimination with partial pivoting
// So take this matrix, A, augmented with the identity
// and essentially reduce [A|I]
// TODO: use column/row swapping methods. Check with Luqman to see let mut A = *self;
// if the column-major layout has been used correctly // let mut I: Mat4<T> = Matrix::identity(); // FIXME: there's something wrong with static functions here!
let mut I = Mat4::identity();
let mut a = *self;
// let mut inv: Mat4<T> = Matrix::identity(); // FIXME: there's something wrong with static functions here!
let mut inv = Mat4::identity();
// Find largest pivot column j among rows j..3
for uint::range(0, 4) |j| { for uint::range(0, 4) |j| {
// Find largest element in col j
let mut i1 = j; let mut i1 = j;
for uint::range(j + 1, 4) |i| { for uint::range(j + 1, 4) |i| {
if abs(&a[i][j]) > abs(&a[i1][j]) { if abs(&A[j][i]) > abs(&A[j][i1]) {
i1 = i; i1 = i;
} }
} }
// Swap rows i1 and j in a and inv to // Swap columns i1 and j in A and I to
// put pivot on diagonal // put pivot on diagonal
let c = [mut a.x, a.y, a.z, a.w]; A.swap_cols(i1, j);
c[i1] <-> c[j]; I.swap_cols(i1, j);
a = Mat4::from_cols(c[0], c[1], c[2], c[3]);
let c = [mut inv.x, inv.y, inv.z, inv.w];
c[i1] <-> c[j];
inv = Mat4::from_cols(c[0], c[1], c[2], c[3]);
// Scale row j to have a unit diagonal // Scale col j to have a unit diagonal
let c = [mut inv.x, inv.y, inv.z, inv.w]; I.col_mut(j).div_self_t(&A[j][j]);
c[j] = c[j].div_t(a[j][j]); A.col_mut(j).div_self_t(&A[j][j]);
inv = Mat4::from_cols(c[0], c[1], c[2], c[3]);
let c = [mut a.x, a.y, a.z, a.w];
c[j] = c[j].div_t(a[j][j]);
a = Mat4::from_cols(c[0], c[1], c[2], c[3]);
// Eliminate off-diagonal elems in col j of a, // Eliminate off-diagonal elems in col j of A,
// doing identical ops to inv // doing identical ops to I
for uint::range(0, 4) |i| { for uint::range(0, 4) |i| {
if i != j { if i != j {
let c = [mut inv.x, inv.y, inv.z, inv.w]; I.col_mut(i).sub_self_v(&I[j].mul_t(A[i][j]));
c[i] = c[i].sub_v(&c[j].mul_t(a[i][j])); A.col_mut(i).sub_self_v(&A[j].mul_t(A[i][j]));
inv = Mat4::from_cols(c[0], c[1], c[2], c[3]);
let c = [mut a.x, a.y, a.z, a.w];
c[i] = c[i].sub_v(&c[j].mul_t(a[i][j]));
a = Mat4::from_cols(c[0], c[1], c[2], c[3]);
} }
} }
} }
Some(inv) Some(I)
} }
} }
@ -1701,10 +1687,10 @@ pub impl<T> Mat4<T>: Dimensional<Vec4<T>> {
pub impl<T:Copy> Mat4<T>: Index<uint, Vec4<T>> { pub impl<T:Copy> Mat4<T>: Index<uint, Vec4<T>> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> Vec4<T> { pure fn index(&self, i: uint) -> Vec4<T> {
unsafe { do buf_as_slice( unsafe { do buf_as_slice(
transmute::<*Mat4<T>, *Vec4<T>>( transmute::<*Mat4<T>, *Vec4<T>>(
to_unsafe_ptr(&self)), 4) |slice| { slice[i] } to_unsafe_ptr(self)), 4) |slice| { slice[i] }
} }
} }
} }
@ -1714,7 +1700,7 @@ pub impl<T:Copy> Mat4<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Mat4<T>, *T>( transmute::<*Mat4<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }

View file

@ -244,7 +244,7 @@ pub impl<T> Quat<T>: Dimensional<T> {
pub impl<T:Copy> Quat<T>: Index<uint, T> { pub impl<T:Copy> Quat<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
} }
} }
@ -254,7 +254,7 @@ pub impl<T:Copy> Quat<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Quat<T>, *T>( transmute::<*Quat<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }

View file

@ -313,7 +313,7 @@ pub impl<T> Vec2<T>: Dimensional<T> {
pub impl<T:Copy> Vec2<T>: Index<uint, T> { pub impl<T:Copy> Vec2<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 2) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 2) |slice| { slice[i] } }
} }
} }
@ -323,7 +323,7 @@ pub impl<T:Copy> Vec2<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Vec2<T>, *T>( transmute::<*Vec2<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -542,7 +542,7 @@ pub impl<T> Vec3<T>: Dimensional<T> {
pub impl<T:Copy> Vec3<T>: Index<uint, T> { pub impl<T:Copy> Vec3<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } }
} }
} }
@ -552,7 +552,7 @@ pub impl<T:Copy> Vec3<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Vec3<T>, *T>( transmute::<*Vec3<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }
@ -803,7 +803,7 @@ pub impl<T> Vec4<T>: Dimensional<T> {
pub impl<T:Copy> Vec4<T>: Index<uint, T> { pub impl<T:Copy> Vec4<T>: Index<uint, T> {
#[inline(always)] #[inline(always)]
pure fn index(i: uint) -> T { pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } } unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
} }
} }
@ -813,7 +813,7 @@ pub impl<T:Copy> Vec4<T>: ToPtr<T> {
pure fn to_ptr(&self) -> *T { pure fn to_ptr(&self) -> *T {
unsafe { unsafe {
transmute::<*Vec4<T>, *T>( transmute::<*Vec4<T>, *T>(
to_unsafe_ptr(&*self) to_unsafe_ptr(self)
) )
} }
} }