diff --git a/src/mat.rs b/src/mat.rs index eba21d6..dcd09a7 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -28,36 +28,16 @@ pub trait Matrix: Dimensional, ToPtr, Eq, Neg { */ pure fn row(&self, i: uint) -> V; - /** - * Swap two columns of the matrix in place - */ - fn swap_cols(&mut self, a: uint, b: uint); - - /** - * Swap two rows of the matrix in place - */ - fn swap_rows(&mut self, a: uint, b: uint); - /** * Returns the identity matrix */ static pure fn identity() -> self; - /** - * Sets the matrix to the identity matrix - */ - fn to_identity(&mut self); - /** * Returns a matrix with all elements set to zero */ static pure fn zero() -> self; - /** - * Sets each element of the matrix to zero - */ - fn to_zero(&mut self); - /** * Returns the scalar multiplication of this matrix and `value` */ @@ -143,6 +123,33 @@ pub trait Matrix: Dimensional, ToPtr, Eq, Neg { pure fn is_invertible(&self) -> bool; } +pub trait MutableMatrix: Matrix { + /** + * Get a mutable reference to the column at `i` + */ + fn col_mut(&mut self, i: uint) -> &self/mut V; + + /** + * Swap two columns of the matrix in place + */ + fn swap_cols(&mut self, a: uint, b: uint); + + /** + * Swap two rows of the matrix in place + */ + fn swap_rows(&mut self, a: uint, b: uint); + + /** + * Sets the matrix to the identity matrix + */ + fn to_identity(&mut self); + + /** + * Sets each element of the matrix to zero + */ + fn to_zero(&mut self); +} + /** * A 2 x 2 square matrix with numeric elements */ @@ -260,30 +267,6 @@ pub impl Mat2: Matrix> { self[1][i]) } - #[inline(always)] - fn swap_cols(&mut self, a: uint, b: uint) { - let addr_a = - match a { - 0 => &mut self.x, - 1 => &mut self.y, - _ => fail(fmt!("index out of bounds: expected an index from 0 to 1 but found %u", a)) - }; - let addr_b = - match b { - 0 => &mut self.x, - 1 => &mut self.y, - _ => fail(fmt!("index out of bounds: expected an index from 0 to 1 but found %u", b)) - }; - - util::swap(addr_a, addr_b); - } - - #[inline(always)] - fn swap_rows(&mut self, a: uint, b: uint) { - self.x.swap(a, b); - self.y.swap(a, b); - } - /** * Returns the multiplicative identity matrix * ~~~ @@ -303,11 +286,6 @@ pub impl Mat2: Matrix> { _0, _1) } - #[inline(always)] - fn to_identity(&mut self) { - *self = Mat2::identity(); - } - /** * Returns the additive identity matrix * ~~~ @@ -326,11 +304,6 @@ pub impl Mat2: Matrix> { _0, _0) } - #[inline(always)] - fn to_zero(&mut self) { - *self = Mat2::zero(); - } - #[inline(always)] pure fn mul_t(&self, value: T) -> Mat2 { Mat2::from_cols(self[0].mul_t(value), @@ -426,6 +399,39 @@ pub impl Mat2: Matrix> { } } +pub impl Mat2: MutableMatrix> { + #[inline(always)] + fn col_mut(&mut self, i: uint) -> &self/mut Vec2 { + match i { + 0 => &mut self.x, + 1 => &mut self.y, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 1, but found %u", i)) + } + } + + #[inline(always)] + fn swap_cols(&mut self, a: uint, b: uint) { + util::swap(self.col_mut(a), + self.col_mut(b)); + } + + #[inline(always)] + fn swap_rows(&mut self, a: uint, b: uint) { + self.x.swap(a, b); + self.y.swap(a, b); + } + + #[inline(always)] + fn to_identity(&mut self) { + *self = Mat2::identity(); + } + + #[inline(always)] + fn to_zero(&mut self) { + *self = Mat2::zero(); + } +} + pub impl Mat2: Matrix2> { #[inline(always)] pure fn to_mat3(&self) -> Mat3 { @@ -612,33 +618,6 @@ pub impl Mat3: Matrix> { self[2][i]) } - #[inline(always)] - fn swap_cols(&mut self, a: uint, b: uint) { - let addr_a = - match a { - 0 => &mut self.x, - 1 => &mut self.y, - 2 => &mut self.z, - _ => fail(fmt!("index out of bounds: expected an index from 0 to 2 but found %u", a)) - }; - let addr_b = - match b { - 0 => &mut self.x, - 1 => &mut self.y, - 2 => &mut self.z, - _ => fail(fmt!("index out of bounds: expected an index from 0 to 2 but found %u", b)) - }; - - util::swap(addr_a, addr_b); - } - - #[inline(always)] - fn swap_rows(&mut self, a: uint, b: uint) { - self.x.swap(a, b); - self.y.swap(a, b); - self.z.swap(a, b); - } - /** * Returns the multiplicative identity matrix * ~~~ @@ -663,11 +642,6 @@ pub impl Mat3: Matrix> { _0, _0, _1) } - #[inline(always)] - fn to_identity(&mut self) { - *self = Mat3::identity(); - } - /** * Returns the additive identity matrix * ~~~ @@ -689,11 +663,6 @@ pub impl Mat3: Matrix> { _0, _0, _0) } - #[inline(always)] - fn to_zero(&mut self) { - *self = Mat3::zero(); - } - #[inline(always)] pure fn mul_t(&self, value: T) -> Mat3 { Mat3::from_cols(self[0].mul_t(value), @@ -809,6 +778,41 @@ pub impl Mat3: Matrix> { } } +pub impl Mat3: MutableMatrix> { + #[inline(always)] + fn col_mut(&mut self, i: uint) -> &self/mut Vec3 { + match i { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", i)) + } + } + + #[inline(always)] + fn swap_cols(&mut self, a: uint, b: uint) { + util::swap(self.col_mut(a), + self.col_mut(b)); + } + + #[inline(always)] + fn swap_rows(&mut self, a: uint, b: uint) { + self.x.swap(a, b); + self.y.swap(a, b); + self.z.swap(a, b); + } + + #[inline(always)] + fn to_identity(&mut self) { + *self = Mat3::identity(); + } + + #[inline(always)] + fn to_zero(&mut self) { + *self = Mat3::zero(); + } +} + pub impl Mat3: Matrix3> { #[inline(always)] pure fn to_mat4(&self) -> Mat4 { @@ -1059,36 +1063,6 @@ pub impl Mat4: Matrix> { self[3][i]) } - #[inline(always)] - fn swap_cols(&mut self, a: uint, b: uint) { - let addr_a = - match a { - 0 => &mut self.x, - 1 => &mut self.y, - 2 => &mut self.z, - 3 => &mut self.w, - _ => fail(fmt!("index out of bounds: expected an index from 0 to 3 but found %u", a)) - }; - let addr_b = - match b { - 0 => &mut self.x, - 1 => &mut self.y, - 2 => &mut self.z, - 3 => &mut self.w, - _ => fail(fmt!("index out of bounds: expected an index from 0 to 3 but found %u", b)) - }; - - util::swap(addr_a, addr_b); - } - - #[inline(always)] - fn swap_rows(&mut self, a: uint, b: uint) { - self.x.swap(a, b); - self.y.swap(a, b); - self.z.swap(a, b); - self.w.swap(a, b); - } - /** * Returns the multiplicative identity matrix * ~~~ @@ -1114,11 +1088,6 @@ pub impl Mat4: Matrix> { _0, _0, _0, _1) } - #[inline(always)] - fn to_identity(&mut self) { - *self = Mat4::identity(); - } - /** * Returns the additive identity matrix * ~~~ @@ -1143,11 +1112,6 @@ pub impl Mat4: Matrix> { _0, _0, _0, _0) } - #[inline(always)] - fn to_zero(&mut self) { - *self = Mat4::zero(); - } - #[inline(always)] pure fn mul_t(&self, value: T) -> Mat4 { Mat4::from_cols(self[0].mul_t(value), @@ -1338,6 +1302,43 @@ pub impl Mat4: Matrix> { } } +pub impl Mat4: MutableMatrix> { + #[inline(always)] + fn col_mut(&mut self, i: uint) -> &self/mut Vec4 { + match i { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + 3 => &mut self.w, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 3, but found %u", i)) + } + } + + #[inline(always)] + fn swap_cols(&mut self, a: uint, b: uint) { + util::swap(self.col_mut(a), + self.col_mut(b)); + } + + #[inline(always)] + fn swap_rows(&mut self, a: uint, b: uint) { + self.x.swap(a, b); + self.y.swap(a, b); + self.z.swap(a, b); + self.w.swap(a, b); + } + + #[inline(always)] + fn to_identity(&mut self) { + *self = Mat4::identity(); + } + + #[inline(always)] + fn to_zero(&mut self) { + *self = Mat4::zero(); + } +} + pub impl Mat4: Matrix4> { }