#[macro_escape]; macro_rules! iso_impl( ($t: ident, $submat: ident, $subvec: ident) => ( impl $t { /// Creates a new isometry from a rotation matrix and a vector. #[inline] pub fn new(translation: $subvec, rotation: $submat) -> $t { $t { rotation: rotation, translation: translation } } } ) ) macro_rules! rotation_matrix_impl( ($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( impl + Algebraic + Trigonometric + 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(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(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 + Add + Clone> Translation<$tv> for $t { #[inline] fn translation(&self) -> $tv { self.translation.clone() } #[inline] fn inv_translation(&self) -> $tv { -self.translation } #[inline] fn translate_by(&mut self, t: &$tv) { self.translation = self.translation + *t } #[inline] fn translated(&self, t: &$tv) -> $t { $t::new(self.translation + *t, self.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 + Trigonometric + Algebraic + 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 rotate_by(&mut self, rot: &$tav) { // FIXME: this does not seem opitmal let mut delta: $trot = One::one(); delta.rotate_by(rot); self.rotation.rotate_by(rot); self.translation = delta * self.translation; } #[inline] fn rotated(&self, rot: &$tav) -> $t { // FIXME: this does not seem opitmal let _1: $trot = One::one(); let delta = _1.rotated(rot); $t::new(delta * self.translation, self.rotation.rotated(rot)) } #[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 self.inverted().unwrap() } fn transform_by(&mut self, other: &$t) { *self = other * *self } fn transformed(&self, t: &$t) -> $t { t * *self } 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 invert(&mut self) -> bool { self.rotation.invert(); self.translation = self.rotation * -self.translation; // always succeed true } #[inline] fn inverted(&self) -> Option<$t> { let mut res = self.clone(); res.invert(); // always succeed Some(res) } } ) ) macro_rules! to_homogeneous_impl( ($t: ident, $th: ident) => ( impl ToHomogeneous<$th> for $t { fn to_homogeneous(&self) -> $th { let mut res = self.rotation.to_homogeneous(); // copy the translation let dim = Dim::dim(None::<$th>); res.set_col(dim - 1, self.translation.to_homogeneous()); res } } ) ) macro_rules! approx_eq_impl( ($t: ident) => ( impl> ApproxEq for $t { #[inline] fn approx_epsilon() -> N { fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.") // ApproxEq::::approx_epsilon() } #[inline] fn approx_eq(&self, other: &$t) -> bool { self.rotation.approx_eq(&other.rotation) && self.translation.approx_eq(&other.translation) } #[inline] fn approx_eq_eps(&self, other: &$t, epsilon: &N) -> bool { self.rotation.approx_eq_eps(&other.rotation, epsilon) && self.translation.approx_eq_eps(&other.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) } } ) )