2014-04-02 04:58:06 +08:00
|
|
|
#![macro_escape]
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
|
|
macro_rules! submat_impl(
|
|
|
|
($t: ident, $submat: ident) => (
|
|
|
|
impl<N> $t<N> {
|
|
|
|
#[inline]
|
|
|
|
pub fn submat<'r>(&'r self) -> &'r $submat<N> {
|
2014-07-05 16:24:43 +08:00
|
|
|
&self.submat
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! rotate_impl(
|
2014-10-10 17:23:52 +08:00
|
|
|
($trhs: ident, $t: ident, $tv: ident, $tp: ident) => (
|
|
|
|
/*
|
|
|
|
* FIXME: we use the double dispatch trick here so that we can rotate vectors _and_
|
|
|
|
* points. Remove this as soon as rust supports multidispatch.
|
|
|
|
*/
|
|
|
|
pub trait $trhs<N> {
|
|
|
|
fn rotate(left: &$t<N>, right: &Self) -> Self;
|
|
|
|
fn inv_rotate(left: &$t<N>, right: &Self) -> Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, V: $trhs<N>> Rotate<V> for $t<N> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn rotate(&self, other: &V) -> V {
|
|
|
|
$trhs::rotate(self, other)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn inv_rotate(&self, other: &V) -> V {
|
|
|
|
$trhs::inv_rotate(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $trhs<N> for $tv<N> {
|
2014-10-10 17:23:52 +08:00
|
|
|
#[inline]
|
|
|
|
fn rotate(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
|
2014-11-06 21:20:59 +08:00
|
|
|
*t * *v
|
2014-10-10 17:23:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn inv_rotate(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
|
2014-11-06 21:20:59 +08:00
|
|
|
*v * *t
|
2014-10-10 17:23:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $trhs<N> for $tp<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
2014-10-10 17:23:52 +08:00
|
|
|
fn rotate(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
|
2014-11-06 21:20:59 +08:00
|
|
|
*t * *p
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-10 17:23:52 +08:00
|
|
|
fn inv_rotate(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
|
2014-11-06 21:20:59 +08:00
|
|
|
*p * *t
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! transform_impl(
|
2014-10-10 17:23:52 +08:00
|
|
|
($trhs: ident, $t: ident, $tv: ident, $tp: ident) => (
|
|
|
|
/*
|
|
|
|
* FIXME: we use the double dispatch trick here so that we can transform vectors _and_
|
|
|
|
* points. Remove this as soon as rust supports multidispatch.
|
|
|
|
*/
|
|
|
|
pub trait $trhs<N> {
|
|
|
|
fn transform(left: &$t<N>, right: &Self) -> Self;
|
|
|
|
fn inv_transform(left: &$t<N>, right: &Self) -> Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, V: $trhs<N>> Transform<V> for $t<N> {
|
|
|
|
#[inline(always)]
|
|
|
|
fn transform(&self, other: &V) -> V {
|
|
|
|
$trhs::transform(self, other)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn inv_transform(&self, other: &V) -> V {
|
|
|
|
$trhs::inv_transform(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $trhs<N> for $tv<N> {
|
2014-10-10 17:23:52 +08:00
|
|
|
#[inline]
|
|
|
|
fn transform(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
|
|
|
|
t.rotate(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn inv_transform(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
|
|
|
|
t.inv_rotate(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $trhs<N> for $tp<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
2014-10-10 17:23:52 +08:00
|
|
|
fn transform(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
|
|
|
|
t.rotate(p)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-10 17:23:52 +08:00
|
|
|
fn inv_transform(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
|
|
|
|
t.inv_rotate(p)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! dim_impl(
|
|
|
|
($t: ident, $dim: expr) => (
|
|
|
|
impl<N> Dim for $t<N> {
|
|
|
|
#[inline]
|
|
|
|
fn dim(_: Option<$t<N>>) -> uint {
|
|
|
|
$dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! rotation_matrix_impl(
|
|
|
|
($t: ident, $tlv: ident, $tav: ident) => (
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: Zero + BaseNum + Cast<f64> + BaseFloat> RotationMatrix<N, $tlv<N>, $tav<N>, $t<N>> for $t<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
|
|
|
fn to_rot_mat(&self) -> $t<N> {
|
|
|
|
self.clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! one_impl(
|
|
|
|
($t: ident) => (
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> One for $t<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
|
|
|
fn one() -> $t<N> {
|
2014-11-16 21:04:15 +08:00
|
|
|
$t { submat: ::one() }
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! rot_mul_rot_impl(
|
|
|
|
($t: ident, $mulrhs: ident) => (
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $mulrhs<N, $t<N>> for $t<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
|
|
|
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
|
|
|
$t { submat: left.submat * right.submat }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! rot_mul_vec_impl(
|
|
|
|
($t: ident, $tv: ident, $mulrhs: ident) => (
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $mulrhs<N, $tv<N>> for $tv<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
|
|
|
fn binop(left: &$t<N>, right: &$tv<N>) -> $tv<N> {
|
|
|
|
left.submat * *right
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2014-10-10 17:23:52 +08:00
|
|
|
macro_rules! rot_mul_pnt_impl(
|
|
|
|
($t: ident, $tv: ident, $mulrhs: ident) => (
|
|
|
|
rot_mul_vec_impl!($t, $tv, $mulrhs)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
macro_rules! vec_mul_rot_impl(
|
|
|
|
($t: ident, $tv: ident, $mulrhs: ident) => (
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> $mulrhs<N, $tv<N>> for $t<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
|
|
|
fn binop(left: &$tv<N>, right: &$t<N>) -> $tv<N> {
|
|
|
|
*left * right.submat
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2014-10-10 17:23:52 +08:00
|
|
|
macro_rules! pnt_mul_rot_impl(
|
|
|
|
($t: ident, $tv: ident, $mulrhs: ident) => (
|
|
|
|
vec_mul_rot_impl!($t, $tv, $mulrhs)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
macro_rules! inv_impl(
|
|
|
|
($t: ident) => (
|
|
|
|
impl<N: Clone> Inv for $t<N> {
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn inv(&mut self) -> bool {
|
2013-10-06 22:54:09 +08:00
|
|
|
self.transpose();
|
|
|
|
|
|
|
|
// always succeed
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn inv_cpy(m: &$t<N>) -> Option<$t<N>> {
|
2013-10-06 22:54:09 +08:00
|
|
|
// always succeed
|
2013-10-14 16:22:32 +08:00
|
|
|
Some(Transpose::transpose_cpy(m))
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! transpose_impl(
|
|
|
|
($t: ident) => (
|
|
|
|
impl<N: Clone> Transpose for $t<N> {
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn transpose_cpy(m: &$t<N>) -> $t<N> {
|
|
|
|
$t { submat: Transpose::transpose_cpy(&m.submat) }
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn transpose(&mut self) {
|
|
|
|
self.submat.transpose()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! row_impl(
|
|
|
|
($t: ident, $tv: ident) => (
|
|
|
|
impl<N: Clone + Zero> Row<$tv<N>> for $t<N> {
|
|
|
|
#[inline]
|
|
|
|
fn nrows(&self) -> uint {
|
|
|
|
self.submat.nrows()
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn row(&self, i: uint) -> $tv<N> {
|
|
|
|
self.submat.row(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn set_row(&mut self, i: uint, row: $tv<N>) {
|
|
|
|
self.submat.set_row(i, row);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! col_impl(
|
|
|
|
($t: ident, $tv: ident) => (
|
|
|
|
impl<N: Clone + Zero> Col<$tv<N>> for $t<N> {
|
|
|
|
#[inline]
|
|
|
|
fn ncols(&self) -> uint {
|
|
|
|
self.submat.ncols()
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn col(&self, i: uint) -> $tv<N> {
|
|
|
|
self.submat.col(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn set_col(&mut self, i: uint, col: $tv<N>) {
|
|
|
|
self.submat.set_col(i, col);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2014-09-18 10:20:36 +08:00
|
|
|
macro_rules! index_impl(
|
2014-10-26 05:02:16 +08:00
|
|
|
($t: ident) => (
|
|
|
|
impl<N> Index<(uint, uint), N> for $t<N> {
|
|
|
|
fn index(&self, i: &(uint, uint)) -> &N {
|
2014-09-18 10:20:36 +08:00
|
|
|
&self.submat[*i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-26 05:02:16 +08:00
|
|
|
impl<N> IndexMut<(uint, uint), N> for $t<N> {
|
|
|
|
fn index_mut(&mut self, i: &(uint, uint)) -> &mut N {
|
2014-09-18 10:20:36 +08:00
|
|
|
&mut self.submat[*i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
macro_rules! to_homogeneous_impl(
|
|
|
|
($t: ident, $tm: ident) => (
|
2014-11-16 21:04:15 +08:00
|
|
|
impl<N: BaseNum + Clone> ToHomogeneous<$tm<N>> for $t<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
2014-11-22 00:00:39 +08:00
|
|
|
fn to_homogeneous(&self) -> $tm<N> {
|
|
|
|
self.submat.to_homogeneous()
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! approx_eq_impl(
|
|
|
|
($t: ident) => (
|
|
|
|
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
|
|
|
#[inline]
|
2014-01-10 03:48:30 +08:00
|
|
|
fn approx_epsilon(_: Option<$t<N>>) -> N {
|
|
|
|
ApproxEq::approx_epsilon(None::<N>)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-01-10 03:48:30 +08:00
|
|
|
fn approx_eq(a: &$t<N>, b: &$t<N>) -> bool {
|
|
|
|
ApproxEq::approx_eq(&a.submat, &b.submat)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-01-10 03:48:30 +08:00
|
|
|
fn approx_eq_eps(a: &$t<N>, b: &$t<N>, epsilon: &N) -> bool {
|
|
|
|
ApproxEq::approx_eq_eps(&a.submat, &b.submat, epsilon)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! absolute_impl(
|
|
|
|
($t: ident, $tm: ident) => (
|
2014-11-15 22:47:59 +08:00
|
|
|
impl<N: Absolute<N>> Absolute<$tm<N>> for $t<N> {
|
2013-10-06 22:54:09 +08:00
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
fn abs(m: &$t<N>) -> $tm<N> {
|
|
|
|
Absolute::abs(&m.submat)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|