Implement Dimensional trait

This commit is contained in:
Brendan Zabarauskas 2013-06-12 12:57:58 +10:00
parent 5cb98d09cf
commit b727dd2bf5
10 changed files with 160 additions and 42 deletions

View file

@ -28,3 +28,12 @@ pub mod quat;
pub mod vec; pub mod vec;
pub mod projection; pub mod projection;
pub trait Dimensional<T,Slice> {
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));
}

View file

@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
pub use super::Dimensional;
pub use self::mat2::{Mat2, ToMat2}; pub use self::mat2::{Mat2, ToMat2};
pub use self::mat3::{Mat3, ToMat3}; pub use self::mat3::{Mat3, ToMat3};
pub use self::mat4::{Mat4, ToMat4}; pub use self::mat4::{Mat4, ToMat4};

View file

@ -17,7 +17,8 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use vec::*; use super::Dimensional;
use vec::Vec2;
use super::{Mat3, ToMat3}; use super::{Mat3, ToMat3};
use super::{Mat4, ToMat4}; use super::{Mat4, ToMat4};
@ -77,11 +78,33 @@ impl<T> Mat2<T> {
#[inline] #[inline]
pub fn col<'a>(&'a self, i: uint) -> &'a Vec2<T> { pub fn col<'a>(&'a self, i: uint) -> &'a Vec2<T> {
&'a self.as_slice()[i] self.index(i)
} }
#[inline] #[inline]
pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2<T> { pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2<T> {
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<T> Dimensional<Vec2<T>,[Vec2<T>,..2]> for Mat2<T> {
#[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a Vec2<T> {
&'a self.as_slice()[i]
}
#[inline]
pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec2<T> {
&'a mut self.as_mut_slice()[i] &'a mut self.as_mut_slice()[i]
} }
@ -95,20 +118,16 @@ impl<T> Mat2<T> {
unsafe { transmute(self) } unsafe { transmute(self) }
} }
#[inline] #[inline(always)]
pub fn elem<'a>(&'a self, i: uint, j: uint) -> &'a T { pub fn map(&self, f: &fn(&Vec2<T>) -> Vec2<T>) -> Mat2<T> {
self.col(i).index(j) Mat2::from_cols(f(self.index(0)),
} f(self.index(1)))
#[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)] #[inline(always)]
pub fn map(&self, f: &fn(&Vec2<T>) -> Vec2<T>) -> Mat2<T> { pub fn map_mut(&mut self, f: &fn(&mut Vec2<T>)) {
Mat2::from_cols(f(self.col(0)), f(self.index_mut(0));
f(self.col(1))) f(self.index_mut(1));
} }
} }

View file

@ -17,7 +17,8 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use vec::*; use super::Dimensional;
use vec::Vec3;
use quat::{Quat, ToQuat}; use quat::{Quat, ToQuat};
use super::{Mat4, ToMat4}; use super::{Mat4, ToMat4};
@ -87,11 +88,33 @@ impl<T> Mat3<T> {
#[inline] #[inline]
pub fn col<'a>(&'a self, i: uint) -> &'a Vec3<T> { pub fn col<'a>(&'a self, i: uint) -> &'a Vec3<T> {
&'a self.as_slice()[i] self.index(i)
} }
#[inline] #[inline]
pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3<T> { pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3<T> {
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<T> Dimensional<Vec3<T>,[Vec3<T>,..3]> for Mat3<T> {
#[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a Vec3<T> {
&'a self.as_slice()[i]
}
#[inline]
pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec3<T> {
&'a mut self.as_mut_slice()[i] &'a mut self.as_mut_slice()[i]
} }
@ -105,21 +128,18 @@ impl<T> Mat3<T> {
unsafe { transmute(self) } unsafe { transmute(self) }
} }
#[inline] #[inline(always)]
pub fn elem<'a>(&'a self, i: uint, j: uint) -> &'a T { pub fn map(&self, f: &fn(&Vec3<T>) -> Vec3<T>) -> Mat3<T> {
self.col(i).index(j) Mat3::from_cols(f(self.index(0)),
} f(self.index(1)),
f(self.index(2)))
#[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)] #[inline(always)]
pub fn map(&self, f: &fn(&Vec3<T>) -> Vec3<T>) -> Mat3<T> { pub fn map_mut(&mut self, f: &fn(&mut Vec3<T>)) {
Mat3::from_cols(f(self.col(0)), f(self.index_mut(0));
f(self.col(1)), f(self.index_mut(1));
f(self.col(2))) f(self.index_mut(2));
} }
} }

View file

@ -18,7 +18,8 @@ use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use std::uint; use std::uint;
use vec::*; use super::Dimensional;
use vec::Vec4;
use super::Mat3; use super::Mat3;
#[deriving(Eq)] #[deriving(Eq)]
@ -97,11 +98,33 @@ impl<T> Mat4<T> {
#[inline] #[inline]
pub fn col<'a>(&'a self, i: uint) -> &'a Vec4<T> { pub fn col<'a>(&'a self, i: uint) -> &'a Vec4<T> {
&'a self.as_slice()[i] self.index(i)
} }
#[inline] #[inline]
pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4<T> { pub fn col_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4<T> {
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<T> Dimensional<Vec4<T>,[Vec4<T>,..4]> for Mat4<T> {
#[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a Vec4<T> {
&'a self.as_slice()[i]
}
#[inline]
pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut Vec4<T> {
&'a mut self.as_mut_slice()[i] &'a mut self.as_mut_slice()[i]
} }
@ -115,22 +138,20 @@ impl<T> Mat4<T> {
unsafe { transmute(self) } unsafe { transmute(self) }
} }
#[inline] #[inline(always)]
pub fn elem<'a>(&'a self, i: uint, j: uint) -> &'a T { pub fn map(&self, f: &fn(&Vec4<T>) -> Vec4<T>) -> Mat4<T> {
self.col(i).index(j) Mat4::from_cols(f(self.index(0)),
} f(self.index(1)),
f(self.index(2)),
#[inline] f(self.index(3)))
pub fn elem_mut<'a>(&'a mut self, i: uint, j: uint) -> &'a mut T {
self.col_mut(i).index_mut(j)
} }
#[inline(always)] #[inline(always)]
pub fn map(&self, f: &fn(&Vec4<T>) -> Vec4<T>) -> Mat4<T> { pub fn map_mut(&mut self, f: &fn(&mut Vec4<T>)) {
Mat4::from_cols(f(self.col(0)), f(self.index_mut(0));
f(self.col(1)), f(self.index_mut(1));
f(self.col(2)), f(self.index_mut(2));
f(self.col(3))) f(self.index_mut(3));
} }
} }

View file

@ -13,6 +13,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
pub use super::Dimensional;
use std::cast::transmute; use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One, cast}; use std::num::{Zero, One, cast};
@ -73,7 +75,9 @@ impl<T> Quat<T> {
pub fn from_sv(s: T, v: Vec3<T>) -> Quat<T> { pub fn from_sv(s: T, v: Vec3<T>) -> Quat<T> {
Quat { s: s, v: v } Quat { s: s, v: v }
} }
}
impl<T> Dimensional<T,[T,..4]> for Quat<T> {
#[inline] #[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a T { pub fn index<'a>(&'a self, i: uint) -> &'a T {
&'a self.as_slice()[i] &'a self.as_slice()[i]
@ -101,6 +105,14 @@ impl<T> Quat<T> {
f(self.index(2)), f(self.index(2)),
f(self.index(3))) 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<T:Copy> Quat<T> { impl<T:Copy> Quat<T> {

View file

@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
pub use super::Dimensional;
pub use self::vec2::Vec2; pub use self::vec2::Vec2;
pub use self::vec3::Vec3; pub use self::vec3::Vec3;
pub use self::vec4::Vec4; pub use self::vec4::Vec4;

View file

@ -17,6 +17,8 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use super::Dimensional;
use super::Vec3; use super::Vec3;
#[deriving(Eq)] #[deriving(Eq)]
@ -27,7 +29,9 @@ impl<T> Vec2<T> {
pub fn new(x: T, y: T ) -> Vec2<T> { pub fn new(x: T, y: T ) -> Vec2<T> {
Vec2 { x: x, y: y } Vec2 { x: x, y: y }
} }
}
impl<T> Dimensional<T,[T,..2]> for Vec2<T> {
#[inline] #[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a T { pub fn index<'a>(&'a self, i: uint) -> &'a T {
&'a self.as_slice()[i] &'a self.as_slice()[i]
@ -53,6 +57,14 @@ impl<T> Vec2<T> {
Vec2::new(f(self.index(0)), Vec2::new(f(self.index(0)),
f(self.index(1))) 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<T:Copy> Vec2<T> { impl<T:Copy> Vec2<T> {

View file

@ -17,6 +17,7 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use super::Dimensional;
use super::Vec4; use super::Vec4;
#[deriving(Eq)] #[deriving(Eq)]
@ -27,7 +28,9 @@ impl<T> Vec3<T> {
pub fn new(x: T, y: T, z: T ) -> Vec3<T> { pub fn new(x: T, y: T, z: T ) -> Vec3<T> {
Vec3 { x: x, y: y, z: z } Vec3 { x: x, y: y, z: z }
} }
}
impl<T> Dimensional<T,[T,..3]> for Vec3<T> {
#[inline] #[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a T { pub fn index<'a>(&'a self, i: uint) -> &'a T {
&'a self.as_slice()[i] &'a self.as_slice()[i]
@ -54,6 +57,14 @@ impl<T> Vec3<T> {
f(self.index(1)), f(self.index(1)),
f(self.index(2))) 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<T:Copy> Vec3<T> { impl<T:Copy> Vec3<T> {

View file

@ -17,6 +17,8 @@ use std::cast::transmute;
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::num::{Zero, One}; use std::num::{Zero, One};
use super::Dimensional;
#[deriving(Eq)] #[deriving(Eq)]
pub struct Vec4<T> { x: T, y: T, z: T, w: T } pub struct Vec4<T> { x: T, y: T, z: T, w: T }
@ -25,7 +27,9 @@ impl<T> Vec4<T> {
pub fn new(x: T, y: T, z: T, w: T ) -> Vec4<T> { pub fn new(x: T, y: T, z: T, w: T ) -> Vec4<T> {
Vec4 { x: x, y: y, z: z, w: w } Vec4 { x: x, y: y, z: z, w: w }
} }
}
impl<T> Dimensional<T,[T,..4]> for Vec4<T> {
#[inline] #[inline]
pub fn index<'a>(&'a self, i: uint) -> &'a T { pub fn index<'a>(&'a self, i: uint) -> &'a T {
&'a self.as_slice()[i] &'a self.as_slice()[i]
@ -53,6 +57,14 @@ impl<T> Vec4<T> {
f(self.index(2)), f(self.index(2)),
f(self.index(3))) 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<T:Copy> Vec4<T> { impl<T:Copy> Vec4<T> {