Fix look_at matrices + implement Display for statically sized structures.
This commit is contained in:
parent
60c0f32e1c
commit
02001667f7
|
@ -1,3 +1,4 @@
|
|||
use std::fmt;
|
||||
use std::ops::{Add, Sub, Mul, Neg};
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
|
@ -44,33 +45,37 @@ pub struct Iso3<N> {
|
|||
}
|
||||
|
||||
impl<N: Clone + BaseFloat> Iso3<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
|
||||
/// `z` axis. See `look_at_z` for that.
|
||||
/// Creates an isometry that corresponds to the local frame of an observer standing at the
|
||||
/// point `eye` and looking toward `target`.
|
||||
///
|
||||
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
|
||||
/// `eye`.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The new translation of the transformation.
|
||||
/// * at - The point to look at. `at - eye` is the direction the matrix `x` axis will be
|
||||
/// aligned with.
|
||||
/// * up - Vector pointing up. The only requirement of this parameter is to not be colinear
|
||||
/// with `at`. Non-colinearity is not checked.
|
||||
/// * eye - The observer position.
|
||||
/// * target - The target position.
|
||||
/// * up - Vertical direction. The only requirement of this parameter is to not be collinear
|
||||
/// to `eye - at`. Non-collinearity is not checked.
|
||||
#[inline]
|
||||
pub fn look_at(eye: &Pnt3<N>, at: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
Iso3::new_with_rotmat(eye.as_vec().clone(), Rot3::look_at(&(*at - *eye), up))
|
||||
pub fn new_observer_frame(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
let new_rotmat = Rot3::new_observer_frame(&(*target - *eye), up);
|
||||
Iso3::new_with_rotmat(eye.as_vec().clone(), new_rotmat)
|
||||
}
|
||||
|
||||
/// Reorient and translate this transformation such that its local `z` axis points to a given
|
||||
/// direction.
|
||||
/// Builds a look-at view matrix.
|
||||
///
|
||||
/// This conforms to the common notion of "look-at" matrix from the computer graphics
|
||||
/// community. Its maps the view direction `target - eye` to the **negative** `z` axis and the
|
||||
/// `eye` to the origin.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The new translation of the transformation.
|
||||
/// * at - The point to look at. `at - eye` is the direction the matrix `x` axis will be
|
||||
/// aligned with
|
||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||
/// with `at`. Non-colinearity is not checked.
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - The vertical view direction. It must not be to collinear to `eye - target`.
|
||||
#[inline]
|
||||
pub fn look_at_z(eye: &Pnt3<N>, at: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
Iso3::new_with_rotmat(eye.as_vec().clone(), Rot3::look_at_z(&(*at - *eye), up))
|
||||
pub fn new_look_at(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
let new_rotmat = Rot3::new_look_at(&(*target - *eye), up);
|
||||
Iso3::new_with_rotmat(new_rotmat * (-*eye.as_vec()), new_rotmat)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,6 +100,7 @@ pnt_mul_iso_impl!(Iso2, Pnt2);
|
|||
iso_mul_vec_impl!(Iso2, Vec2);
|
||||
vec_mul_iso_impl!(Iso2, Vec2);
|
||||
arbitrary_iso_impl!(Iso2);
|
||||
iso_display_impl!(Iso2);
|
||||
|
||||
iso_impl!(Iso3, Rot3, Vec3, Vec3);
|
||||
rotation_matrix_impl!(Iso3, Rot3, Vec3, Vec3);
|
||||
|
@ -117,3 +123,4 @@ pnt_mul_iso_impl!(Iso3, Pnt3);
|
|||
iso_mul_vec_impl!(Iso3, Vec3);
|
||||
vec_mul_iso_impl!(Iso3, Vec3);
|
||||
arbitrary_iso_impl!(Iso3);
|
||||
iso_display_impl!(Iso3);
|
||||
|
|
|
@ -403,3 +403,26 @@ macro_rules! arbitrary_iso_impl(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! iso_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(writeln!(f, "Isometry {{"));
|
||||
|
||||
if let Some(precision) = f.precision() {
|
||||
try!(writeln!(f, "... translation: {:.*}", precision, self.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{:.*}", precision, *self.rotation.submat()));
|
||||
}
|
||||
else {
|
||||
try!(writeln!(f, "... translation: {}", self.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{}", *self.rotation.submat()));
|
||||
}
|
||||
|
||||
writeln!(f, "}}")
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![allow(missing_docs)] // we allow missing to avoid having to document the mij components.
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};
|
||||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
|
@ -82,6 +83,7 @@ eigen_qr_impl!(Mat1, Vec1);
|
|||
arbitrary_impl!(Mat1, m11);
|
||||
rand_impl!(Mat1, m11);
|
||||
mean_impl!(Mat1, Vec1, 1);
|
||||
mat_display_impl!(Mat1, 1);
|
||||
|
||||
/// Square matrix of dimension 2.
|
||||
#[repr(C)]
|
||||
|
@ -136,6 +138,7 @@ eigen_qr_impl!(Mat2, Vec2);
|
|||
arbitrary_impl!(Mat2, m11, m12, m21, m22);
|
||||
rand_impl!(Mat2, m11, m12, m21, m22);
|
||||
mean_impl!(Mat2, Vec2, 2);
|
||||
mat_display_impl!(Mat2, 2);
|
||||
|
||||
/// Square matrix of dimension 3.
|
||||
#[repr(C)]
|
||||
|
@ -233,6 +236,7 @@ rand_impl!(Mat3,
|
|||
m31, m32, m33
|
||||
);
|
||||
mean_impl!(Mat3, Vec3, 3);
|
||||
mat_display_impl!(Mat3, 3);
|
||||
|
||||
/// Square matrix of dimension 4.
|
||||
#[repr(C)]
|
||||
|
@ -353,6 +357,7 @@ rand_impl!(Mat4,
|
|||
m41, m42, m43, m44
|
||||
);
|
||||
mean_impl!(Mat4, Vec4, 4);
|
||||
mat_display_impl!(Mat4, 4);
|
||||
|
||||
/// Square matrix of dimension 5.
|
||||
#[repr(C)]
|
||||
|
@ -490,6 +495,7 @@ rand_impl!(Mat5,
|
|||
m51, m52, m53, m54, m55
|
||||
);
|
||||
mean_impl!(Mat5, Vec5, 5);
|
||||
mat_display_impl!(Mat5, 5);
|
||||
|
||||
/// Square matrix of dimension 6.
|
||||
#[repr(C)]
|
||||
|
@ -632,3 +638,4 @@ rand_impl!(Mat6,
|
|||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
mean_impl!(Mat6, Vec6, 6);
|
||||
mat_display_impl!(Mat6, 6);
|
||||
|
|
|
@ -749,3 +749,56 @@ macro_rules! mean_impl(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! mat_display_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
// XXX: will will not always work correctly due to rounding errors.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn integral_length<N: BaseFloat>(val: &N) -> usize {
|
||||
let mut res = 1;
|
||||
let mut curr: N = ::cast(10.0f64);
|
||||
|
||||
while curr <= *val {
|
||||
curr = curr * ::cast(10.0f64);
|
||||
res = res + 1;
|
||||
}
|
||||
|
||||
if val.is_sign_negative() {
|
||||
res + 1
|
||||
}
|
||||
else {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
let mut max_decimal_length = 0;
|
||||
let mut decimal_lengths: $t<usize> = ::zero();
|
||||
for i in 0 .. $dim {
|
||||
for j in 0 .. $dim {
|
||||
decimal_lengths[(i, j)] = integral_length(&self[(i, j)].clone());
|
||||
max_decimal_length = ::max(max_decimal_length, decimal_lengths[(i, j)]);
|
||||
}
|
||||
}
|
||||
|
||||
let precision = f.precision().unwrap_or(3);
|
||||
let max_number_length = max_decimal_length + precision + 1;
|
||||
|
||||
try!(writeln!(f, " ┌ {:>width$} ┐", "", width = max_number_length * $dim + $dim - 1));
|
||||
|
||||
for i in 0 .. $dim {
|
||||
try!(write!(f, " │"));
|
||||
for j in 0 .. $dim {
|
||||
let number_length = decimal_lengths[(i, j)] + precision + 1;
|
||||
let pad = max_number_length - number_length;
|
||||
try!(write!(f, " {:>thepad$}", "", thepad = pad));
|
||||
try!(write!(f, "{:.*}", precision, (*self)[(i, j)]));
|
||||
}
|
||||
try!(writeln!(f, " │"));
|
||||
}
|
||||
|
||||
writeln!(f, " └ {:>width$} ┘", "", width = max_number_length * $dim + $dim - 1)
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
|
@ -41,11 +41,11 @@ impl<N: BaseFloat> Ortho3<N> {
|
|||
|
||||
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
|
||||
pub fn to_mat(&self) -> Mat4<N> {
|
||||
self.to_persp_mat().mat
|
||||
self.to_ortho_mat().mat
|
||||
}
|
||||
|
||||
/// Build a `OrthoMat3` representing this projection.
|
||||
pub fn to_persp_mat(&self) -> OrthoMat3<N> {
|
||||
pub fn to_ortho_mat(&self) -> OrthoMat3<N> {
|
||||
OrthoMat3::new(self.width, self.height, self.znear, self.zfar)
|
||||
}
|
||||
}
|
||||
|
@ -114,14 +114,14 @@ impl<N: BaseFloat + Clone> Ortho3<N> {
|
|||
#[inline]
|
||||
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
// FIXME: optimize that
|
||||
self.to_persp_mat().project_pnt(p)
|
||||
self.to_ortho_mat().project_pnt(p)
|
||||
}
|
||||
|
||||
/// Projects a vector.
|
||||
#[inline]
|
||||
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
|
||||
// FIXME: optimize that
|
||||
self.to_persp_mat().project_vec(p)
|
||||
self.to_ortho_mat().project_vec(p)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ impl<N: BaseFloat + Clone> OrthoMat3<N> {
|
|||
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthoMat3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> OrthoMat3<N> {
|
||||
let x: Ortho3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_persp_mat()
|
||||
x.to_ortho_mat()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! Points with dimension known at compile-time.
|
||||
|
||||
use std::mem;
|
||||
use std::fmt;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
||||
|
@ -57,6 +58,7 @@ pnt_from_homogeneous_impl!(Pnt1, Pnt2, y, x);
|
|||
num_float_pnt_impl!(Pnt1, Vec1);
|
||||
arbitrary_pnt_impl!(Pnt1, x);
|
||||
rand_impl!(Pnt1, x);
|
||||
pnt_display_impl!(Pnt1);
|
||||
|
||||
/// Point of dimension 2.
|
||||
///
|
||||
|
@ -102,6 +104,7 @@ pnt_from_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
|
|||
num_float_pnt_impl!(Pnt2, Vec2);
|
||||
arbitrary_pnt_impl!(Pnt2, x, y);
|
||||
rand_impl!(Pnt2, x, y);
|
||||
pnt_display_impl!(Pnt2);
|
||||
|
||||
/// Point of dimension 3.
|
||||
///
|
||||
|
@ -149,6 +152,7 @@ pnt_from_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
|
|||
num_float_pnt_impl!(Pnt3, Vec3);
|
||||
arbitrary_pnt_impl!(Pnt3, x, y, z);
|
||||
rand_impl!(Pnt3, x, y, z);
|
||||
pnt_display_impl!(Pnt3);
|
||||
|
||||
/// Point of dimension 4.
|
||||
///
|
||||
|
@ -198,6 +202,7 @@ pnt_from_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
|
|||
num_float_pnt_impl!(Pnt4, Vec4);
|
||||
arbitrary_pnt_impl!(Pnt4, x, y, z, w);
|
||||
rand_impl!(Pnt4, x, y, z, w);
|
||||
pnt_display_impl!(Pnt4);
|
||||
|
||||
/// Point of dimension 5.
|
||||
///
|
||||
|
@ -249,6 +254,7 @@ pnt_from_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
|
|||
num_float_pnt_impl!(Pnt5, Vec5);
|
||||
arbitrary_pnt_impl!(Pnt5, x, y, z, w, a);
|
||||
rand_impl!(Pnt5, x, y, z, w, a);
|
||||
pnt_display_impl!(Pnt5);
|
||||
|
||||
/// Point of dimension 6.
|
||||
///
|
||||
|
@ -300,3 +306,4 @@ iterable_mut_impl!(Pnt6, 6);
|
|||
num_float_pnt_impl!(Pnt6, Vec6);
|
||||
arbitrary_pnt_impl!(Pnt6, x, y, z, w, a, b);
|
||||
rand_impl!(Pnt6, x, y, z, w, a, b);
|
||||
pnt_display_impl!(Pnt6);
|
||||
|
|
|
@ -155,3 +155,24 @@ macro_rules! arbitrary_pnt_impl(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// FIXME: differenciate them from vectors ?
|
||||
try!(write!(f, "("));
|
||||
|
||||
let mut it = self.iter();
|
||||
|
||||
try!(write!(f, "{}", *it.next().unwrap()));
|
||||
|
||||
for comp in it {
|
||||
try!(write!(f, ", {}", *comp));
|
||||
}
|
||||
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Quaternion definition.
|
||||
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
||||
|
@ -154,6 +155,12 @@ impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> fmt::Display for Quat<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Quaternion {} − ({}, {}, {})", self.w, self.i, self.j, self.k)
|
||||
}
|
||||
}
|
||||
|
||||
rand_impl!(Quat, w, i, j, k);
|
||||
|
||||
|
||||
|
@ -505,6 +512,12 @@ impl<N: BaseNum + Neg<Output = N>> Transform<Pnt3<N>> for UnitQuat<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> fmt::Display for UnitQuat<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Unit quaternion {} − ({}, {}, {})", self.q.w, self.q.i, self.q.j, self.q.k)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuat<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuat<N> {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Rotations matrices.
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::{Mul, Neg, Index};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
|
@ -193,47 +194,42 @@ impl<N: Clone + BaseFloat> Rot3<N> {
|
|||
}
|
||||
|
||||
impl<N: Clone + BaseFloat> Rot3<N> {
|
||||
/// Create a new matrix and orient it such that its local `x` axis points to a given point.
|
||||
/// Note that the usually known `look_at` function does the same thing but with the `z` axis.
|
||||
/// See `look_at_z` for that.
|
||||
/// Creates a rotation that corresponds to the local frame of an observer standing at the
|
||||
/// origin and looking toward `dir`.
|
||||
///
|
||||
/// It maps the view direction `dir` to the positive `z` axis.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * at - The point to look at. It is also the direction the matrix `x` axis will be aligned
|
||||
/// with
|
||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||
/// with `at`. Non-colinearity is not checked.
|
||||
pub fn look_at(at: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
let xaxis = Norm::normalize(at);
|
||||
let zaxis = Norm::normalize(&Cross::cross(up, &xaxis));
|
||||
let yaxis = Cross::cross(&zaxis, &xaxis);
|
||||
/// * dir - The look direction, that is, direction the matrix `z` axis will be aligned with.
|
||||
/// * up - The vertical direction. The only requirement of this parameter is to not be
|
||||
/// collinear
|
||||
/// to `dir`. Non-collinearity is not checked.
|
||||
#[inline]
|
||||
pub fn new_observer_frame(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
let zaxis = Norm::normalize(dir);
|
||||
let xaxis = Norm::normalize(&Cross::cross(up, &zaxis));
|
||||
let yaxis = Norm::normalize(&Cross::cross(&zaxis, &xaxis));
|
||||
|
||||
unsafe {
|
||||
Rot3::new_with_mat(Mat3::new(
|
||||
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
|
||||
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
|
||||
xaxis.z , yaxis.z , zaxis.z)
|
||||
)
|
||||
xaxis.z , yaxis.z , zaxis.z))
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new matrix and orient it such that its local `z` axis points to a given point.
|
||||
/// Builds a look-at view matrix with no translational component.
|
||||
///
|
||||
/// This conforms to the common notion of "look-at" matrix from the computer graphics community.
|
||||
/// Its maps the view direction `dir` to the **negative** `z` axis.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * at - The look direction, that is, direction the matrix `y` axis will be aligned with
|
||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||
/// with `at`. Non-colinearity is not checked.
|
||||
pub fn look_at_z(at: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
let zaxis = Norm::normalize(at);
|
||||
let xaxis = Norm::normalize(&Cross::cross(up, &zaxis));
|
||||
let yaxis = Cross::cross(&zaxis, &xaxis);
|
||||
|
||||
unsafe {
|
||||
Rot3::new_with_mat(Mat3::new(
|
||||
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
|
||||
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
|
||||
xaxis.z , yaxis.z , zaxis.z)
|
||||
)
|
||||
}
|
||||
/// * dir - The view direction.
|
||||
/// * up - The vertical direction. The only requirement of this parameter is to not be
|
||||
/// collinear to `dir`.
|
||||
#[inline]
|
||||
pub fn new_look_at(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
Rot3::new_observer_frame(&(-*dir), up).inv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,6 +364,7 @@ inv_impl!(Rot2);
|
|||
transpose_impl!(Rot2);
|
||||
approx_eq_impl!(Rot2);
|
||||
diag_impl!(Rot2, Vec2);
|
||||
rot_display_impl!(Rot2);
|
||||
|
||||
submat_impl!(Rot3, Mat3);
|
||||
rotate_impl!(Rot3, Vec3, Pnt3);
|
||||
|
@ -390,3 +387,4 @@ inv_impl!(Rot3);
|
|||
transpose_impl!(Rot3);
|
||||
approx_eq_impl!(Rot3);
|
||||
diag_impl!(Rot3, Vec3);
|
||||
rot_display_impl!(Rot3);
|
||||
|
|
|
@ -326,3 +326,17 @@ macro_rules! absolute_impl(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! rot_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let precision = f.precision().unwrap_or(3);
|
||||
|
||||
try!(writeln!(f, "Rotation matrix {{"));
|
||||
try!(write!(f, "{:.*}", precision, self.submat));
|
||||
writeln!(f, "}}")
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::fmt;
|
||||
use std::ops::{Mul, Neg};
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
|
@ -64,6 +65,7 @@ sim_to_homogeneous_impl!(Sim2, Mat3);
|
|||
sim_approx_eq_impl!(Sim2);
|
||||
sim_rand_impl!(Sim2);
|
||||
sim_arbitrary_impl!(Sim2);
|
||||
sim_display_impl!(Sim2);
|
||||
|
||||
sim_impl!(Sim3, Iso3, Rot3, Vec3, Vec3);
|
||||
dim_impl!(Sim3, 3);
|
||||
|
@ -81,3 +83,4 @@ sim_to_homogeneous_impl!(Sim3, Mat4);
|
|||
sim_approx_eq_impl!(Sim3);
|
||||
sim_rand_impl!(Sim3);
|
||||
sim_arbitrary_impl!(Sim3);
|
||||
sim_display_impl!(Sim3);
|
||||
|
|
|
@ -118,7 +118,7 @@ macro_rules! sim_mul_sim_impl(
|
|||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
self.isometry.translation + self.isometry.rotation * (right.isometry.translation * right.scale),
|
||||
self.isometry.translation + self.isometry.rotation * (right.isometry.translation * self.scale),
|
||||
self.isometry.rotation * right.isometry.rotation,
|
||||
self.scale * right.scale)
|
||||
}
|
||||
|
@ -174,10 +174,11 @@ macro_rules! sim_inv_impl(
|
|||
fn inv_mut(&mut self) -> bool {
|
||||
self.scale = ::one::<N>() / self.scale;
|
||||
self.isometry.inv_mut();
|
||||
// We multiply by self.scale because the scale has been inverted on the previous line.
|
||||
// We multiply (instead of dividing) by self.scale because it has already been
|
||||
// inverted.
|
||||
self.isometry.translation = self.isometry.translation * self.scale;
|
||||
|
||||
// always succeed
|
||||
// Always succeed.
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -186,7 +187,7 @@ macro_rules! sim_inv_impl(
|
|||
let mut res = *self;
|
||||
res.inv_mut();
|
||||
|
||||
// always succeed
|
||||
// Always succeed.
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +244,12 @@ macro_rules! sim_rand_impl(
|
|||
impl<N: Rand + BaseFloat> Rand for $t<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> $t<N> {
|
||||
$t::new_with_iso(rng.gen(), rng.gen())
|
||||
let mut scale: N = rng.gen();
|
||||
while scale.is_zero() {
|
||||
scale = rng.gen();
|
||||
}
|
||||
|
||||
$t::new_with_iso(rng.gen(), scale)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -262,3 +268,28 @@ macro_rules! sim_arbitrary_impl(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! sim_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(writeln!(f, "Similarity transformation {{"));
|
||||
|
||||
if let Some(precision) = f.precision() {
|
||||
try!(writeln!(f, "... scale factor: {:.*}", precision, self.scale));
|
||||
try!(writeln!(f, "... translation: {:.*}", precision, self.isometry.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submat()));
|
||||
}
|
||||
else {
|
||||
try!(writeln!(f, "... scale factor: {}", self.scale));
|
||||
try!(writeln!(f, "... translation: {}", self.isometry.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{}", *self.isometry.rotation.submat()));
|
||||
}
|
||||
|
||||
writeln!(f, "}}")
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
|||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||
use std::fmt;
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::operations::{ApproxEq, POrd, POrdering, Axpy, Absolute, Mean};
|
||||
|
@ -71,6 +72,7 @@ absolute_vec_impl!(Vec1, x);
|
|||
arbitrary_impl!(Vec1, x);
|
||||
rand_impl!(Vec1, x);
|
||||
mean_impl!(Vec1);
|
||||
vec_display_impl!(Vec1);
|
||||
|
||||
/// Vector of dimension 2.
|
||||
///
|
||||
|
@ -128,6 +130,7 @@ absolute_vec_impl!(Vec2, x, y);
|
|||
arbitrary_impl!(Vec2, x, y);
|
||||
rand_impl!(Vec2, x, y);
|
||||
mean_impl!(Vec2);
|
||||
vec_display_impl!(Vec2);
|
||||
|
||||
/// Vector of dimension 3.
|
||||
///
|
||||
|
@ -187,6 +190,7 @@ absolute_vec_impl!(Vec3, x, y, z);
|
|||
arbitrary_impl!(Vec3, x, y, z);
|
||||
rand_impl!(Vec3, x, y, z);
|
||||
mean_impl!(Vec3);
|
||||
vec_display_impl!(Vec3);
|
||||
|
||||
|
||||
/// Vector of dimension 4.
|
||||
|
@ -249,6 +253,7 @@ absolute_vec_impl!(Vec4, x, y, z, w);
|
|||
arbitrary_impl!(Vec4, x, y, z, w);
|
||||
rand_impl!(Vec4, x, y, z, w);
|
||||
mean_impl!(Vec4);
|
||||
vec_display_impl!(Vec4);
|
||||
|
||||
/// Vector of dimension 5.
|
||||
///
|
||||
|
@ -312,6 +317,7 @@ absolute_vec_impl!(Vec5, x, y, z, w, a);
|
|||
arbitrary_impl!(Vec5, x, y, z, w, a);
|
||||
rand_impl!(Vec5, x, y, z, w, a);
|
||||
mean_impl!(Vec5);
|
||||
vec_display_impl!(Vec5);
|
||||
|
||||
/// Vector of dimension 6.
|
||||
///
|
||||
|
@ -375,3 +381,4 @@ absolute_vec_impl!(Vec6, x, y, z, w, a, b);
|
|||
arbitrary_impl!(Vec6, x, y, z, w, a, b);
|
||||
rand_impl!(Vec6, x, y, z, w, a, b);
|
||||
mean_impl!(Vec6);
|
||||
vec_display_impl!(Vec6);
|
||||
|
|
|
@ -820,3 +820,25 @@ macro_rules! mean_impl(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! vec_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "("));
|
||||
|
||||
let mut it = self.iter();
|
||||
|
||||
let precision = f.precision().unwrap_or(8);
|
||||
|
||||
try!(write!(f, "{:.*}", precision, *it.next().unwrap()));
|
||||
|
||||
for comp in it {
|
||||
try!(write!(f, ", {:.*}", precision, *comp));
|
||||
}
|
||||
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
173
tests/mat.rs
173
tests/mat.rs
|
@ -2,8 +2,8 @@ extern crate nalgebra as na;
|
|||
extern crate rand;
|
||||
|
||||
use rand::random;
|
||||
use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot2, Rot3, Persp3, PerspMat3, Ortho3,
|
||||
OrthoMat3, DMat, DVec, Row, Col, BaseFloat, Diag, Transpose, RowSlice, ColSlice, Shape};
|
||||
use na::{Rot2, Rot3, Iso2, Iso3, Sim2, Sim3, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, DMat, DVec,
|
||||
Row, Col, Diag, Transpose, RowSlice, ColSlice, Shape};
|
||||
|
||||
macro_rules! test_inv_mat_impl(
|
||||
($t: ty) => (
|
||||
|
@ -12,7 +12,9 @@ macro_rules! test_inv_mat_impl(
|
|||
|
||||
match na::inv(&randmat) {
|
||||
None => { },
|
||||
Some(i) => assert!(na::approx_eq(&(i * randmat), &na::one()))
|
||||
Some(i) => {
|
||||
assert!(na::approx_eq(&(i * randmat), &na::one()))
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -183,13 +185,33 @@ fn test_inv_mat6() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotation2() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: na::Rot2<f64> = na::one();
|
||||
let ang = Vec1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
fn test_inv_rot2() {
|
||||
test_inv_mat_impl!(Rot2<f64>);
|
||||
}
|
||||
|
||||
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang));
|
||||
}
|
||||
#[test]
|
||||
fn test_inv_rot3() {
|
||||
test_inv_mat_impl!(Rot3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_iso2() {
|
||||
test_inv_mat_impl!(Iso2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_iso3() {
|
||||
test_inv_mat_impl!(Iso3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_sim2() {
|
||||
test_inv_mat_impl!(Sim2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_sim3() {
|
||||
test_inv_mat_impl!(Sim3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -199,59 +221,6 @@ fn test_index_mat2() {
|
|||
assert!(mat[(0, 1)] == na::transpose(&mat)[(1, 0)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_rotation3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: Rot3<f64> = na::one();
|
||||
let dir: Vec3<f64> = random();
|
||||
let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
let rot = na::append_rotation(&randmat, &ang);
|
||||
|
||||
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot3_rotation_between() {
|
||||
let r1: Rot3<f64> = random();
|
||||
let r2: Rot3<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&(delta * r1), &r2))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot3_angle_between() {
|
||||
let r1: Rot3<f64> = random();
|
||||
let r2: Rot3<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
let delta_angle = na::angle_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot2_rotation_between() {
|
||||
let r1: Rot2<f64> = random();
|
||||
let r2: Rot2<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&(delta * r1), &r2))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot2_angle_between() {
|
||||
let r1: Rot2<f64> = random();
|
||||
let r2: Rot2<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
let delta_angle = na::angle_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mean_dmat() {
|
||||
|
@ -755,86 +724,6 @@ fn test_row_3() {
|
|||
assert!(second_col == Vec3::new(1.0, 4.0, 7.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_persp() {
|
||||
let mut p = Persp3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
let mut pm = PerspMat3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
assert!(p.to_mat() == pm.to_mat());
|
||||
assert!(p.aspect() == 42.0);
|
||||
assert!(p.fov() == 0.5);
|
||||
assert!(p.znear() == 1.5);
|
||||
assert!(p.zfar() == 10.0);
|
||||
assert!(na::approx_eq(&pm.aspect(), &42.0));
|
||||
assert!(na::approx_eq(&pm.fov(), &0.5));
|
||||
assert!(na::approx_eq(&pm.znear(), &1.5));
|
||||
assert!(na::approx_eq(&pm.zfar(), &10.0));
|
||||
|
||||
p.set_fov(0.1);
|
||||
pm.set_fov(0.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_znear(24.0);
|
||||
pm.set_znear(24.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_zfar(61.0);
|
||||
pm.set_zfar(61.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_aspect(23.0);
|
||||
pm.set_aspect(23.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
assert!(p.aspect() == 23.0);
|
||||
assert!(p.fov() == 0.1);
|
||||
assert!(p.znear() == 24.0);
|
||||
assert!(p.zfar() == 61.0);
|
||||
assert!(na::approx_eq(&pm.aspect(), &23.0));
|
||||
assert!(na::approx_eq(&pm.fov(), &0.1));
|
||||
assert!(na::approx_eq(&pm.znear(), &24.0));
|
||||
assert!(na::approx_eq(&pm.zfar(), &61.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ortho() {
|
||||
let mut p = Ortho3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
let mut pm = OrthoMat3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
assert!(p.to_mat() == pm.to_mat());
|
||||
assert!(p.width() == 42.0);
|
||||
assert!(p.height() == 0.5);
|
||||
assert!(p.znear() == 1.5);
|
||||
assert!(p.zfar() == 10.0);
|
||||
assert!(na::approx_eq(&pm.width(), &42.0));
|
||||
assert!(na::approx_eq(&pm.height(), &0.5));
|
||||
assert!(na::approx_eq(&pm.znear(), &1.5));
|
||||
assert!(na::approx_eq(&pm.zfar(), &10.0));
|
||||
|
||||
p.set_width(0.1);
|
||||
pm.set_width(0.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_znear(24.0);
|
||||
pm.set_znear(24.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_zfar(61.0);
|
||||
pm.set_zfar(61.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_height(23.0);
|
||||
pm.set_height(23.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
assert!(p.height() == 23.0);
|
||||
assert!(p.width() == 0.1);
|
||||
assert!(p.znear() == 24.0);
|
||||
assert!(p.zfar() == 61.0);
|
||||
assert!(na::approx_eq(&pm.height(), &23.0));
|
||||
assert!(na::approx_eq(&pm.width(), &0.1));
|
||||
assert!(na::approx_eq(&pm.znear(), &24.0));
|
||||
assert!(na::approx_eq(&pm.zfar(), &61.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_const() {
|
||||
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
extern crate nalgebra as na;
|
||||
extern crate rand;
|
||||
|
||||
use rand::random;
|
||||
use na::{Pnt3, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, Iso2, Iso3, BaseFloat,
|
||||
Sim2, Sim3};
|
||||
|
||||
macro_rules! test_transform_inv_transform_impl(
|
||||
($t: ty, $p: ty) => (
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: $t = random();
|
||||
let randvec: $p = random();
|
||||
|
||||
let tvec = randmat.transform(&randvec);
|
||||
let original = randmat.inv_transform(&randvec);
|
||||
|
||||
assert!(na::approx_eq(&randvec, &original));
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
test_transform_inv_transform_impl!(Rot2, Pnt2);
|
||||
test_transform_inv_transform_impl!(Rot3, Pnt3);
|
||||
test_transform_inv_transform_impl!(Iso2, Pnt2);
|
||||
test_transform_inv_transform_impl!(Iso3, Pnt3);
|
||||
test_transform_inv_transform_impl!(Sim2, Pnt2);
|
||||
test_transform_inv_transform_impl!(Sim3, Pnt3);
|
||||
|
||||
#[test]
|
||||
fn test_rotation2() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: na::Rot2<f64> = na::one();
|
||||
let ang = Vec1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
|
||||
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_rotation3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: Rot3<f64> = na::one();
|
||||
let dir: Vec3<f64> = random();
|
||||
let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
let rot = na::append_rotation(&randmat, &ang);
|
||||
|
||||
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot3_rotation_between() {
|
||||
let r1: Rot3<f64> = random();
|
||||
let r2: Rot3<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&(delta * r1), &r2))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot3_angle_between() {
|
||||
let r1: Rot3<f64> = random();
|
||||
let r2: Rot3<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
let delta_angle = na::angle_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot2_rotation_between() {
|
||||
let r1: Rot2<f64> = random();
|
||||
let r2: Rot2<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&(delta * r1), &r2))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot2_angle_between() {
|
||||
let r1: Rot2<f64> = random();
|
||||
let r2: Rot2<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
let delta_angle = na::angle_between(&r1, &r2);
|
||||
|
||||
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_look_at_iso3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let eye = random::<Pnt3<f64>>();
|
||||
let target = random::<Pnt3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let viewmat = Iso3::new_look_at(&eye, &target, &up);
|
||||
|
||||
assert_eq!(&(viewmat * eye), &na::orig());
|
||||
assert!(na::approx_eq(&na::normalize(&(viewmat * (target - eye))), &-Vec3::z()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_look_at_rot3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let dir = random::<Vec3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let viewmat = Rot3::new_look_at(&dir, &up);
|
||||
|
||||
assert!(na::approx_eq(&na::normalize(&(viewmat * dir)), &-Vec3::z()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_observer_frame_iso3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let eye = random::<Pnt3<f64>>();
|
||||
let target = random::<Pnt3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let observer = Iso3::new_observer_frame(&eye, &target, &up);
|
||||
|
||||
assert_eq!(&(observer * na::orig::<Pnt3<f64>>()), &eye);
|
||||
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&(target - eye))));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_observer_frame_rot3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let dir = random::<Vec3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let observer = Rot3::new_observer_frame(&dir, &up);
|
||||
|
||||
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&dir)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_persp() {
|
||||
let mut p = Persp3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
let mut pm = PerspMat3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
assert!(p.to_mat() == pm.to_mat());
|
||||
assert!(p.aspect() == 42.0);
|
||||
assert!(p.fov() == 0.5);
|
||||
assert!(p.znear() == 1.5);
|
||||
assert!(p.zfar() == 10.0);
|
||||
assert!(na::approx_eq(&pm.aspect(), &42.0));
|
||||
assert!(na::approx_eq(&pm.fov(), &0.5));
|
||||
assert!(na::approx_eq(&pm.znear(), &1.5));
|
||||
assert!(na::approx_eq(&pm.zfar(), &10.0));
|
||||
|
||||
p.set_fov(0.1);
|
||||
pm.set_fov(0.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_znear(24.0);
|
||||
pm.set_znear(24.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_zfar(61.0);
|
||||
pm.set_zfar(61.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_aspect(23.0);
|
||||
pm.set_aspect(23.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
assert!(p.aspect() == 23.0);
|
||||
assert!(p.fov() == 0.1);
|
||||
assert!(p.znear() == 24.0);
|
||||
assert!(p.zfar() == 61.0);
|
||||
assert!(na::approx_eq(&pm.aspect(), &23.0));
|
||||
assert!(na::approx_eq(&pm.fov(), &0.1));
|
||||
assert!(na::approx_eq(&pm.znear(), &24.0));
|
||||
assert!(na::approx_eq(&pm.zfar(), &61.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ortho() {
|
||||
let mut p = Ortho3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
let mut pm = OrthoMat3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
assert!(p.to_mat() == pm.to_mat());
|
||||
assert!(p.width() == 42.0);
|
||||
assert!(p.height() == 0.5);
|
||||
assert!(p.znear() == 1.5);
|
||||
assert!(p.zfar() == 10.0);
|
||||
assert!(na::approx_eq(&pm.width(), &42.0));
|
||||
assert!(na::approx_eq(&pm.height(), &0.5));
|
||||
assert!(na::approx_eq(&pm.znear(), &1.5));
|
||||
assert!(na::approx_eq(&pm.zfar(), &10.0));
|
||||
|
||||
p.set_width(0.1);
|
||||
pm.set_width(0.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_znear(24.0);
|
||||
pm.set_znear(24.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_zfar(61.0);
|
||||
pm.set_zfar(61.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
p.set_height(23.0);
|
||||
pm.set_height(23.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
|
||||
assert!(p.height() == 23.0);
|
||||
assert!(p.width() == 0.1);
|
||||
assert!(p.znear() == 24.0);
|
||||
assert!(p.zfar() == 61.0);
|
||||
assert!(na::approx_eq(&pm.height(), &23.0));
|
||||
assert!(na::approx_eq(&pm.width(), &0.1));
|
||||
assert!(na::approx_eq(&pm.znear(), &24.0));
|
||||
assert!(na::approx_eq(&pm.zfar(), &61.0));
|
||||
}
|
|
@ -1,10 +1,16 @@
|
|||
extern crate rand;
|
||||
#[cfg(feature="generic_sizes")]
|
||||
extern crate typenum;
|
||||
extern crate nalgebra as na;
|
||||
|
||||
use rand::random;
|
||||
use na::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, IterableMut};
|
||||
|
||||
#[cfg(feature="generic_sizes")]
|
||||
use typenum::U10;
|
||||
use na::{VecN, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, IterableMut};
|
||||
#[cfg(feature="generic_sizes")]
|
||||
use na::VecN;
|
||||
|
||||
|
||||
macro_rules! test_iterator_impl(
|
||||
($t: ty, $n: ty) => (
|
||||
|
@ -295,6 +301,7 @@ fn test_outer_vec3() {
|
|||
12.0, 15.0, 18.0));
|
||||
}
|
||||
|
||||
#[cfg(feature="generic_sizes")]
|
||||
#[test]
|
||||
fn test_vecn10_add_mul() {
|
||||
for _ in 0usize .. 10000 {
|
||||
|
|
Loading…
Reference in New Issue