From a4c7332e2bc2762bc036134ea1a050a92c7e92f3 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 16 Jun 2013 15:34:59 +1000 Subject: [PATCH] Move Dimensional trait and dimensional macros into separate files --- src/dim.rs | 21 +++++ src/dim_macros.rs | 222 ++++++++++++++++++++++++++++++++++++++++++++++ src/macros.rs | 206 ------------------------------------------ src/mat2.rs | 1 + src/mat3.rs | 1 + src/mat4.rs | 1 + src/quat.rs | 4 +- src/vec2.rs | 1 + src/vec3.rs | 1 + src/vec4.rs | 1 + 10 files changed, 252 insertions(+), 207 deletions(-) create mode 100644 src/dim.rs create mode 100644 src/dim_macros.rs diff --git a/src/dim.rs b/src/dim.rs new file mode 100644 index 0000000..316bcbd --- /dev/null +++ b/src/dim.rs @@ -0,0 +1,21 @@ +// Copyright 2013 The Lmath Developers. For a full listing of the authors, +// refer to the AUTHORS file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +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; +} diff --git a/src/dim_macros.rs b/src/dim_macros.rs new file mode 100644 index 0000000..1b43aea --- /dev/null +++ b/src/dim_macros.rs @@ -0,0 +1,222 @@ +// Copyright 2013 The Lmath Developers. For a full listing of the authors, +// refer to the AUTHORS file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[macro_escape]; + +macro_rules! impl_dimensional( + ($Self:ident, $T:ty, $n:expr) => ( + impl Dimensional<$T,[$T,..$n]> for $Self { + #[inline] + pub fn index<'a>(&'a self, i: uint) -> &'a $T { + &'a self.as_slice()[i] + } + + #[inline] + pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut $T { + &'a mut self.as_mut_slice()[i] + } + + #[inline] + pub fn as_slice<'a>(&'a self) -> &'a [$T,..$n] { + use std::cast::transmute; + unsafe { transmute(self) } + } + + #[inline] + pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [$T,..$n] { + use std::cast::transmute; + unsafe { transmute(self) } + } + } + ) +) + +macro_rules! impl_dimensional_fns( + ($Self:ident, $T:ty, 2) => ( + impl $Self { + #[inline] + pub fn from_slice<'a>(slice: [$T,..2]) -> $Self { + use std::cast::transmute; + unsafe { transmute(slice) } + } + + #[inline(always)] + pub fn map(&self, f: &fn(&$T) -> U) -> [U,..2] { + [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)); + } + + #[inline(always)] + pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..2] { + [f(self.index(0), other.index(0)), + f(self.index(1), other.index(1))] + } + + #[inline(always)] + pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { + f(self.index_mut(0), other.index(0)); + f(self.index_mut(1), other.index(1)); + } + + #[inline(always)] + pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { + f(self.index(0), &f(self.index(1), init)) + } + + #[inline(always)] + pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { + f(self.index(1), &f(self.index(0), init)) + } + } + ); + ($Self:ident, $T:ty, 3) => ( + impl $Self { + #[inline] + pub fn from_slice<'a>(slice: [$T,..3]) -> $Self { + use std::cast::transmute; + unsafe { transmute(slice) } + } + + #[inline(always)] + pub fn map(&self, f: &fn(&$T) -> U) -> [U,..3] { + [f(self.index(0)), + 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)); + } + + #[inline(always)] + pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..3] { + [f(self.index(0), other.index(0)), + f(self.index(1), other.index(1)), + f(self.index(2), other.index(2))] + } + + #[inline(always)] + pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { + f(self.index_mut(0), other.index(0)); + f(self.index_mut(1), other.index(1)); + f(self.index_mut(2), other.index(2)); + } + + #[inline(always)] + pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { + f(self.index(0), &f(self.index(1), &f(self.index(2), init))) + } + + #[inline(always)] + pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { + f(self.index(2), &f(self.index(1), &f(self.index(0), init))) + } + } + ); + ($Self:ident, $T:ty, 4) => ( + impl $Self { + #[inline] + pub fn from_slice<'a>(slice: [$T,..4]) -> $Self { + use std::cast::transmute; + unsafe { transmute(slice) } + } + + #[inline(always)] + pub fn map(&self, f: &fn(&$T) -> U) -> [U,..4] { + [f(self.index(0)), + f(self.index(1)), + 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)); + } + + #[inline(always)] + pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..4] { + [f(self.index(0), other.index(0)), + f(self.index(1), other.index(1)), + f(self.index(2), other.index(2)), + f(self.index(3), other.index(3))] + } + + #[inline(always)] + pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { + f(self.index_mut(0), other.index(0)); + f(self.index_mut(1), other.index(1)); + f(self.index_mut(2), other.index(2)); + f(self.index_mut(3), other.index(3)); + } + + #[inline(always)] + pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { + f(self.index(0), &f(self.index(1), &f(self.index(2), &f(self.index(3), init)))) + } + + #[inline(always)] + pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { + f(self.index(3), &f(self.index(2), &f(self.index(1), &f(self.index(0), init)))) + } + } + ) +) + +macro_rules! impl_swap( + ($Self:ident) => ( + impl $Self { + #[inline] + pub fn swap(&mut self, a: uint, b: uint) { + let tmp = *self.index(a); + *self.index_mut(a) = *self.index(b); + *self.index_mut(b) = tmp; + } + } + ) +) + +macro_rules! impl_approx( + ($Self:ident) => ( + impl> ApproxEq for $Self { + #[inline] + pub fn approx_epsilon() -> T { + ApproxEq::approx_epsilon::() + } + + #[inline] + pub fn approx_eq(&self, other: &$Self) -> bool { + self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) + } + + #[inline] + pub fn approx_eq_eps(&self, other: &$Self, epsilon: &T) -> bool { + self.zip(other, |a, b| a.approx_eq_eps(b, epsilon)).all(|&x| x) + } + } + ) +) diff --git a/src/macros.rs b/src/macros.rs index 88e3d48..86dd893 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -32,209 +32,3 @@ macro_rules! one( macro_rules! two( ($T:ty) => (one!(T) + one!(T)); ) - -macro_rules! impl_dimensional( - ($Self:ident, $T:ty, $n:expr) => ( - impl Dimensional<$T,[$T,..$n]> for $Self { - #[inline] - pub fn index<'a>(&'a self, i: uint) -> &'a $T { - &'a self.as_slice()[i] - } - - #[inline] - pub fn index_mut<'a>(&'a mut self, i: uint) -> &'a mut $T { - &'a mut self.as_mut_slice()[i] - } - - #[inline] - pub fn as_slice<'a>(&'a self) -> &'a [$T,..$n] { - use std::cast::transmute; - unsafe { transmute(self) } - } - - #[inline] - pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [$T,..$n] { - use std::cast::transmute; - unsafe { transmute(self) } - } - } - ) -) - -macro_rules! impl_dimensional_fns( - ($Self:ident, $T:ty, 2) => ( - impl $Self { - #[inline] - pub fn from_slice<'a>(slice: [$T,..2]) -> $Self { - use std::cast::transmute; - unsafe { transmute(slice) } - } - - #[inline(always)] - pub fn map(&self, f: &fn(&$T) -> U) -> [U,..2] { - [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)); - } - - #[inline(always)] - pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..2] { - [f(self.index(0), other.index(0)), - f(self.index(1), other.index(1))] - } - - #[inline(always)] - pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { - f(self.index_mut(0), other.index(0)); - f(self.index_mut(1), other.index(1)); - } - - #[inline(always)] - pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(0), &f(self.index(1), init)) - } - - #[inline(always)] - pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(1), &f(self.index(0), init)) - } - } - ); - ($Self:ident, $T:ty, 3) => ( - impl $Self { - #[inline] - pub fn from_slice<'a>(slice: [$T,..3]) -> $Self { - use std::cast::transmute; - unsafe { transmute(slice) } - } - - #[inline(always)] - pub fn map(&self, f: &fn(&$T) -> U) -> [U,..3] { - [f(self.index(0)), - 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)); - } - - #[inline(always)] - pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..3] { - [f(self.index(0), other.index(0)), - f(self.index(1), other.index(1)), - f(self.index(2), other.index(2))] - } - - #[inline(always)] - pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { - f(self.index_mut(0), other.index(0)); - f(self.index_mut(1), other.index(1)); - f(self.index_mut(2), other.index(2)); - } - - #[inline(always)] - pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(0), &f(self.index(1), &f(self.index(2), init))) - } - - #[inline(always)] - pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(2), &f(self.index(1), &f(self.index(0), init))) - } - } - ); - ($Self:ident, $T:ty, 4) => ( - impl $Self { - #[inline] - pub fn from_slice<'a>(slice: [$T,..4]) -> $Self { - use std::cast::transmute; - unsafe { transmute(slice) } - } - - #[inline(always)] - pub fn map(&self, f: &fn(&$T) -> U) -> [U,..4] { - [f(self.index(0)), - f(self.index(1)), - 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)); - } - - #[inline(always)] - pub fn zip, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..4] { - [f(self.index(0), other.index(0)), - f(self.index(1), other.index(1)), - f(self.index(2), other.index(2)), - f(self.index(3), other.index(3))] - } - - #[inline(always)] - pub fn zip_mut>(&mut self, other: &SU, f: &fn(&mut $T, &U)) { - f(self.index_mut(0), other.index(0)); - f(self.index_mut(1), other.index(1)); - f(self.index_mut(2), other.index(2)); - f(self.index_mut(3), other.index(3)); - } - - #[inline(always)] - pub fn foldl(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(0), &f(self.index(1), &f(self.index(2), &f(self.index(3), init)))) - } - - #[inline(always)] - pub fn foldr(&self, init: &U, f: &fn(&$T, &U) -> U) -> U { - f(self.index(3), &f(self.index(2), &f(self.index(1), &f(self.index(0), init)))) - } - } - ) -) - -macro_rules! impl_swap( - ($Self:ident) => ( - impl $Self { - #[inline] - pub fn swap(&mut self, a: uint, b: uint) { - let tmp = *self.index(a); - *self.index_mut(a) = *self.index(b); - *self.index_mut(b) = tmp; - } - } - ) -) - -macro_rules! impl_approx( - ($Self:ident) => ( - impl> ApproxEq for $Self { - #[inline] - pub fn approx_epsilon() -> T { - ApproxEq::approx_epsilon::() - } - - #[inline] - pub fn approx_eq(&self, other: &$Self) -> bool { - self.approx_eq_eps(other, &ApproxEq::approx_epsilon::()) - } - - #[inline] - pub fn approx_eq_eps(&self, other: &$Self, epsilon: &T) -> bool { - self.zip(other, |a, b| a.approx_eq_eps(b, epsilon)).all(|&x| x) - } - } - ) -) diff --git a/src/mat2.rs b/src/mat2.rs index f9d1909..1533570 100644 --- a/src/mat2.rs +++ b/src/mat2.rs @@ -20,6 +20,7 @@ use mat::{Mat4, ToMat4}; use vec::Vec2; mod macros; +mod dim_macros; mod mat_macros; #[deriving(Eq)] diff --git a/src/mat3.rs b/src/mat3.rs index 04fb91a..afd3eb8 100644 --- a/src/mat3.rs +++ b/src/mat3.rs @@ -20,6 +20,7 @@ use quat::{Quat, ToQuat}; use vec::Vec3; mod macros; +mod dim_macros; mod mat_macros; #[deriving(Eq)] diff --git a/src/mat4.rs b/src/mat4.rs index 4487a35..8fa21a1 100644 --- a/src/mat4.rs +++ b/src/mat4.rs @@ -19,6 +19,7 @@ use mat::Mat3; use vec::Vec4; mod macros; +mod dim_macros; mod mat_macros; #[deriving(Eq)] diff --git a/src/quat.rs b/src/quat.rs index 55171c8..83d16ab 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -15,11 +15,11 @@ pub use super::Dimensional; -use std::num::cast; use mat::{Mat3, ToMat3}; use vec::Vec3; mod macros; +mod dim_macros; // GLSL-style type aliases @@ -285,6 +285,8 @@ impl Quat { /// - [Arcsynthesis OpenGL tutorial] /// (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html) pub fn slerp(&self, other: &Quat, amount: T) -> Quat { + use std::num::cast; + let dot = self.dot(other); let dot_threshold = cast(0.9995); diff --git a/src/vec2.rs b/src/vec2.rs index 1d9dfa6..808780a 100644 --- a/src/vec2.rs +++ b/src/vec2.rs @@ -16,6 +16,7 @@ pub use super::Dimensional; mod macros; +mod dim_macros; mod vec_macros; #[deriving(Eq)] diff --git a/src/vec3.rs b/src/vec3.rs index 3712428..25c0c96 100644 --- a/src/vec3.rs +++ b/src/vec3.rs @@ -16,6 +16,7 @@ pub use super::Dimensional; mod macros; +mod dim_macros; mod vec_macros; #[deriving(Eq)] diff --git a/src/vec4.rs b/src/vec4.rs index c15c4cc..56737a4 100644 --- a/src/vec4.rs +++ b/src/vec4.rs @@ -16,6 +16,7 @@ pub use super::Dimensional; mod macros; +mod dim_macros; mod vec_macros; #[deriving(Eq)]