use num::Zero; use alga::general::{Real, SubsetOf, SupersetOf}; use alga::linear::Rotation as AlgaRotation; #[cfg(feature = "mint")] use mint; use base::dimension::U3; use base::{Matrix3, Matrix4, Vector4}; use geometry::{ Isometry, Point3, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, UnitQuaternion, }; /* * This file provides the following conversions: * ============================================= * * Quaternion -> Quaternion * UnitQuaternion -> UnitQuaternion * UnitQuaternion -> Rotation * UnitQuaternion -> Isometry * UnitQuaternion -> Similarity * UnitQuaternion -> Transform * UnitQuaternion -> Matrix (homogeneous) * * mint::Quaternion <-> Quaternion * UnitQuaternion -> mint::Quaternion * * NOTE: * UnitQuaternion -> Quaternion is already provided by: Unit -> T */ impl SubsetOf> for Quaternion where N1: Real, N2: Real + SupersetOf, { #[inline] fn to_superset(&self) -> Quaternion { Quaternion::from_vector(self.coords.to_superset()) } #[inline] fn is_in_subset(q: &Quaternion) -> bool { ::is_convertible::<_, Vector4>(&q.coords) } #[inline] unsafe fn from_superset_unchecked(q: &Quaternion) -> Self { Self::from_vector(q.coords.to_subset_unchecked()) } } impl SubsetOf> for UnitQuaternion where N1: Real, N2: Real + SupersetOf, { #[inline] fn to_superset(&self) -> UnitQuaternion { UnitQuaternion::new_unchecked(self.as_ref().to_superset()) } #[inline] fn is_in_subset(uq: &UnitQuaternion) -> bool { ::is_convertible::<_, Quaternion>(uq.as_ref()) } #[inline] unsafe fn from_superset_unchecked(uq: &UnitQuaternion) -> Self { Self::new_unchecked(::convert_ref_unchecked(uq.as_ref())) } } impl SubsetOf> for UnitQuaternion where N1: Real, N2: Real + SupersetOf, { #[inline] fn to_superset(&self) -> Rotation3 { let q: UnitQuaternion = self.to_superset(); q.to_rotation_matrix() } #[inline] fn is_in_subset(rot: &Rotation3) -> bool { ::is_convertible::<_, Rotation3>(rot) } #[inline] unsafe fn from_superset_unchecked(rot: &Rotation3) -> Self { let q = UnitQuaternion::::from_rotation_matrix(rot); ::convert_unchecked(q) } } impl SubsetOf> for UnitQuaternion where N1: Real, N2: Real + SupersetOf, R: AlgaRotation> + SupersetOf>, { #[inline] fn to_superset(&self) -> Isometry { Isometry::from_parts(Translation::identity(), ::convert_ref(self)) } #[inline] fn is_in_subset(iso: &Isometry) -> bool { iso.translation.vector.is_zero() } #[inline] unsafe fn from_superset_unchecked(iso: &Isometry) -> Self { ::convert_ref_unchecked(&iso.rotation) } } impl SubsetOf> for UnitQuaternion where N1: Real, N2: Real + SupersetOf, R: AlgaRotation> + SupersetOf>, { #[inline] fn to_superset(&self) -> Similarity { Similarity::from_isometry(::convert_ref(self), N2::one()) } #[inline] fn is_in_subset(sim: &Similarity) -> bool { sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one() } #[inline] unsafe fn from_superset_unchecked(sim: &Similarity) -> Self { ::convert_ref_unchecked(&sim.isometry) } } impl SubsetOf> for UnitQuaternion where N1: Real, N2: Real + SupersetOf, C: SuperTCategoryOf, { #[inline] fn to_superset(&self) -> Transform { Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) } #[inline] fn is_in_subset(t: &Transform) -> bool { >::is_in_subset(t.matrix()) } #[inline] unsafe fn from_superset_unchecked(t: &Transform) -> Self { Self::from_superset_unchecked(t.matrix()) } } impl> SubsetOf> for UnitQuaternion { #[inline] fn to_superset(&self) -> Matrix4 { self.to_homogeneous().to_superset() } #[inline] fn is_in_subset(m: &Matrix4) -> bool { ::is_convertible::<_, Rotation3>(m) } #[inline] unsafe fn from_superset_unchecked(m: &Matrix4) -> Self { let rot: Rotation3 = ::convert_ref_unchecked(m); Self::from_rotation_matrix(&rot) } } #[cfg(feature = "mint")] impl From> for Quaternion { fn from(q: mint::Quaternion) -> Self { Quaternion::new(q.s, q.v.x, q.v.y, q.v.z) } } #[cfg(feature = "mint")] impl Into> for Quaternion { fn into(self) -> mint::Quaternion { mint::Quaternion { v: mint::Vector3 { x: self[0], y: self[1], z: self[2], }, s: self[3], } } } #[cfg(feature = "mint")] impl Into> for UnitQuaternion { fn into(self) -> mint::Quaternion { mint::Quaternion { v: mint::Vector3 { x: self[0], y: self[1], z: self[2], }, s: self[3], } } } impl From> for Matrix4 { #[inline] fn from(q: UnitQuaternion) -> Matrix4 { q.to_homogeneous() } } impl From> for Matrix3 { #[inline] fn from(q: UnitQuaternion) -> Matrix3 { q.to_rotation_matrix().unwrap() } }