2013-06-02 02:50:00 +08:00
|
|
|
use std::num::{One, Zero};
|
|
|
|
use std::rand::{Rand, Rng, RngUtil};
|
|
|
|
use std::cmp::ApproxEq;
|
2013-05-17 05:30:39 +08:00
|
|
|
use traits::dim::Dim;
|
|
|
|
use traits::inv::Inv;
|
2013-05-19 19:44:27 +08:00
|
|
|
use traits::rotation::Rotation;
|
|
|
|
use traits::translation::Translation;
|
2013-05-17 05:30:39 +08:00
|
|
|
use traits::transpose::Transpose;
|
2013-06-13 22:44:15 +08:00
|
|
|
use traits::delta_transform::{DeltaTransform, DeltaTransformVector};
|
2013-06-16 04:16:44 +08:00
|
|
|
use traits::rlmul::{RMul, LMul};
|
2013-05-17 05:30:39 +08:00
|
|
|
|
2013-05-26 02:30:03 +08:00
|
|
|
#[deriving(Eq, ToStr)]
|
2013-05-17 05:30:39 +08:00
|
|
|
pub struct Transform<M, V>
|
|
|
|
{
|
2013-05-20 03:45:30 +08:00
|
|
|
priv submat : M,
|
|
|
|
priv subtrans : V
|
2013-05-17 05:30:39 +08:00
|
|
|
}
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
impl<M: Copy, V: Copy> Transform<M, V>
|
|
|
|
{
|
|
|
|
#[inline(always)]
|
|
|
|
pub fn new(mat: &M, trans: &V) -> Transform<M, V>
|
|
|
|
{ Transform { submat: *mat, subtrans: *trans } }
|
|
|
|
}
|
2013-05-17 05:30:39 +08:00
|
|
|
|
|
|
|
impl<M:Dim, V> Dim for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn dim() -> uint
|
|
|
|
{ Dim::dim::<M>() }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<M:Copy + One, V:Copy + Zero> One for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn one() -> Transform<M, V>
|
|
|
|
{ Transform { submat: One::one(), subtrans: Zero::zero() } }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<M:Copy + Zero, V:Copy + Zero> Zero for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn zero() -> Transform<M, V>
|
|
|
|
{ Transform { submat: Zero::zero(), subtrans: Zero::zero() } }
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn is_zero(&self) -> bool
|
|
|
|
{ self.submat.is_zero() && self.subtrans.is_zero() }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<M:Copy + RMul<V> + Mul<M, M>, V:Copy + Add<V, V>>
|
|
|
|
Mul<Transform<M, V>, Transform<M, V>> for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn mul(&self, other: &Transform<M, V>) -> Transform<M, V>
|
|
|
|
{
|
|
|
|
Transform { submat: self.submat * other.submat,
|
|
|
|
subtrans: self.subtrans + self.submat.rmul(&other.subtrans) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 22:44:15 +08:00
|
|
|
impl<M: RMul<V>, V: Add<V, V>> RMul<V> for Transform<M, V>
|
2013-05-17 05:30:39 +08:00
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn rmul(&self, other: &V) -> V
|
2013-06-13 22:44:15 +08:00
|
|
|
{ self.submat.rmul(other) + self.subtrans }
|
2013-05-17 05:30:39 +08:00
|
|
|
}
|
|
|
|
|
2013-06-13 22:44:15 +08:00
|
|
|
impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V>
|
2013-05-17 05:30:39 +08:00
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn lmul(&self, other: &V) -> V
|
2013-06-13 22:44:15 +08:00
|
|
|
{ self.submat.lmul(other) + self.subtrans }
|
2013-05-17 05:30:39 +08:00
|
|
|
}
|
|
|
|
|
2013-05-19 19:44:27 +08:00
|
|
|
impl<M: Copy, V: Copy + Translation<V>> Translation<V> for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-19 19:44:27 +08:00
|
|
|
fn translation(&self) -> V
|
|
|
|
{ self.subtrans.translation() }
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-19 19:44:27 +08:00
|
|
|
fn translated(&self, t: &V) -> Transform<M, V>
|
2013-06-14 00:48:28 +08:00
|
|
|
{ Transform::new(&self.submat, &self.subtrans.translated(t)) }
|
2013-05-19 19:44:27 +08:00
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-19 19:44:27 +08:00
|
|
|
fn translate(&mut self, t: &V)
|
|
|
|
{ self.subtrans.translate(t) }
|
|
|
|
}
|
|
|
|
|
2013-06-09 00:33:49 +08:00
|
|
|
impl<M: Rotation<AV> + Copy + RMul<V> + One, V: Copy, AV>
|
|
|
|
Rotation<AV> for Transform<M, V>
|
2013-05-19 19:44:27 +08:00
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-06-09 00:33:49 +08:00
|
|
|
fn rotation(&self) -> AV
|
2013-05-19 19:44:27 +08:00
|
|
|
{ self.submat.rotation() }
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-06-09 00:33:49 +08:00
|
|
|
fn rotated(&self, rot: &AV) -> Transform<M, V>
|
2013-05-19 23:01:38 +08:00
|
|
|
{
|
|
|
|
// FIXME: this does not seem opitmal
|
|
|
|
let delta = One::one::<M>().rotated(rot);
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
Transform::new(&self.submat.rotated(rot), &delta.rmul(&self.subtrans))
|
2013-05-19 23:01:38 +08:00
|
|
|
}
|
2013-05-19 19:44:27 +08:00
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-06-09 00:33:49 +08:00
|
|
|
fn rotate(&mut self, rot: &AV)
|
2013-05-19 23:01:38 +08:00
|
|
|
{
|
|
|
|
// FIXME: this does not seem opitmal
|
|
|
|
let delta = One::one::<M>().rotated(rot);
|
|
|
|
self.submat.rotate(rot);
|
|
|
|
self.subtrans = delta.rmul(&self.subtrans);
|
|
|
|
}
|
2013-05-19 19:44:27 +08:00
|
|
|
}
|
|
|
|
|
2013-05-20 03:45:30 +08:00
|
|
|
impl<M: Copy, V> DeltaTransform<M> for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-20 03:45:30 +08:00
|
|
|
fn delta_transform(&self) -> M
|
|
|
|
{ self.submat }
|
|
|
|
}
|
|
|
|
|
2013-06-13 22:44:15 +08:00
|
|
|
impl<M: RMul<V> + Copy, V> DeltaTransformVector<V> for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-06-13 22:44:15 +08:00
|
|
|
fn delta_transform_vector(&self, v: &V) -> V
|
|
|
|
{ self.submat.rmul(v) }
|
|
|
|
}
|
|
|
|
|
2013-05-17 05:30:39 +08:00
|
|
|
impl<M:Copy + Transpose + Inv + RMul<V>, V:Copy + Neg<V>>
|
|
|
|
Inv for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn invert(&mut self)
|
|
|
|
{
|
|
|
|
self.submat.invert();
|
|
|
|
self.subtrans = self.submat.rmul(&-self.subtrans);
|
|
|
|
}
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-17 05:30:39 +08:00
|
|
|
fn inverse(&self) -> Transform<M, V>
|
|
|
|
{
|
|
|
|
let mut res = *self;
|
|
|
|
|
|
|
|
res.invert();
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-10 07:36:47 +08:00
|
|
|
impl<N: ApproxEq<N>, M:ApproxEq<N>, V:ApproxEq<N>>
|
|
|
|
ApproxEq<N> for Transform<M, V>
|
2013-05-17 06:23:25 +08:00
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-06-10 07:36:47 +08:00
|
|
|
fn approx_epsilon() -> N
|
|
|
|
{ ApproxEq::approx_epsilon::<N, N>() }
|
2013-05-21 23:25:01 +08:00
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-21 23:25:01 +08:00
|
|
|
fn approx_eq(&self, other: &Transform<M, V>) -> bool
|
2013-05-17 06:23:25 +08:00
|
|
|
{
|
2013-05-21 23:25:01 +08:00
|
|
|
self.submat.approx_eq(&other.submat) &&
|
|
|
|
self.subtrans.approx_eq(&other.subtrans)
|
2013-05-17 06:23:25 +08:00
|
|
|
}
|
|
|
|
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-06-10 07:36:47 +08:00
|
|
|
fn approx_eq_eps(&self, other: &Transform<M, V>, epsilon: &N) -> bool
|
2013-05-17 06:23:25 +08:00
|
|
|
{
|
2013-05-21 23:25:01 +08:00
|
|
|
self.submat.approx_eq_eps(&other.submat, epsilon) &&
|
|
|
|
self.subtrans.approx_eq_eps(&other.subtrans, epsilon)
|
2013-05-17 06:23:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-18 08:11:59 +08:00
|
|
|
impl<M: Rand + Copy, V: Rand + Copy> Rand for Transform<M, V>
|
|
|
|
{
|
2013-06-14 00:48:28 +08:00
|
|
|
#[inline(always)]
|
2013-05-21 23:25:01 +08:00
|
|
|
fn rand<R: Rng>(rng: &mut R) -> Transform<M, V>
|
2013-06-14 00:48:28 +08:00
|
|
|
{ Transform::new(&rng.gen(), &rng.gen()) }
|
2013-05-18 08:11:59 +08:00
|
|
|
}
|