From b727dd2bf5104f55beb9b1e1e7ddea3de155d51d Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Wed, 12 Jun 2013 12:57:58 +1000 Subject: [PATCH] Implement Dimensional trait --- src/lmath.rs | 9 +++++++++ src/mat.rs | 1 + src/mat2.rs | 45 ++++++++++++++++++++++++++++++++------------- src/mat3.rs | 48 ++++++++++++++++++++++++++++++++++-------------- src/mat4.rs | 51 ++++++++++++++++++++++++++++++++++++--------------- src/quat.rs | 12 ++++++++++++ src/vec.rs | 1 + src/vec2.rs | 12 ++++++++++++ src/vec3.rs | 11 +++++++++++ src/vec4.rs | 12 ++++++++++++ 10 files changed, 160 insertions(+), 42 deletions(-) diff --git a/src/lmath.rs b/src/lmath.rs index c528f0c..e653b6a 100644 --- a/src/lmath.rs +++ b/src/lmath.rs @@ -28,3 +28,12 @@ pub mod quat; pub mod vec; pub mod projection; + +pub trait Dimensional { + pub fn index<'a>(&'a self, i: uint) -> &'a T; + pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut T; + pub fn as_slice<'a>(&'a self) -> &'a Slice; + pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut Slice; + pub fn map(&self, f: &fn(&T) -> T) -> Self; + pub fn map_mut(&mut self, f: &fn(&mut T)); +} diff --git a/src/mat.rs b/src/mat.rs index 2e6d5ed..4318755 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub use super::Dimensional; pub use self::mat2::{Mat2, ToMat2}; pub use self::mat3::{Mat3, ToMat3}; pub use self::mat4::{Mat4, ToMat4}; diff --git a/src/mat2.rs b/src/mat2.rs index 9b2fe09..bdfbb84 100644 --- a/src/mat2.rs +++ b/src/mat2.rs @@ -17,7 +17,8 @@ use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One}; -use vec::*; +use super::Dimensional; +use vec::Vec2; use super::{Mat3, ToMat3}; use super::{Mat4, ToMat4}; @@ -77,11 +78,33 @@ impl Mat2 { #[inline] pub fn col<'a>(&'a self, i: uint) -> &'a Vec2 { - &'a self.as_slice()[i] + 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, i: uint, j: uint) -> &'a T { + self.index(i).index(j) + } + + #[inline] + pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T { + self.index_mut(i).index_mut(j) + } +} + +impl Dimensional,[Vec2,..2]> for Mat2 { + #[inline] + pub fn index<'a>(&'a self, i: uint) -> &'a Vec2 { + &'a self.as_slice()[i] + } + + #[inline] + pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2 { &'a mut self.as_mut_slice()[i] } @@ -95,20 +118,16 @@ impl Mat2 { unsafe { transmute(self) } } - #[inline] - pub fn elem<'a>(&'a self, i: uint, j: uint) -> &'a T { - self.col(i).index(j) - } - - #[inline] - pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T { - self.col_mut(i).index_mut(j) + #[inline(always)] + pub fn map(&self, f: &fn(&Vec2) -> Vec2) -> Mat2 { + Mat2::from_cols(f(self.index(0)), + f(self.index(1))) } #[inline(always)] - pub fn map(&self, f: &fn(&Vec2) -> Vec2) -> Mat2 { - Mat2::from_cols(f(self.col(0)), - f(self.col(1))) + pub fn map_mut(&mut self, f: &fn(&mut Vec2)) { + f(self.index_mut(0)); + f(self.index_mut(1)); } } diff --git a/src/mat3.rs b/src/mat3.rs index 839a2dc..7f1b3f6 100644 --- a/src/mat3.rs +++ b/src/mat3.rs @@ -17,7 +17,8 @@ use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One}; -use vec::*; +use super::Dimensional; +use vec::Vec3; use quat::{Quat, ToQuat}; use super::{Mat4, ToMat4}; @@ -87,11 +88,33 @@ impl Mat3 { #[inline] pub fn col<'a>(&'a self, i: uint) -> &'a Vec3 { - &'a self.as_slice()[i] + 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, i: uint, j: uint) -> &'a T { + self.index(i).index(j) + } + + #[inline] + pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T { + self.index_mut(i).index_mut(j) + } +} + +impl Dimensional,[Vec3,..3]> for Mat3 { + #[inline] + pub fn index<'a>(&'a self, i: uint) -> &'a Vec3 { + &'a self.as_slice()[i] + } + + #[inline] + pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3 { &'a mut self.as_mut_slice()[i] } @@ -105,21 +128,18 @@ impl Mat3 { unsafe { transmute(self) } } - #[inline] - pub fn elem<'a>(&'a self, i: uint, j: uint) -> &'a T { - self.col(i).index(j) - } - - #[inline] - pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T { - self.col_mut(i).index_mut(j) + #[inline(always)] + pub fn map(&self, f: &fn(&Vec3) -> Vec3) -> Mat3 { + Mat3::from_cols(f(self.index(0)), + f(self.index(1)), + f(self.index(2))) } #[inline(always)] - pub fn map(&self, f: &fn(&Vec3) -> Vec3) -> Mat3 { - Mat3::from_cols(f(self.col(0)), - f(self.col(1)), - f(self.col(2))) + pub fn map_mut(&mut self, f: &fn(&mut Vec3)) { + f(self.index_mut(0)); + f(self.index_mut(1)); + f(self.index_mut(2)); } } diff --git a/src/mat4.rs b/src/mat4.rs index babb2b1..3f80402 100644 --- a/src/mat4.rs +++ b/src/mat4.rs @@ -18,7 +18,8 @@ use std::cmp::ApproxEq; use std::num::{Zero, One}; use std::uint; -use vec::*; +use super::Dimensional; +use vec::Vec4; use super::Mat3; #[deriving(Eq)] @@ -97,11 +98,33 @@ impl Mat4 { #[inline] pub fn col<'a>(&'a self, i: uint) -> &'a Vec4 { - &'a self.as_slice()[i] + 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, i: uint, j: uint) -> &'a T { + self.index(i).index(j) + } + + #[inline] + pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T { + self.index_mut(i).index_mut(j) + } +} + +impl Dimensional,[Vec4,..4]> for Mat4 { + #[inline] + pub fn index<'a>(&'a self, i: uint) -> &'a Vec4 { + &'a self.as_slice()[i] + } + + #[inline] + pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4 { &'a mut self.as_mut_slice()[i] } @@ -115,22 +138,20 @@ impl Mat4 { unsafe { transmute(self) } } - #[inline] - pub fn elem<'a>(&'a self, i: uint, j: uint) -> &'a T { - self.col(i).index(j) - } - - #[inline] - pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T { - self.col_mut(i).index_mut(j) + #[inline(always)] + pub fn map(&self, f: &fn(&Vec4) -> Vec4) -> Mat4 { + Mat4::from_cols(f(self.index(0)), + f(self.index(1)), + f(self.index(2)), + f(self.index(3))) } #[inline(always)] - pub fn map(&self, f: &fn(&Vec4) -> Vec4) -> Mat4 { - Mat4::from_cols(f(self.col(0)), - f(self.col(1)), - f(self.col(2)), - f(self.col(3))) + pub fn map_mut(&mut self, f: &fn(&mut Vec4)) { + f(self.index_mut(0)); + f(self.index_mut(1)); + f(self.index_mut(2)); + f(self.index_mut(3)); } } diff --git a/src/quat.rs b/src/quat.rs index 88e29a0..26e5e0b 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub use super::Dimensional; + use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One, cast}; @@ -73,7 +75,9 @@ impl Quat { pub fn from_sv(s: T, v: Vec3) -> Quat { Quat { s: s, v: v } } +} +impl Dimensional for Quat { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] @@ -101,6 +105,14 @@ impl Quat { f(self.index(2)), f(self.index(3))) } + + #[inline(always)] + pub fn map_mut(&mut self, f: &fn(&mut T)) { + f(self.index_mut(0)); + f(self.index_mut(1)); + f(self.index_mut(2)); + f(self.index_mut(3)); + } } impl Quat { diff --git a/src/vec.rs b/src/vec.rs index aec298e..46fc9c2 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub use super::Dimensional; pub use self::vec2::Vec2; pub use self::vec3::Vec3; pub use self::vec4::Vec4; diff --git a/src/vec2.rs b/src/vec2.rs index 7a7c19a..6768cc2 100644 --- a/src/vec2.rs +++ b/src/vec2.rs @@ -17,6 +17,8 @@ use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One}; +use super::Dimensional; + use super::Vec3; #[deriving(Eq)] @@ -27,7 +29,9 @@ impl Vec2 { pub fn new(x: T, y: T ) -> Vec2 { Vec2 { x: x, y: y } } +} +impl Dimensional for Vec2 { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] @@ -53,6 +57,14 @@ impl Vec2 { Vec2::new(f(self.index(0)), f(self.index(1))) } + + #[inline(always)] + pub fn map_mut(&mut self, f: &fn(&mut T)) { + f(self.index_mut(0)); + f(self.index_mut(1)); + f(self.index_mut(2)); + f(self.index_mut(3)); + } } impl Vec2 { diff --git a/src/vec3.rs b/src/vec3.rs index 3e08c41..aa28467 100644 --- a/src/vec3.rs +++ b/src/vec3.rs @@ -17,6 +17,7 @@ use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One}; +use super::Dimensional; use super::Vec4; #[deriving(Eq)] @@ -27,7 +28,9 @@ impl Vec3 { pub fn new(x: T, y: T, z: T ) -> Vec3 { Vec3 { x: x, y: y, z: z } } +} +impl Dimensional for Vec3 { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] @@ -54,6 +57,14 @@ impl Vec3 { f(self.index(1)), f(self.index(2))) } + + #[inline(always)] + pub fn map_mut(&mut self, f: &fn(&mut T)) { + f(self.index_mut(0)); + f(self.index_mut(1)); + f(self.index_mut(2)); + f(self.index_mut(3)); + } } impl Vec3 { diff --git a/src/vec4.rs b/src/vec4.rs index 4e2ad28..0597595 100644 --- a/src/vec4.rs +++ b/src/vec4.rs @@ -17,6 +17,8 @@ use std::cast::transmute; use std::cmp::ApproxEq; use std::num::{Zero, One}; +use super::Dimensional; + #[deriving(Eq)] pub struct Vec4 { x: T, y: T, z: T, w: T } @@ -25,7 +27,9 @@ impl Vec4 { pub fn new(x: T, y: T, z: T, w: T ) -> Vec4 { Vec4 { x: x, y: y, z: z, w: w } } +} +impl Dimensional for Vec4 { #[inline] pub fn index<'a>(&'a self, i: uint) -> &'a T { &'a self.as_slice()[i] @@ -53,6 +57,14 @@ impl Vec4 { f(self.index(2)), f(self.index(3))) } + + #[inline(always)] + pub fn map_mut(&mut self, f: &fn(&mut T)) { + f(self.index_mut(0)); + f(self.index_mut(1)); + f(self.index_mut(2)); + f(self.index_mut(3)); + } } impl Vec4 {