From 948341685efe929b86c8656bf2927afaba2547ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 15 Nov 2015 21:38:23 +0100 Subject: [PATCH 1/4] Add implementation of `RotationMatrix` for `UnitQuat`. --- src/structs/quat.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/structs/quat.rs b/src/structs/quat.rs index 604a1e20..a8664ef5 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -12,7 +12,7 @@ use structs::{Vec3, Pnt3, Rot3, Mat3}; use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy}; use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum, Bounded, Repeat}; -use traits::geometry::{Norm, Rotation, Rotate, RotationTo, Transform}; +use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Transform}; #[cfg(feature="arbitrary")] use quickcheck::{Arbitrary, Gen}; @@ -156,6 +156,8 @@ impl + BaseFloat> Div> for Quat { } } +rand_impl!(Quat, w, i, j, k); + /// A unit quaternion that can represent a 3D rotation. #[repr(C)] @@ -246,8 +248,6 @@ impl UnitQuat { } } -rand_impl!(Quat, w, i, j, k); - impl UnitQuat { /// Creates a new unit quaternion from a quaternion. @@ -432,6 +432,15 @@ impl Rotation> for UnitQuat { } } +impl RotationMatrix, Vec3> for UnitQuat { + type Output = Rot3; + + #[inline] + fn to_rot_mat(&self) -> Rot3 { + self.to_rot() + } +} + impl> Rotate> for UnitQuat { #[inline] fn rotate(&self, v: &Vec3) -> Vec3 { From 58000e48383e0285da5863321195b4652a7f8c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 15 Nov 2015 21:38:28 +0100 Subject: [PATCH 2/4] Implement AsRef, AsMut, From for vectors and matrices. This allows pointer conversion between arrays and vectors or matrices. Those implementations replace the `.as_array()` and `.as_array_mut()` method. --- src/structs/mat.rs | 12 ++++++------ src/structs/mat_macros.rs | 35 ++++++++++++++++------------------- src/structs/pnt.rs | 12 ++++++------ src/structs/quat.rs | 2 +- src/structs/vec.rs | 12 ++++++------ src/structs/vec_macros.rs | 39 ++++++++++++++++++--------------------- 6 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/structs/mat.rs b/src/structs/mat.rs index 40604e9b..3cee999a 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -45,7 +45,7 @@ eye_impl!(Mat1, 1, m11); mat_impl!(Mat1, m11); repeat_impl!(Mat1, m11); -as_array_impl!(Mat1, 1); +conversion_impl!(Mat1, 1); mat_cast_impl!(Mat1, m11); add_impl!(Mat1, m11); sub_impl!(Mat1, m11); @@ -96,7 +96,7 @@ mat_impl!(Mat2, m11, m12, m21, m22); repeat_impl!(Mat2, m11, m12, m21, m22); -as_array_impl!(Mat2, 2); +conversion_impl!(Mat2, 2); mat_cast_impl!(Mat2, m11, m12, m21, m22); add_impl!(Mat2, m11, m12, m21, m22); @@ -152,7 +152,7 @@ mat_impl!(Mat3, m11, m12, m13, repeat_impl!(Mat3, m11, m12, m13, m21, m22, m23, m31, m32, m33); -as_array_impl!(Mat3, 3); +conversion_impl!(Mat3, 3); mat_cast_impl!(Mat3, m11, m12, m13, m21, m22, m23, m31, m32, m33); @@ -255,7 +255,7 @@ repeat_impl!(Mat4, m31, m32, m33, m34, m41, m42, m43, m44 ); -as_array_impl!(Mat4, 4); +conversion_impl!(Mat4, 4); mat_cast_impl!(Mat4, m11, m12, m13, m14, m21, m22, m23, m24, @@ -377,7 +377,7 @@ repeat_impl!(Mat5, m41, m42, m43, m44, m45, m51, m52, m53, m54, m55 ); -as_array_impl!(Mat5, 5); +conversion_impl!(Mat5, 5); mat_cast_impl!(Mat5, m11, m12, m13, m14, m15, m21, m22, m23, m24, m25, @@ -516,7 +516,7 @@ repeat_impl!(Mat6, m51, m52, m53, m54, m55, m56, m61, m62, m63, m64, m65, m66 ); -as_array_impl!(Mat6, 6); +conversion_impl!(Mat6, 6); mat_cast_impl!(Mat6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26, diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index d95ffd2d..d128b998 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -13,43 +13,40 @@ macro_rules! mat_impl( ) ); -macro_rules! as_array_impl( +macro_rules! conversion_impl( ($t: ident, $dim: expr) => ( - impl $t { - /// View this matrix as a column-major array of arrays. + impl AsRef<[[N; $dim]; $dim]> for $t { #[inline] - pub fn as_array(&self) -> &[[N; $dim]; $dim] { + fn as_ref(&self) -> &[[N; $dim]; $dim] { unsafe { mem::transmute(self) } } + } - /// View this matrix as a column-major mutable array of arrays. + impl AsMut<[[N; $dim]; $dim]> for $t { #[inline] - pub fn as_array_mut<'a>(&'a mut self) -> &'a mut [[N; $dim]; $dim] { + fn as_mut(&mut self) -> &mut [[N; $dim]; $dim] { unsafe { mem::transmute(self) } } + } - // FIXME: because of https://github.com/rust-lang/rust/issues/16418 we cannot do the - // array-to-mat conversion by-value: - // - // pub fn from_array(array: [N; $dim]) -> $t - - /// View a column-major array of array as a vector. + impl<'a, N> From<&'a [[N; $dim]; $dim]> for &'a $t { #[inline] - pub fn from_array_ref(array: &[[N; $dim]; $dim]) -> &$t { + fn from(arr: &'a [[N; $dim]; $dim]) -> &'a $t { unsafe { - mem::transmute(array) + mem::transmute(arr) } } + } - /// View a column-major array of array as a mutable vector. + impl<'a, N> From<&'a mut [[N; $dim]; $dim]> for &'a mut $t { #[inline] - pub fn from_array_mut(array: &mut [[N; $dim]; $dim]) -> &mut $t { + fn from(arr: &'a mut [[N; $dim]; $dim]) -> &'a mut $t { unsafe { - mem::transmute(array) + mem::transmute(arr) } } } @@ -325,7 +322,7 @@ macro_rules! col_slice_impl( fn col_slice(&self, cid: usize, rstart: usize, rend: usize) -> $slice { let col = self.col(cid); - $slice::from_slice(rend - rstart, &col.as_array()[rstart .. rend]) + $slice::from_slice(rend - rstart, &col.as_ref()[rstart .. rend]) } } ) @@ -366,7 +363,7 @@ macro_rules! row_slice_impl( fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice { let row = self.row(rid); - $slice::from_slice(cend - cstart, &row.as_array()[cstart .. cend]) + $slice::from_slice(cend - cstart, &row.as_ref()[cstart .. cend]) } } ) diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index b7452f19..2731a413 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -54,7 +54,7 @@ scalar_div_impl!(Pnt1, x); scalar_add_impl!(Pnt1, x); scalar_sub_impl!(Pnt1, x); vec_cast_impl!(Pnt1, x); -as_array_impl!(Pnt1, 1); +conversion_impl!(Pnt1, 1); index_impl!(Pnt1); indexable_impl!(Pnt1, 1); at_fast_impl!(Pnt1, 1); @@ -96,7 +96,7 @@ scalar_div_impl!(Pnt2, x, y); scalar_add_impl!(Pnt2, x, y); scalar_sub_impl!(Pnt2, x, y); vec_cast_impl!(Pnt2, x, y); -as_array_impl!(Pnt2, 2); +conversion_impl!(Pnt2, 2); index_impl!(Pnt2); indexable_impl!(Pnt2, 2); at_fast_impl!(Pnt2, 2); @@ -140,7 +140,7 @@ scalar_div_impl!(Pnt3, x, y, z); scalar_add_impl!(Pnt3, x, y, z); scalar_sub_impl!(Pnt3, x, y, z); vec_cast_impl!(Pnt3, x, y, z); -as_array_impl!(Pnt3, 3); +conversion_impl!(Pnt3, 3); index_impl!(Pnt3); indexable_impl!(Pnt3, 3); at_fast_impl!(Pnt3, 3); @@ -186,7 +186,7 @@ scalar_div_impl!(Pnt4, x, y, z, w); scalar_add_impl!(Pnt4, x, y, z, w); scalar_sub_impl!(Pnt4, x, y, z, w); vec_cast_impl!(Pnt4, x, y, z, w); -as_array_impl!(Pnt4, 4); +conversion_impl!(Pnt4, 4); index_impl!(Pnt4); indexable_impl!(Pnt4, 4); at_fast_impl!(Pnt4, 4); @@ -234,7 +234,7 @@ scalar_div_impl!(Pnt5, x, y, z, w, a); scalar_add_impl!(Pnt5, x, y, z, w, a); scalar_sub_impl!(Pnt5, x, y, z, w, a); vec_cast_impl!(Pnt5, x, y, z, w, a); -as_array_impl!(Pnt5, 5); +conversion_impl!(Pnt5, 5); index_impl!(Pnt5); indexable_impl!(Pnt5, 5); at_fast_impl!(Pnt5, 5); @@ -284,7 +284,7 @@ scalar_div_impl!(Pnt6, x, y, z, w, a, b); scalar_add_impl!(Pnt6, x, y, z, w, a, b); scalar_sub_impl!(Pnt6, x, y, z, w, a, b); vec_cast_impl!(Pnt6, x, y, z, w, a, b); -as_array_impl!(Pnt6, 6); +conversion_impl!(Pnt6, 6); index_impl!(Pnt6); indexable_impl!(Pnt6, 6); at_fast_impl!(Pnt6, 6); diff --git a/src/structs/quat.rs b/src/structs/quat.rs index a8664ef5..3aa3af07 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -518,7 +518,7 @@ impl Arbitrary for UnitQuat { ord_impl!(Quat, w, i, j, k); vec_axis_impl!(Quat, w, i, j, k); vec_cast_impl!(Quat, w, i, j, k); -as_array_impl!(Quat, 4); +conversion_impl!(Quat, 4); index_impl!(Quat); indexable_impl!(Quat, 4); at_fast_impl!(Quat, 4); diff --git a/src/structs/vec.rs b/src/structs/vec.rs index 318bcfad..cbe4621c 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -52,7 +52,7 @@ new_impl!(Vec1, x); ord_impl!(Vec1, x,); vec_axis_impl!(Vec1, x); vec_cast_impl!(Vec1, x); -as_array_impl!(Vec1, 1); +conversion_impl!(Vec1, 1); index_impl!(Vec1); indexable_impl!(Vec1, 1); at_fast_impl!(Vec1, 1); @@ -105,7 +105,7 @@ new_impl!(Vec2, x, y); ord_impl!(Vec2, x, y); vec_axis_impl!(Vec2, x, y); vec_cast_impl!(Vec2, x, y); -as_array_impl!(Vec2, 2); +conversion_impl!(Vec2, 2); index_impl!(Vec2); indexable_impl!(Vec2, 2); at_fast_impl!(Vec2, 2); @@ -160,7 +160,7 @@ new_impl!(Vec3, x, y, z); ord_impl!(Vec3, x, y, z); vec_axis_impl!(Vec3, x, y, z); vec_cast_impl!(Vec3, x, y, z); -as_array_impl!(Vec3, 3); +conversion_impl!(Vec3, 3); index_impl!(Vec3); indexable_impl!(Vec3, 3); at_fast_impl!(Vec3, 3); @@ -218,7 +218,7 @@ new_impl!(Vec4, x, y, z, w); ord_impl!(Vec4, x, y, z, w); vec_axis_impl!(Vec4, x, y, z, w); vec_cast_impl!(Vec4, x, y, z, w); -as_array_impl!(Vec4, 4); +conversion_impl!(Vec4, 4); index_impl!(Vec4); indexable_impl!(Vec4, 4); at_fast_impl!(Vec4, 4); @@ -277,7 +277,7 @@ new_impl!(Vec5, x, y, z, w, a); ord_impl!(Vec5, x, y, z, w, a); vec_axis_impl!(Vec5, x, y, z, w, a); vec_cast_impl!(Vec5, x, y, z, w, a); -as_array_impl!(Vec5, 5); +conversion_impl!(Vec5, 5); index_impl!(Vec5); indexable_impl!(Vec5, 5); at_fast_impl!(Vec5, 5); @@ -338,7 +338,7 @@ new_impl!(Vec6, x, y, z, w, a, b); ord_impl!(Vec6, x, y, z, w, a, b); vec_axis_impl!(Vec6, x, y, z, w, a, b); vec_cast_impl!(Vec6, x, y, z, w, a, b); -as_array_impl!(Vec6, 6); +conversion_impl!(Vec6, 6); index_impl!(Vec6); indexable_impl!(Vec6, 6); at_fast_impl!(Vec6, 6); diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index 6c7079f0..c42cf227 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -14,43 +14,40 @@ macro_rules! new_impl( ); ); -macro_rules! as_array_impl( +macro_rules! conversion_impl( ($t: ident, $dim: expr) => ( - impl $t { - /// View this vector as an array. + impl AsRef<[N; $dim]> for $t { #[inline] - pub fn as_array(&self) -> &[N; $dim] { + fn as_ref(&self) -> &[N; $dim] { unsafe { mem::transmute(self) } } + } - /// View this vector as a mutable array. + impl AsMut<[N; $dim]> for $t { #[inline] - pub fn as_array_mut(&mut self) -> &mut [N; $dim] { + fn as_mut(&mut self) -> &mut [N; $dim] { unsafe { mem::transmute(self) } } + } - // FIXME: because of https://github.com/rust-lang/rust/issues/16418 we cannot do the - // array-to-vec conversion by-value: - // - // pub fn from_array(array: [N; $dim]) -> $t - - /// View an array as a vector. + impl<'a, N> From<&'a [N; $dim]> for &'a $t { #[inline] - pub fn from_array_ref(array: &[N; $dim]) -> &$t { + fn from(arr: &'a [N; $dim]) -> &'a $t { unsafe { - mem::transmute(array) + mem::transmute(arr) } } + } - /// View an array as a vector. + impl<'a, N> From<&'a mut [N; $dim]> for &'a mut $t { #[inline] - pub fn from_array_mut(array: &mut [N; $dim]) -> &mut $t { + fn from(arr: &'a mut [N; $dim]) -> &'a mut $t { unsafe { - mem::transmute(array) + mem::transmute(arr) } } } @@ -63,13 +60,13 @@ macro_rules! at_fast_impl( /// Unsafe read access to a vector element by index. #[inline] pub unsafe fn at_fast(&self, i: usize) -> N { - (*self.as_array().get_unchecked(i)) + (*self.as_ref().get_unchecked(i)) } /// Unsafe write access to a vector element by index. #[inline] pub unsafe fn set_fast(&mut self, i: usize, val: N) { - (*self.as_array_mut().get_unchecked_mut(i)) = val + (*self.as_mut().get_unchecked_mut(i)) = val } } ) @@ -215,13 +212,13 @@ macro_rules! index_impl( type Output = N; fn index(&self, i: usize) -> &N { - &self.as_array()[i] + &self.as_ref()[i] } } impl IndexMut for $t { fn index_mut(&mut self, i: usize) -> &mut N { - &mut self.as_array_mut()[i] + &mut self.as_mut()[i] } } ) From 4098c6c5e51629ff951cfa63e77e8ff4e33b5db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 15 Nov 2015 21:38:35 +0100 Subject: [PATCH 3/4] Make Iso::look_at{_z} static. This did not need to access `self`. Fix #161. --- src/structs/iso.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/structs/iso.rs b/src/structs/iso.rs index b8e6957e..f42d48d5 100644 --- a/src/structs/iso.rs +++ b/src/structs/iso.rs @@ -69,9 +69,8 @@ impl Iso3 { /// 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(&mut self, eye: &Pnt3, at: &Pnt3, up: &Vec3) { - self.rotation = Rot3::look_at(&(*at - *eye), up); - self.translation = eye.as_vec().clone(); + pub fn look_at(eye: &Pnt3, at: &Pnt3, up: &Vec3) -> Iso3 { + Iso3::new_with_rotmat(eye.as_vec().clone(), Rot3::look_at(&(*at - *eye), up)) } /// Reorient and translate this transformation such that its local `z` axis points to a given @@ -83,9 +82,8 @@ impl Iso3 { /// 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(&mut self, eye: &Pnt3, at: &Pnt3, up: &Vec3) { - self.rotation = Rot3::look_at_z(&(*at - *eye), up); - self.translation = eye.as_vec().clone(); + pub fn look_at_z(eye: &Pnt3, at: &Pnt3, up: &Vec3) -> Iso3 { + Iso3::new_with_rotmat(eye.as_vec().clone(), Rot3::look_at_z(&(*at - *eye), up)) } } From 54c22c2fc3f85f3ef275ac55249552d2b07e2cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 15 Nov 2015 21:38:40 +0100 Subject: [PATCH 4/4] Release v0.4.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 96a443a9..ba68bb95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nalgebra" -version = "0.3.2" +version = "0.4.0" authors = [ "Sébastien Crozet " ] # FIXME: add the contributors. description = "Linear algebra library for computer physics, computer graphics and general low-dimensional linear algebra for Rust."