#![macro_escape] macro_rules! iso_impl( ($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => ( impl $t { /// Creates a new isometry from a rotation matrix and a vector. #[inline] pub fn new(translation: $subvec, rotation: $subrotvec) -> $t { $t { rotation: $submat::new(rotation), translation: translation } } /// Creates a new isometry from a rotation matrix and a vector. #[inline] pub fn new_with_rotmat(translation: $subvec, rotation: $submat) -> $t { $t { rotation: rotation, translation: translation } } } ) ) macro_rules! rotation_matrix_impl( ($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( impl + Float + Float + Num + Clone> RotationMatrix<$tlv, $tav, $trot> for $t { #[inline] fn to_rot_mat(&self) -> $trot { self.rotation.clone() } } ) ) macro_rules! dim_impl( ($t: ident, $dim: expr) => ( impl Dim for $t { #[inline] fn dim(_: Option<$t>) -> uint { $dim } } ) ) macro_rules! one_impl( ($t: ident) => ( impl One for $t { #[inline] fn one() -> $t { $t::new_with_rotmat(Zero::zero(), One::one()) } } ) ) macro_rules! iso_mul_iso_impl( ($t: ident, $tmul: ident) => ( impl $tmul> for $t { #[inline] fn binop(left: &$t, right: &$t) -> $t { $t::new_with_rotmat( left.translation + left.rotation * right.translation, left.rotation * right.rotation) } } ) ) macro_rules! iso_mul_vec_impl( ($t: ident, $tv: ident, $tmul: ident) => ( impl $tmul> for $tv { #[inline] fn binop(left: &$t, right: &$tv) -> $tv { left.translation + left.rotation * *right } } ) ) macro_rules! vec_mul_iso_impl( ($t: ident, $tv: ident, $tmul: ident) => ( impl $tmul> for $t { #[inline] fn binop(left: &$tv, right: &$t) -> $tv { (left + right.translation) * right.rotation } } ) ) macro_rules! translation_impl( ($t: ident, $tv: ident) => ( impl Translation<$tv> for $t { #[inline] fn translation(&self) -> $tv { self.translation.clone() } #[inline] fn inv_translation(&self) -> $tv { -self.translation } #[inline] fn append_translation(&mut self, t: &$tv) { self.translation = *t + self.translation } #[inline] fn append_translation_cpy(iso: &$t, t: &$tv) -> $t { $t::new_with_rotmat(*t + iso.translation, iso.rotation.clone()) } #[inline] fn prepend_translation(&mut self, t: &$tv) { self.translation = self.translation + self.rotation * *t } #[inline] fn prepend_translation_cpy(iso: &$t, t: &$tv) -> $t { $t::new_with_rotmat(iso.translation + iso.rotation * *t, iso.rotation.clone()) } #[inline] fn set_translation(&mut self, t: $tv) { self.translation = t } } ) ) macro_rules! translate_impl( ($t: ident, $tv: ident) => ( impl + Sub> Translate<$tv> for $t { #[inline] fn translate(&self, v: &$tv) -> $tv { v + self.translation } #[inline] fn inv_translate(&self, v: &$tv) -> $tv { v - self.translation } } ) ) macro_rules! rotation_impl( ($t: ident, $trot: ident, $tav: ident) => ( impl + Num + Float + Float + Clone> Rotation<$tav> for $t { #[inline] fn rotation(&self) -> $tav { self.rotation.rotation() } #[inline] fn inv_rotation(&self) -> $tav { self.rotation.inv_rotation() } #[inline] fn append_rotation(&mut self, rot: &$tav) { let delta = $trot::new(rot.clone()); self.rotation = delta * self.rotation; self.translation = delta * self.translation; } #[inline] fn append_rotation_cpy(t: &$t, rot: &$tav) -> $t { let delta = $trot::new(rot.clone()); $t::new_with_rotmat(delta * t.translation, delta * t.rotation) } #[inline] fn prepend_rotation(&mut self, rot: &$tav) { let delta = $trot::new(rot.clone()); self.rotation = self.rotation * delta; } #[inline] fn prepend_rotation_cpy(t: &$t, rot: &$tav) -> $t { let delta = $trot::new(rot.clone()); $t::new_with_rotmat(t.translation.clone(), t.rotation * delta) } #[inline] fn set_rotation(&mut self, rot: $tav) { // FIXME: should the translation be changed too? self.rotation.set_rotation(rot) } } ) ) macro_rules! rotate_impl( ($t: ident, $tv: ident) => ( impl Rotate<$tv> for $t { #[inline] fn rotate(&self, v: &$tv) -> $tv { self.rotation.rotate(v) } #[inline] fn inv_rotate(&self, v: &$tv) -> $tv { self.rotation.inv_rotate(v) } } ) ) macro_rules! transformation_impl( ($t: ident) => ( impl Transformation<$t> for $t { fn transformation(&self) -> $t { self.clone() } fn inv_transformation(&self) -> $t { // inversion will never fails Inv::inv_cpy(self).unwrap() } fn append_transformation(&mut self, t: &$t) { *self = *t * *self } fn append_transformation_cpy(iso: &$t, t: &$t) -> $t { t * *iso } fn prepend_transformation(&mut self, t: &$t) { *self = *self * *t } fn prepend_transformation_cpy(iso: &$t, t: &$t) -> $t { *iso * *t } fn set_transformation(&mut self, t: $t) { *self = t } } ) ) macro_rules! transform_impl( ($t: ident, $tv: ident) => ( impl Transform<$tv> for $t { #[inline] fn transform(&self, v: &$tv) -> $tv { self.rotation.transform(v) + self.translation } #[inline] fn inv_transform(&self, v: &$tv) -> $tv { self.rotation.inv_transform(&(v - self.translation)) } } ) ) macro_rules! inv_impl( ($t: ident) => ( impl Inv for $t { #[inline] fn inv(&mut self) -> bool { self.rotation.inv(); self.translation = self.rotation * -self.translation; // always succeed true } #[inline] fn inv_cpy(m: &$t) -> Option<$t> { let mut res = m.clone(); res.inv(); // always succeed Some(res) } } ) ) macro_rules! to_homogeneous_impl( ($t: ident, $th: ident) => ( impl ToHomogeneous<$th> for $t { fn to_homogeneous(m: &$t) -> $th { let mut res = ToHomogeneous::to_homogeneous(&m.rotation); // copy the translation let dim = Dim::dim(None::<$th>); res.set_col(dim - 1, ToHomogeneous::to_homogeneous(&m.translation)); res } } ) ) macro_rules! approx_eq_impl( ($t: ident) => ( impl> ApproxEq for $t { #[inline] fn approx_epsilon(_: Option<$t>) -> N { ApproxEq::approx_epsilon(None::) } #[inline] fn approx_eq(a: &$t, b: &$t) -> bool { ApproxEq::approx_eq(&a.rotation, &b.rotation) && ApproxEq::approx_eq(&a.translation, &b.translation) } #[inline] fn approx_eq_eps(a: &$t, b: &$t, epsilon: &N) -> bool { ApproxEq::approx_eq_eps(&a.rotation, &b.rotation, epsilon) && ApproxEq::approx_eq_eps(&a.translation, &b.translation, epsilon) } } ) ) macro_rules! rand_impl( ($t: ident) => ( impl Rand for $t { #[inline] fn rand(rng: &mut R) -> $t { $t::new(rng.gen(), rng.gen()) } } ) ) macro_rules! absolute_rotate_impl( ($t: ident, $tv: ident) => ( impl AbsoluteRotate<$tv> for $t { #[inline] fn absolute_rotate(&self, v: &$tv) -> $tv { self.rotation.absolute_rotate(v) } } ) )