diff --git a/src/core/core.rs b/src/core/core.rs index b414d81..a16c45f 100644 --- a/src/core/core.rs +++ b/src/core/core.rs @@ -15,6 +15,7 @@ //! Core datatypes and conversion traits for 3D mathematics +pub use self::mat::{Mat, NumMat, FloatMat}; pub use self::mat::{Mat2, ToMat2}; pub use self::mat::{Mat3, ToMat3}; pub use self::mat::{Mat4, ToMat4}; diff --git a/src/core/mat.rs b/src/core/mat.rs index f147da0..ef3150d 100644 --- a/src/core/mat.rs +++ b/src/core/mat.rs @@ -17,93 +17,43 @@ use core::{Dimensional, Swap}; use core::{Quat, ToQuat}; use core::{Vec2, Vec3, Vec4}; -macro_rules! impl_mat( - ($Mat:ident, $Vec:ident) => ( - impl $Mat { - #[inline] - pub fn col<'a>(&'a self, i: uint) -> &'a $Vec { - self.index(i) - } - - #[inline] - pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut $Vec { - self.index_mut(i) - } - - #[inline] - pub fn elem<'a>(&'a self, col: uint, row: uint) -> &'a T { - self.index(col).index(row) - } - - #[inline] - pub fn elem_mut<'a>(&'a mut self, col: uint, row: uint) -> &'a mut T { - self.index_mut(col).index_mut(row) - } - } - ) -) - -macro_rules! impl_mat_swap( - ($Mat:ident, $Vec:ident) => ( - impl $Mat { - #[inline] - pub fn swap_cols(&mut self, a: uint, b: uint) { - let tmp = self.col(a).clone(); - *self.col_mut(a) = self.col(b).clone(); - *self.col_mut(b) = tmp; - } - - #[inline] - pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), (col_b, row_b): (uint, uint)) { - let tmp = self.elem(col_a, row_a).clone(); - *self.elem_mut(col_a, row_a) = self.elem(col_b, row_b).clone(); - *self.elem_mut(col_b, row_b) = tmp; - } - } - ) -) - -impl Mat2 { - #[inline] pub fn transpose(&self) -> Mat2 { - Mat2::new(self.elem(0, 0).clone(), self.elem(1, 0).clone(), - self.elem(0, 1).clone(), self.elem(1, 1).clone()) - } - - #[inline] pub fn transpose_self(&mut self) { - self.swap_elem((0, 1), (1, 0)); - } +pub trait Mat: Dimensional + Swap { + pub fn col<'a>(&'a self, i: uint) -> &'a Vec; + pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec; + pub fn elem<'a>(&'a self, col: uint, row: uint) -> &'a T; + pub fn elem_mut<'a>(&'a mut self, col: uint, row: uint) -> &'a mut T; + pub fn swap_cols(&mut self, a: uint, b: uint); + pub fn row(&self, i: uint) -> Vec; + pub fn swap_rows(&mut self, a: uint, b: uint); + pub fn swap_elem(&mut self, a: (uint, uint), b: (uint, uint)); + pub fn transpose(&self) -> Self; + pub fn transpose_self(&mut self); } -impl Mat3 { - #[inline] pub fn transpose(&self) -> Mat3 { - Mat3::new(self.elem(0, 0).clone(), self.elem(1, 0).clone(), self.elem(2, 0).clone(), - self.elem(0, 1).clone(), self.elem(1, 1).clone(), self.elem(2, 1).clone(), - self.elem(0, 2).clone(), self.elem(1, 2).clone(), self.elem(2, 2).clone()) - } - - #[inline] pub fn transpose_self(&mut self) { - self.swap_elem((0, 1), (1, 0)); - self.swap_elem((0, 2), (2, 0)); - self.swap_elem((1, 2), (2, 1)); - } +pub trait NumMat: Mat + Neg { + pub fn mul_t(&self, value: T) -> Self; + pub fn mul_v(&self, vec: &Vec) -> Vec; + pub fn add_m(&self, other: &Self) -> Self; + pub fn sub_m(&self, other: &Self) -> Self; + pub fn mul_m(&self, other: &Self) -> Self; + pub fn mul_self_t(&mut self, value: T); + pub fn add_self_m(&mut self, other: &Self); + pub fn sub_self_m(&mut self, other: &Self); + pub fn dot(&self, other: &Self) -> T; + pub fn determinant(&self) -> T; + pub fn trace(&self) -> T; + pub fn to_identity(&mut self); + pub fn to_zero(&mut self); } -impl Mat4 { - #[inline] pub fn transpose(&self) -> Mat4 { - Mat4::new(self.elem(0, 0).clone(), self.elem(1, 0).clone(), self.elem(2, 0).clone(), self.elem(3, 0).clone(), - self.elem(0, 1).clone(), self.elem(1, 1).clone(), self.elem(2, 1).clone(), self.elem(3, 1).clone(), - self.elem(0, 2).clone(), self.elem(1, 2).clone(), self.elem(2, 2).clone(), self.elem(3, 2).clone(), - self.elem(0, 3).clone(), self.elem(1, 3).clone(), self.elem(2, 3).clone(), self.elem(3, 3).clone()) - } - - #[inline] pub fn transpose_self(&mut self) { - self.swap_elem((0, 1), (1, 0)); - self.swap_elem((0, 2), (2, 0)); - self.swap_elem((0, 3), (3, 0)); - self.swap_elem((1, 2), (2, 1)); - self.swap_elem((1, 3), (3, 1)); - self.swap_elem((2, 3), (3, 2)); - } +pub trait FloatMat: NumMat { + pub fn inverse(&self) -> Option; + pub fn invert_self(&mut self); + pub fn is_identity(&self) -> bool; + pub fn is_diagonal(&self) -> bool; + pub fn is_rotated(&self) -> bool; + pub fn is_symmetric(&self) -> bool; + pub fn is_invertible(&self) -> bool; } #[deriving(Clone, Eq)] @@ -121,8 +71,6 @@ pub type Mat2f = Mat2; pub type Mat2f32 = Mat2; pub type Mat2f64 = Mat2; -impl_mat!(Mat2, Vec2) -impl_mat_swap!(Mat2, Vec2) impl_dimensional!(Mat2, Vec2, 2) impl_approx!(Mat3 { x, y, z }) @@ -145,7 +93,34 @@ impl Mat2 { } } -impl Mat2 { +impl Mat,[Vec2,..2]> for Mat2 { + #[inline] + pub fn col<'a>(&'a self, i: uint) -> &'a Vec2 { + self.index(i) + } + + #[inline] + pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2 { + self.index_mut(i) + } + + #[inline] + pub fn elem<'a>(&'a self, col: uint, row: uint) -> &'a T { + self.index(col).index(row) + } + + #[inline] + pub fn elem_mut<'a>(&'a mut self, col: uint, row: uint) -> &'a mut T { + self.index_mut(col).index_mut(row) + } + + #[inline] + pub fn swap_cols(&mut self, a: uint, b: uint) { + let tmp = self.col(a).clone(); + *self.col_mut(a) = self.col(b).clone(); + *self.col_mut(b) = tmp; + } + #[inline] pub fn row(&self, i: uint) -> Vec2 { Vec2::new(self.col(0).index(i).clone(), @@ -157,6 +132,28 @@ impl Mat2 { self.col_mut(0).swap(a, b); self.col_mut(1).swap(a, b); } + + #[inline] + pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), + (col_b, row_b): (uint, uint)) { + let tmp = self.elem(col_a, row_a).clone(); + *self.elem_mut(col_a, row_a) = self.elem(col_b, row_b).clone(); + *self.elem_mut(col_b, row_b) = tmp; + } + + #[inline] + pub fn transpose(&self) -> Mat2 { + Mat2::new(self.elem(0, 0).clone(), + self.elem(1, 0).clone(), + + self.elem(0, 1).clone(), + self.elem(1, 1).clone()) + } + + #[inline] + pub fn transpose_self(&mut self) { + self.swap_elem((0, 1), (1, 0)); + } } impl ToMat3 for Mat2 { @@ -190,7 +187,9 @@ impl Mat2 { #[inline] pub fn zero() -> Mat2 { Mat2::from_value(zero!(T)) } +} +impl NumMat,[Vec2,..2]> for Mat2 { #[inline] pub fn mul_t(&self, value: T) -> Mat2 { Mat2::from_cols(self.col(0).mul_t(value.clone()), @@ -284,7 +283,7 @@ impl Mat2 { } } -impl> Mat2 { +impl FloatMat,[Vec3,..3]> for Mat2 { #[inline] pub fn inverse(&self) -> Option> { let d = self.determinant(); @@ -533,8 +532,6 @@ pub type Mat3f = Mat3; pub type Mat3f32 = Mat3; pub type Mat3f64 = Mat3; -impl_mat!(Mat3, Vec3) -impl_mat_swap!(Mat3, Vec3) impl_dimensional!(Mat3, Vec3, 3) impl_approx!(Mat2 { x, y }) @@ -560,7 +557,34 @@ impl Mat3 { } } -impl Mat3 { +impl Mat,[Vec3,..3]> for Mat3 { + #[inline] + pub fn col<'a>(&'a self, i: uint) -> &'a Vec3 { + self.index(i) + } + + #[inline] + pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3 { + self.index_mut(i) + } + + #[inline] + pub fn elem<'a>(&'a self, col: uint, row: uint) -> &'a T { + self.index(col).index(row) + } + + #[inline] + pub fn elem_mut<'a>(&'a mut self, col: uint, row: uint) -> &'a mut T { + self.index_mut(col).index_mut(row) + } + + #[inline] + pub fn swap_cols(&mut self, a: uint, b: uint) { + let tmp = self.col(a).clone(); + *self.col_mut(a) = self.col(b).clone(); + *self.col_mut(b) = tmp; + } + #[inline] pub fn row(&self, i: uint) -> Vec3 { Vec3::new(self.col(0).index(i).clone(), @@ -574,6 +598,36 @@ impl Mat3 { self.col_mut(1).swap(a, b); self.col_mut(2).swap(a, b); } + + #[inline] + pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), + (col_b, row_b): (uint, uint)) { + let tmp = self.elem(col_a, row_a).clone(); + *self.elem_mut(col_a, row_a) = self.elem(col_b, row_b).clone(); + *self.elem_mut(col_b, row_b) = tmp; + } + + #[inline] + pub fn transpose(&self) -> Mat3 { + Mat3::new(self.elem(0, 0).clone(), + self.elem(1, 0).clone(), + self.elem(2, 0).clone(), + + self.elem(0, 1).clone(), + self.elem(1, 1).clone(), + self.elem(2, 1).clone(), + + self.elem(0, 2).clone(), + self.elem(1, 2).clone(), + self.elem(2, 2).clone()) + } + + #[inline] + pub fn transpose_self(&mut self) { + self.swap_elem((0, 1), (1, 0)); + self.swap_elem((0, 2), (2, 0)); + self.swap_elem((1, 2), (2, 1)); + } } impl ToMat4 for Mat3 { @@ -599,7 +653,9 @@ impl Mat3 { #[inline] pub fn zero() -> Mat3 { Mat3::from_value(zero!(T)) } +} +impl NumMat,[Vec3,..3]> for Mat3 { #[inline] pub fn mul_t(&self, value: T) -> Mat3 { Mat3::from_cols(self.col(0).mul_t(value.clone()), @@ -834,7 +890,7 @@ impl ToQuat for Mat3 { } } -impl> Mat3 { +impl FloatMat,[Vec4,..4]> for Mat3 { #[inline] pub fn inverse(&self) -> Option> { let d = self.determinant(); @@ -1121,8 +1177,6 @@ pub type Mat4f = Mat4; pub type Mat4f32 = Mat4; pub type Mat4f64 = Mat4; -impl_mat!(Mat4, Vec4) -impl_mat_swap!(Mat4, Vec4) impl_dimensional!(Mat4, Vec4, 4) impl_approx!(Mat4 { x, y, z, w }) @@ -1151,7 +1205,34 @@ impl Mat4 { } } -impl Mat4 { +impl Mat,[Vec4,..4]> for Mat4 { + #[inline] + pub fn col<'a>(&'a self, i: uint) -> &'a Vec4 { + self.index(i) + } + + #[inline] + pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4 { + self.index_mut(i) + } + + #[inline] + pub fn elem<'a>(&'a self, col: uint, row: uint) -> &'a T { + self.index(col).index(row) + } + + #[inline] + pub fn elem_mut<'a>(&'a mut self, col: uint, row: uint) -> &'a mut T { + self.index_mut(col).index_mut(row) + } + + #[inline] + pub fn swap_cols(&mut self, a: uint, b: uint) { + let tmp = self.col(a).clone(); + *self.col_mut(a) = self.col(b).clone(); + *self.col_mut(b) = tmp; + } + #[inline] pub fn row(&self, i: uint) -> Vec4 { Vec4::new(self.col(0).index(i).clone(), @@ -1167,6 +1248,47 @@ impl Mat4 { self.col_mut(2).swap(a, b); self.col_mut(3).swap(a, b); } + + #[inline] + pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), + (col_b, row_b): (uint, uint)) { + let tmp = self.elem(col_a, row_a).clone(); + *self.elem_mut(col_a, row_a) = self.elem(col_b, row_b).clone(); + *self.elem_mut(col_b, row_b) = tmp; + } + + #[inline] + pub fn transpose(&self) -> Mat4 { + Mat4::new(self.elem(0, 0).clone(), + self.elem(1, 0).clone(), + self.elem(2, 0).clone(), + self.elem(3, 0).clone(), + + self.elem(0, 1).clone(), + self.elem(1, 1).clone(), + self.elem(2, 1).clone(), + self.elem(3, 1).clone(), + + self.elem(0, 2).clone(), + self.elem(1, 2).clone(), + self.elem(2, 2).clone(), + self.elem(3, 2).clone(), + + self.elem(0, 3).clone(), + self.elem(1, 3).clone(), + self.elem(2, 3).clone(), + self.elem(3, 3).clone()) + } + + #[inline] + pub fn transpose_self(&mut self) { + self.swap_elem((0, 1), (1, 0)); + self.swap_elem((0, 2), (2, 0)); + self.swap_elem((0, 3), (3, 0)); + self.swap_elem((1, 2), (2, 1)); + self.swap_elem((1, 3), (3, 1)); + self.swap_elem((2, 3), (3, 2)); + } } impl Mat4 { @@ -1183,7 +1305,9 @@ impl Mat4 { #[inline] pub fn zero() -> Mat4 { Mat4::from_value(zero!(T)) } +} +impl NumMat,[Vec4,..4]> for Mat4 { #[inline] pub fn mul_t(&self, value: T) -> Mat4 { Mat4::from_cols(self.col(0).mul_t(value.clone()), @@ -1312,7 +1436,7 @@ impl Neg> for Mat4 { } } -impl> Mat4 { +impl FloatMat,[Vec4,..4]> for Mat4 { #[inline] pub fn inverse(&self) -> Option> { use std::uint;