Add `Absolute`, `Col`, `Mat`, `AbsoluteRotate` traits.
Traits like `AbsoluteRotate` and `RotationWithTranslation` have been moved to a `comp` folder containing any trait providing operations which are combination of several traits.
This commit is contained in:
parent
00f26f8951
commit
6f81fc6d5c
|
@ -5,15 +5,18 @@ use traits::rlmul::{RMul, LMul};
|
|||
use traits::cross::Cross;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::row::Row;
|
||||
use traits::col::Col;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::rotation::{Rotation, Rotate};
|
||||
use traits::absolute::Absolute;
|
||||
use traits::rotation::{Rotation, Rotate, RotationMatrix};
|
||||
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
|
||||
use traits::homogeneous::ToHomogeneous;
|
||||
use traits::indexable::Indexable;
|
||||
use traits::norm::Norm;
|
||||
use vec::Vec1;
|
||||
use traits::comp::absolute_rotate::AbsoluteRotate;
|
||||
use vec::{Vec1, Vec2, Vec3};
|
||||
use mat::{Mat2, Mat3};
|
||||
use vec::Vec3;
|
||||
|
||||
/// Matrix wrapper representing rotation matrix. It is built uppon another matrix and ensures (at
|
||||
/// the type-level) that it will always represent a rotation. Rotation matrices have some
|
||||
|
@ -120,6 +123,14 @@ impl<N: Clone + Num + Algebraic> Rotmat<Mat3<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + Num + Clone>
|
||||
RotationMatrix<Vec2<N>, Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> {
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> Rotmat<Mat2<N>> {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + Num + Clone>
|
||||
Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
|
||||
#[inline]
|
||||
|
@ -148,6 +159,14 @@ Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: NumCast + Algebraic + Trigonometric + Num + Clone>
|
||||
RotationMatrix<Vec3<N>, Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>> {
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> Rotmat<Mat3<N>> {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Trigonometric + Num + Algebraic + NumCast>
|
||||
Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
|
||||
#[inline]
|
||||
|
@ -304,8 +323,42 @@ Transpose for Rotmat<M> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<M: Row<R>, R> Row<R> for Rotmat<M> {
|
||||
#[inline]
|
||||
fn num_rows(&self) -> uint {
|
||||
self.submat.num_rows()
|
||||
}
|
||||
#[inline]
|
||||
fn row(&self, i: uint) -> R {
|
||||
self.submat.row(i)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: uint, row: R) {
|
||||
self.submat.set_row(i, row);
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Col<C>, C> Col<C> for Rotmat<M> {
|
||||
#[inline]
|
||||
fn num_cols(&self) -> uint {
|
||||
self.submat.num_cols()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn col(&self, i: uint) -> C {
|
||||
self.submat.col(i)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_col(&mut self, i: uint, col: C) {
|
||||
self.submat.set_col(i, col);
|
||||
}
|
||||
}
|
||||
|
||||
// we loose the info that we are a rotation matrix
|
||||
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M> {
|
||||
#[inline]
|
||||
fn to_homogeneous(&self) -> M2 {
|
||||
self.submat.to_homogeneous()
|
||||
}
|
||||
|
@ -328,3 +381,33 @@ impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M> {
|
|||
self.submat.approx_eq_eps(&other.submat, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Absolute<M2>, M2> Absolute<M2> for Rotmat<M> {
|
||||
#[inline]
|
||||
fn absolute(&self) -> M2 {
|
||||
self.submat.absolute()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Signed> AbsoluteRotate<Vec3<N>> for Rotmat<Mat3<N>> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &Vec3<N>) -> Vec3<N> {
|
||||
Vec3::new(
|
||||
self.submat.m11.abs() * v.x + self.submat.m12.abs() * v.y + self.submat.m13.abs() * v.z,
|
||||
self.submat.m21.abs() * v.x + self.submat.m22.abs() * v.y + self.submat.m23.abs() * v.z,
|
||||
self.submat.m31.abs() * v.x + self.submat.m32.abs() * v.y + self.submat.m33.abs() * v.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Signed> AbsoluteRotate<Vec2<N>> for Rotmat<Mat2<N>> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &Vec2<N>) -> Vec2<N> {
|
||||
// the matrix is skew-symetric, so we dont need to compute the absolute value of every
|
||||
// component.
|
||||
let m11 = self.submat.m11.abs();
|
||||
let m12 = self.submat.m12.abs();
|
||||
let m22 = self.submat.m22.abs();
|
||||
|
||||
Vec2::new(m11 * v.x + m12 * v.y, m12 * v.x + m22 * v.y)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,17 @@ use std::num::{One, Zero};
|
|||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::dim::Dim;
|
||||
use traits::absolute::Absolute;
|
||||
use traits::mat::Mat;
|
||||
use traits::inv::Inv;
|
||||
use traits::rotation::{Rotation, Rotate};
|
||||
use traits::rotation::{Rotation, Rotate, RotationMatrix};
|
||||
use traits::translation::{Translation, Translate};
|
||||
use Ts = traits::transformation::Transform;
|
||||
use traits::transformation::{Transformation};
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
||||
use traits::column::Column;
|
||||
use traits::comp::absolute_rotate::AbsoluteRotate;
|
||||
use adaptors::rotmat::Rotmat;
|
||||
use vec::Vec3;
|
||||
use mat::Mat3;
|
||||
|
@ -53,6 +56,14 @@ impl<V: Clone, M: Clone> Transform<V, M> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<LV, AV, M: One + RMul<LV> + RotationMatrix<LV, AV, M2>, M2: Mat<LV, LV> + Rotation<AV>>
|
||||
RotationMatrix<LV, AV, M2> for Transform<LV, M> {
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> M2 {
|
||||
self.submat.to_rot_mat()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Num + Algebraic> Transform<Vec3<N>, Rotmat<Mat3<N>>> {
|
||||
/// Reorient and translate this transformation such that its local `x` axis points to a given
|
||||
/// direction. Note that the usually known `look_at` function does the same thing but with the
|
||||
|
@ -342,3 +353,18 @@ impl<M: Rand, V: Rand> Rand for Transform<V, M> {
|
|||
Transform::new(rng.gen(), rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Absolute<V2>, M: Absolute<M2>, V2, M2>
|
||||
Absolute<Transform<V2, M2>> for Transform<V, M> {
|
||||
#[inline]
|
||||
fn absolute(&self) -> Transform<V2, M2> {
|
||||
Transform::new(self.subtrans.absolute(), self.submat.absolute())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, M: AbsoluteRotate<V>> AbsoluteRotate<V> for Transform<V, M> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &V) -> V {
|
||||
self.submat.absolute_rotate(v)
|
||||
}
|
||||
}
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -29,16 +29,14 @@ mod vec0_spec;
|
|||
mod identity_spec;
|
||||
|
||||
/// Wrappers around raw matrices to restrict their behaviour.
|
||||
pub mod adaptors
|
||||
{
|
||||
pub mod adaptors {
|
||||
pub mod rotmat;
|
||||
pub mod transform;
|
||||
}
|
||||
|
||||
pub mod types;
|
||||
|
||||
pub mod traits
|
||||
{
|
||||
pub mod traits {
|
||||
pub mod vector;
|
||||
pub mod sample;
|
||||
pub mod indexable;
|
||||
|
@ -61,11 +59,21 @@ pub mod traits
|
|||
pub mod mat_cast;
|
||||
pub mod norm;
|
||||
pub mod dot;
|
||||
pub mod mat;
|
||||
pub mod absolute;
|
||||
pub mod col;
|
||||
|
||||
/// Unusual traits which are composition of other primitive traits.
|
||||
/// Those are mainly shortcuts to make some operation easier to use or faster.
|
||||
/// Mathematics purists should really not go in there!
|
||||
pub mod comp {
|
||||
pub mod rotation_with_translation;
|
||||
pub mod absolute_rotate;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests
|
||||
{
|
||||
pub mod tests {
|
||||
pub mod mat;
|
||||
pub mod vec;
|
||||
}
|
||||
|
|
40
src/mat.rs
40
src/mat.rs
|
@ -7,6 +7,8 @@ use std::vec::{VecIterator, VecMutIterator};
|
|||
use vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Outer};
|
||||
|
||||
// traits
|
||||
pub use traits::mat::Mat;
|
||||
pub use traits::absolute::Absolute;
|
||||
pub use traits::dim::Dim;
|
||||
pub use traits::indexable::Indexable;
|
||||
pub use traits::iterable::{Iterable, IterableMut};
|
||||
|
@ -15,12 +17,15 @@ pub use traits::mat_cast::MatCast;
|
|||
pub use traits::column::Column;
|
||||
pub use traits::inv::Inv;
|
||||
pub use traits::rlmul::{RMul, LMul};
|
||||
pub use traits::rotation::{Rotation, Rotate, RotationWithTranslation};
|
||||
pub use traits::rotation::{Rotation, RotationMatrix, Rotate};
|
||||
pub use traits::transformation::{Transformation, Transform};
|
||||
pub use traits::translation::{Translation, Translate};
|
||||
pub use traits::transpose::{Transpose};
|
||||
pub use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
||||
pub use traits::row::Row;
|
||||
pub use traits::col::Col;
|
||||
pub use traits::comp::rotation_with_translation::RotationWithTranslation;
|
||||
pub use traits::comp::absolute_rotate::AbsoluteRotate;
|
||||
|
||||
// structs
|
||||
pub use dmat::DMat;
|
||||
|
@ -57,6 +62,7 @@ scalar_mul_impl!(Mat1, m11)
|
|||
scalar_div_impl!(Mat1, m11)
|
||||
scalar_add_impl!(Mat1, m11)
|
||||
scalar_sub_impl!(Mat1, m11)
|
||||
absolute_impl!(Mat1, m11)
|
||||
one_impl!(Mat1, One::one)
|
||||
iterable_impl!(Mat1, 1)
|
||||
iterable_mut_impl!(Mat1, 1)
|
||||
|
@ -71,6 +77,7 @@ transpose_impl!(Mat1, 1)
|
|||
approx_eq_impl!(Mat1)
|
||||
column_impl!(Mat1, Vec1, 1)
|
||||
row_impl!(Mat1, Vec1, 1)
|
||||
col_impl!(Mat1, Vec1, 1)
|
||||
to_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||
from_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||
outer_impl!(Vec1, Mat1)
|
||||
|
@ -98,6 +105,8 @@ scalar_add_impl!(Mat2, m11, m12,
|
|||
m21, m22)
|
||||
scalar_sub_impl!(Mat2, m11, m12,
|
||||
m21, m22)
|
||||
absolute_impl!(Mat2, m11, m12,
|
||||
m21, m22)
|
||||
one_impl!(Mat2, One::one, Zero::zero,
|
||||
Zero::zero, One::one)
|
||||
iterable_impl!(Mat2, 2)
|
||||
|
@ -113,6 +122,7 @@ transpose_impl!(Mat2, 2)
|
|||
approx_eq_impl!(Mat2)
|
||||
column_impl!(Mat2, Vec2, 2)
|
||||
row_impl!(Mat2, Vec2, 2)
|
||||
col_impl!(Mat2, Vec2, 2)
|
||||
to_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||
from_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||
outer_impl!(Vec2, Mat2)
|
||||
|
@ -149,6 +159,9 @@ scalar_add_impl!(Mat3, m11, m12, m13,
|
|||
scalar_sub_impl!(Mat3, m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33)
|
||||
absolute_impl!(Mat3, m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33)
|
||||
one_impl!(Mat3, One::one , Zero::zero, Zero::zero,
|
||||
Zero::zero, One::one , Zero::zero,
|
||||
Zero::zero, Zero::zero, One::one)
|
||||
|
@ -165,6 +178,7 @@ transpose_impl!(Mat3, 3)
|
|||
approx_eq_impl!(Mat3)
|
||||
column_impl!(Mat3, Vec3, 3)
|
||||
// (specialized) row_impl!(Mat3, Vec3, 3)
|
||||
// (specialized) col_impl!(Mat3, Vec3, 3)
|
||||
to_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||
from_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||
outer_impl!(Vec3, Mat3)
|
||||
|
@ -226,6 +240,12 @@ scalar_sub_impl!(Mat4,
|
|||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
)
|
||||
absolute_impl!(Mat4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
)
|
||||
one_impl!(Mat4, One::one , Zero::zero, Zero::zero, Zero::zero,
|
||||
Zero::zero, One::one , Zero::zero, Zero::zero,
|
||||
Zero::zero, Zero::zero, One::one , Zero::zero,
|
||||
|
@ -243,6 +263,7 @@ transpose_impl!(Mat4, 4)
|
|||
approx_eq_impl!(Mat4)
|
||||
column_impl!(Mat4, Vec4, 4)
|
||||
row_impl!(Mat4, Vec4, 4)
|
||||
col_impl!(Mat4, Vec4, 4)
|
||||
to_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||
from_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||
outer_impl!(Vec4, Mat4)
|
||||
|
@ -271,6 +292,13 @@ mat_cast_impl!(Mat5,
|
|||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
)
|
||||
absolute_impl!(Mat5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
)
|
||||
one_impl!(Mat5,
|
||||
One::one , Zero::zero, Zero::zero, Zero::zero, Zero::zero,
|
||||
Zero::zero, One::one , Zero::zero, Zero::zero, Zero::zero,
|
||||
|
@ -333,6 +361,7 @@ transpose_impl!(Mat5, 5)
|
|||
approx_eq_impl!(Mat5)
|
||||
column_impl!(Mat5, Vec5, 5)
|
||||
row_impl!(Mat5, Vec5, 5)
|
||||
col_impl!(Mat5, Vec5, 5)
|
||||
to_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||
from_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||
outer_impl!(Vec5, Mat5)
|
||||
|
@ -412,6 +441,14 @@ scalar_sub_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
)
|
||||
absolute_impl!(Mat6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
m41, m42, m43, m44, m45, m46,
|
||||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
)
|
||||
one_impl!(Mat6,
|
||||
One::one , Zero::zero, Zero::zero, Zero::zero, Zero::zero, Zero::zero,
|
||||
Zero::zero, One::one , Zero::zero, Zero::zero, Zero::zero, Zero::zero,
|
||||
|
@ -433,4 +470,5 @@ transpose_impl!(Mat6, 6)
|
|||
approx_eq_impl!(Mat6)
|
||||
column_impl!(Mat6, Vec6, 6)
|
||||
row_impl!(Mat6, Vec6, 6)
|
||||
col_impl!(Mat6, Vec6, 6)
|
||||
outer_impl!(Vec6, Mat6)
|
||||
|
|
|
@ -105,6 +105,17 @@ macro_rules! scalar_sub_impl(
|
|||
)
|
||||
)
|
||||
|
||||
macro_rules! absolute_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Signed> Absolute<$t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn absolute(&self) -> $t<N> {
|
||||
$t::new(self.$comp0.abs() $(, self.$compN.abs() )*)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! iterable_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> Iterable<N> for $t<N> {
|
||||
|
@ -208,6 +219,11 @@ macro_rules! column_impl(
|
|||
macro_rules! row_impl(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Clone + Zero> Row<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn num_rows(&self) -> uint {
|
||||
Dim::dim(None::<$t<N>>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, row: uint, v: $tv<N>) {
|
||||
for (i, e) in v.iter().enumerate() {
|
||||
|
@ -229,6 +245,35 @@ macro_rules! row_impl(
|
|||
)
|
||||
)
|
||||
|
||||
macro_rules! col_impl(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Clone + Zero> Col<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn num_cols(&self) -> uint {
|
||||
Dim::dim(None::<$t<N>>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_col(&mut self, col: uint, v: $tv<N>) {
|
||||
for (i, e) in v.iter().enumerate() {
|
||||
self.set((col, i), e.clone());
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn col(&self, col: uint) -> $tv<N> {
|
||||
let mut res: $tv<N> = Zero::zero();
|
||||
|
||||
for (i, e) in res.mut_iter().enumerate() {
|
||||
*e = self.at((i, col));
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! mul_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Clone + Num> Mul<$t<N>, $t<N>> for $t<N> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::num::{Zero, One};
|
||||
use vec::Vec3;
|
||||
use mat::{Mat1, Mat2, Mat3, Inv, Row};
|
||||
use mat::{Mat1, Mat2, Mat3, Inv, Row, Col};
|
||||
use mat;
|
||||
|
||||
// some specializations:
|
||||
|
@ -110,6 +110,11 @@ Inv for Mat3<N> {
|
|||
}
|
||||
|
||||
impl<N: Clone> Row<Vec3<N>> for Mat3<N> {
|
||||
#[inline]
|
||||
fn num_rows(&self) -> uint {
|
||||
3
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn row(&self, i: uint) -> Vec3<N> {
|
||||
match i {
|
||||
|
@ -144,6 +149,46 @@ impl<N: Clone> Row<Vec3<N>> for Mat3<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone> Col<Vec3<N>> for Mat3<N> {
|
||||
#[inline]
|
||||
fn num_cols(&self) -> uint {
|
||||
3
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn col(&self, i: uint) -> Vec3<N> {
|
||||
match i {
|
||||
0 => Vec3::new(self.m11.clone(), self.m21.clone(), self.m31.clone()),
|
||||
1 => Vec3::new(self.m12.clone(), self.m22.clone(), self.m32.clone()),
|
||||
2 => Vec3::new(self.m13.clone(), self.m23.clone(), self.m33.clone()),
|
||||
_ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " cols.")
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_col(&mut self, i: uint, r: Vec3<N>) {
|
||||
match i {
|
||||
0 => {
|
||||
self.m11 = r.x.clone();
|
||||
self.m21 = r.y.clone();
|
||||
self.m31 = r.z;
|
||||
},
|
||||
1 => {
|
||||
self.m12 = r.x.clone();
|
||||
self.m22 = r.y.clone();
|
||||
self.m32 = r.z;
|
||||
},
|
||||
2 => {
|
||||
self.m13 = r.x.clone();
|
||||
self.m23 = r.y.clone();
|
||||
self.m33 = r.z;
|
||||
},
|
||||
_ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " cols.")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: move this to another file?
|
||||
impl<N: Real + NumCast + Zero + One> mat::Mat4<N> {
|
||||
/// Computes a projection matrix given the frustrum near plane width, height, the field of
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/// Trait of objects having an absolute value.
|
||||
/// This is useful of the object and the absolute value do not have the same type.
|
||||
pub trait Absolute<A> {
|
||||
/// Compute some absolute representation of this object.
|
||||
/// Typically, this will make all component of a matrix or vector positive.
|
||||
fn absolute(&self) -> A;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/// Traits to access columns of a matrix or vector.
|
||||
pub trait Col<C> {
|
||||
/// The number of columun of this matrix or vector.
|
||||
fn num_cols(&self) -> uint;
|
||||
/// Reads the `i`-th column of `self`.
|
||||
fn col(&self, i: uint) -> C;
|
||||
/// Writes the `i`-th column of `self`.
|
||||
fn set_col(&mut self, i: uint, C);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/// Trait of matrices having the following operation:
|
||||
///
|
||||
/// self.absolute_rotate(v) = self.rotation_matrix().absolute().rmul(v)
|
||||
///
|
||||
/// The operation is accessible using the `RotationMatrix`, `Absolute`, and `RMul` traits, but
|
||||
/// doing so is not easy in generic code as it can be a cause of type over-parametrization.
|
||||
///
|
||||
/// # Known use case:
|
||||
/// * to compute efficiently the AABB of a rotated AABB.
|
||||
pub trait AbsoluteRotate<V> {
|
||||
|
||||
/// This is the same as:
|
||||
///
|
||||
/// self.absolute_rotate(v) = self.rotation_matrix().absolute().rmul(v)
|
||||
fn absolute_rotate(&self, &V) -> V;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
use traits::rotation::Rotation;
|
||||
use traits::translation::Translation;
|
||||
|
||||
// NOTE: we cannot call this an Isometry since an isometry really does not need to have a rotation
|
||||
// nor a translation (this can be a reflexion).
|
||||
/// Utilities to make rotations with regard to a point different than the origin.
|
||||
/// All those operations are the composition of rotations and translations.
|
||||
/// This could be implemented in term of the `Rotation` and `Translation` traits, but having those
|
||||
/// here make it easier to use.
|
||||
///
|
||||
/// # Known use case:
|
||||
/// * to change the center of a rotation.
|
||||
pub trait RotationWithTranslation<LV: Neg<LV>, AV>: Rotation<AV> + Translation<LV> {
|
||||
/**
|
||||
* Applies a rotation centered on a specific point.
|
||||
*
|
||||
* - `m`: the object to be rotated.
|
||||
* - `ammount`: the rotation to apply.
|
||||
* - `point`: the center of rotation.
|
||||
*/
|
||||
#[inline]
|
||||
fn rotated_wrt_point(&self, ammount: &AV, center: &LV) -> Self {
|
||||
let mut res = self.translated(&-center);
|
||||
|
||||
res.rotate_by(ammount);
|
||||
res.translate_by(center);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/// Rotates an object using a specific center of rotation.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `m` - the object to be rotated
|
||||
/// * `ammount` - the rotation to be applied
|
||||
/// * `center` - the new center of rotation
|
||||
#[inline]
|
||||
fn rotate_wrt_point(&mut self, ammount: &AV, center: &LV) {
|
||||
self.translate_by(&-center);
|
||||
self.rotate_by(ammount);
|
||||
self.translate_by(center);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a rotation centered on the input translation.
|
||||
*
|
||||
* # Arguments
|
||||
* * `m` - the object to be rotated.
|
||||
* * `ammount` - the rotation to apply.
|
||||
*/
|
||||
#[inline]
|
||||
fn rotated_wrt_center(&self, ammount: &AV) -> Self {
|
||||
self.rotated_wrt_point(ammount, &self.translation())
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a rotation centered on the input translation.
|
||||
*
|
||||
* # Arguments
|
||||
* * `m` - the object to be rotated.
|
||||
* * `ammount` - the rotation to apply.
|
||||
*/
|
||||
#[inline]
|
||||
fn rotate_wrt_center(&mut self, ammount: &AV) {
|
||||
let center = self.translation();
|
||||
self.rotate_wrt_point(ammount, ¢er)
|
||||
}
|
||||
}
|
||||
|
||||
impl<LV: Neg<LV>, AV, M: Rotation<AV> + Translation<LV>> RotationWithTranslation<LV, AV> for M;
|
|
@ -0,0 +1,8 @@
|
|||
use traits::row::Row;
|
||||
use traits::col::Col;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
|
||||
/// Trait of matrix. A matrix must have lines and columns.
|
||||
pub trait Mat<R, C> : Row<R> + Col<C> + RMul<R> + LMul<C> { }
|
||||
|
||||
impl<M: Row<R> + Col<C> + RMul<R> + LMul<C>, R, C> Mat<R, C> for M;
|
|
@ -1,4 +1,4 @@
|
|||
use traits::translation::Translation;
|
||||
use traits::mat::Mat;
|
||||
|
||||
/// Trait of object which represent a rotation, and to wich new rotations can
|
||||
/// be appended. A rotation is assumed to be an isomitry without translation
|
||||
|
@ -29,64 +29,9 @@ pub trait Rotate<V> {
|
|||
fn inv_rotate(&self, &V) -> V;
|
||||
}
|
||||
|
||||
/// Utilities to make rotations with regard to a point different than the origin.
|
||||
// NOTE: we cannot call this an Isometry since an isometry really does not need to have a rotation
|
||||
// nor a translation (this can be a reflexion).
|
||||
pub trait RotationWithTranslation<LV: Neg<LV>, AV>: Rotation<AV> + Translation<LV> {
|
||||
/**
|
||||
* Applies a rotation centered on a specific point.
|
||||
*
|
||||
* - `m`: the object to be rotated.
|
||||
* - `ammount`: the rotation to apply.
|
||||
* - `point`: the center of rotation.
|
||||
*/
|
||||
#[inline]
|
||||
fn rotated_wrt_point(&self, ammount: &AV, center: &LV) -> Self {
|
||||
let mut res = self.translated(&-center);
|
||||
|
||||
res.rotate_by(ammount);
|
||||
res.translate_by(center);
|
||||
|
||||
res
|
||||
/// Trait of transformation having a rotation extractable as a rotation matrix. This can typically
|
||||
/// be implemented by quaternions to convert them
|
||||
pub trait RotationMatrix<LV, AV, R: Mat<LV, LV> + Rotation<AV>> : Rotation<AV> {
|
||||
/// Gets the rotation matrix from this object.
|
||||
fn to_rot_mat(&self) -> R;
|
||||
}
|
||||
|
||||
/// Rotates an object using a specific center of rotation.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `m` - the object to be rotated
|
||||
/// * `ammount` - the rotation to be applied
|
||||
/// * `center` - the new center of rotation
|
||||
#[inline]
|
||||
fn rotate_wrt_point(&mut self, ammount: &AV, center: &LV) {
|
||||
self.translate_by(&-center);
|
||||
self.rotate_by(ammount);
|
||||
self.translate_by(center);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a rotation centered on the input translation.
|
||||
*
|
||||
* # Arguments
|
||||
* * `m` - the object to be rotated.
|
||||
* * `ammount` - the rotation to apply.
|
||||
*/
|
||||
#[inline]
|
||||
fn rotated_wrt_center(&self, ammount: &AV) -> Self {
|
||||
self.rotated_wrt_point(ammount, &self.translation())
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a rotation centered on the input translation.
|
||||
*
|
||||
* # Arguments
|
||||
* * `m` - the object to be rotated.
|
||||
* * `ammount` - the rotation to apply.
|
||||
*/
|
||||
#[inline]
|
||||
fn rotate_wrt_center(&mut self, ammount: &AV) {
|
||||
let center = self.translation();
|
||||
self.rotate_wrt_point(ammount, ¢er)
|
||||
}
|
||||
}
|
||||
|
||||
impl<LV: Neg<LV>, AV, M: Rotation<AV> + Translation<LV>> RotationWithTranslation<LV, AV> for M;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/// Traits to access rows of a matrix or vector.
|
||||
pub trait Row<R> {
|
||||
/// The number of columun of this matrix or vector.
|
||||
fn num_rows(&self) -> uint;
|
||||
/// Reads the `i`-th row of `self`.
|
||||
fn row(&self, i: uint) -> R;
|
||||
/// Writes the `i`-th row of `self`.
|
||||
|
|
|
@ -41,6 +41,11 @@ impl<N: Neg<N> + Zero + Clone> CrossMatrix<Mat3<N>> for Vec3<N> {
|
|||
|
||||
// FIXME: iplement this for all other vectors
|
||||
impl<N: Clone> Row<Vec1<N>> for Vec2<N> {
|
||||
#[inline]
|
||||
fn num_rows(&self) -> uint {
|
||||
2
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn row(&self, i: uint) -> Vec1<N> {
|
||||
match i {
|
||||
|
|
Loading…
Reference in New Issue