use num::Zero; use simba::scalar::{RealField, SubsetOf, SupersetOf}; use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use crate::base::{Matrix3, Matrix4, Scalar, Vector4}; use crate::geometry::{ AbstractRotation, Isometry, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, UnitDualQuaternion, UnitQuaternion, }; /* * This file provides the following conversions: * ============================================= * * Quaternion -> Quaternion * UnitQuaternion -> UnitQuaternion * UnitQuaternion -> Rotation<3> * UnitQuaternion -> Isometry<3> * UnitQuaternion -> UnitDualQuaternion * UnitQuaternion -> Similarity<3> * UnitQuaternion -> Transform<3> * UnitQuaternion -> Matrix (homogeneous) * * NOTE: * UnitQuaternion -> Quaternion is already provided by: Unit -> T */ impl SubsetOf> for Quaternion where T1: Scalar, T2: Scalar + SupersetOf, { #[inline] fn to_superset(&self) -> Quaternion { Quaternion::from(self.coords.to_superset()) } #[inline] fn is_in_subset(q: &Quaternion) -> bool { crate::is_convertible::<_, Vector4>(&q.coords) } #[inline] fn from_superset_unchecked(q: &Quaternion) -> Self { Self { coords: q.coords.to_subset_unchecked(), } } } impl SubsetOf> for UnitQuaternion where T1: Scalar, T2: Scalar + SupersetOf, { #[inline] fn to_superset(&self) -> UnitQuaternion { UnitQuaternion::new_unchecked(self.as_ref().to_superset()) } #[inline] fn is_in_subset(uq: &UnitQuaternion) -> bool { crate::is_convertible::<_, Quaternion>(uq.as_ref()) } #[inline] fn from_superset_unchecked(uq: &UnitQuaternion) -> Self { Self::new_unchecked(crate::convert_ref_unchecked(uq.as_ref())) } } impl SubsetOf> for UnitQuaternion where T1: RealField, T2: RealField + 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 { crate::is_convertible::<_, Rotation3>(rot) } #[inline] fn from_superset_unchecked(rot: &Rotation3) -> Self { let q = UnitQuaternion::::from_rotation_matrix(rot); crate::convert_unchecked(q) } } impl SubsetOf> for UnitQuaternion where T1: RealField, T2: RealField + SupersetOf, R: AbstractRotation + SupersetOf, { #[inline] fn to_superset(&self) -> Isometry { Isometry::from_parts(Translation::identity(), crate::convert_ref(self)) } #[inline] fn is_in_subset(iso: &Isometry) -> bool { iso.translation.vector.is_zero() } #[inline] fn from_superset_unchecked(iso: &Isometry) -> Self { crate::convert_ref_unchecked(&iso.rotation) } } impl SubsetOf> for UnitQuaternion where T1: RealField, T2: RealField + SupersetOf, { #[inline] fn to_superset(&self) -> UnitDualQuaternion { let q: UnitQuaternion = crate::convert_ref(self); UnitDualQuaternion::from_rotation(q) } #[inline] fn is_in_subset(dq: &UnitDualQuaternion) -> bool { dq.translation().vector.is_zero() } #[inline] fn from_superset_unchecked(dq: &UnitDualQuaternion) -> Self { crate::convert_unchecked(dq.rotation()) } } impl SubsetOf> for UnitQuaternion where T1: RealField, T2: RealField + SupersetOf, R: AbstractRotation + SupersetOf, { #[inline] fn to_superset(&self) -> Similarity { Similarity::from_isometry(crate::convert_ref(self), T2::one()) } #[inline] fn is_in_subset(sim: &Similarity) -> bool { sim.isometry.translation.vector.is_zero() && sim.scaling() == T2::one() } #[inline] fn from_superset_unchecked(sim: &Similarity) -> Self { crate::convert_ref_unchecked(&sim.isometry) } } impl SubsetOf> for UnitQuaternion where T1: RealField, T2: RealField + SupersetOf, C: SuperTCategoryOf, { #[inline] fn to_superset(&self) -> Transform { Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset()) } #[inline] fn is_in_subset(t: &Transform) -> bool { >::is_in_subset(t.matrix()) } #[inline] fn from_superset_unchecked(t: &Transform) -> Self { Self::from_superset_unchecked(t.matrix()) } } impl> SubsetOf> for UnitQuaternion { #[inline] fn to_superset(&self) -> Matrix4 { self.clone().to_homogeneous().to_superset() } #[inline] fn is_in_subset(m: &Matrix4) -> bool { crate::is_convertible::<_, Rotation3>(m) } #[inline] fn from_superset_unchecked(m: &Matrix4) -> Self { let rot: Rotation3 = crate::convert_ref_unchecked(m); Self::from_rotation_matrix(&rot) } } impl From> for Matrix4 where T::Element: SimdRealField, { #[inline] fn from(q: UnitQuaternion) -> Self { q.to_homogeneous() } } impl From> for Rotation3 where T::Element: SimdRealField, { #[inline] fn from(q: UnitQuaternion) -> Self { q.to_rotation_matrix() } } impl From> for UnitQuaternion where T::Element: SimdRealField, { #[inline] fn from(q: Rotation3) -> Self { Self::from_rotation_matrix(&q) } } impl From> for Matrix3 where T::Element: SimdRealField, { #[inline] fn from(q: UnitQuaternion) -> Self { q.to_rotation_matrix().into_inner() } } impl From> for Quaternion { #[inline] fn from(coords: Vector4) -> Self { Self { coords } } } impl From<[T; 4]> for Quaternion { #[inline] fn from(coords: [T; 4]) -> Self { Self { coords: coords.into(), } } } impl From<[Quaternion; 2]> for Quaternion where T: From<[::Element; 2]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [Quaternion; 2]) -> Self { Self::from(Vector4::from([arr[0].coords, arr[1].coords])) } } impl From<[Quaternion; 4]> for Quaternion where T: From<[::Element; 4]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [Quaternion; 4]) -> Self { Self::from(Vector4::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, ])) } } impl From<[Quaternion; 8]> for Quaternion where T: From<[::Element; 8]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [Quaternion; 8]) -> Self { Self::from(Vector4::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, arr[4].coords, arr[5].coords, arr[6].coords, arr[7].coords, ])) } } impl From<[Quaternion; 16]> for Quaternion where T: From<[::Element; 16]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [Quaternion; 16]) -> Self { Self::from(Vector4::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, arr[4].coords, arr[5].coords, arr[6].coords, arr[7].coords, arr[8].coords, arr[9].coords, arr[10].coords, arr[11].coords, arr[12].coords, arr[13].coords, arr[14].coords, arr[15].coords, ])) } } impl From<[UnitQuaternion; 2]> for UnitQuaternion where T: From<[::Element; 2]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [UnitQuaternion; 2]) -> Self { Self::new_unchecked(Quaternion::from([arr[0].into_inner(), arr[1].into_inner()])) } } impl From<[UnitQuaternion; 4]> for UnitQuaternion where T: From<[::Element; 4]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [UnitQuaternion; 4]) -> Self { Self::new_unchecked(Quaternion::from([ arr[0].into_inner(), arr[1].into_inner(), arr[2].into_inner(), arr[3].into_inner(), ])) } } impl From<[UnitQuaternion; 8]> for UnitQuaternion where T: From<[::Element; 8]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [UnitQuaternion; 8]) -> Self { Self::new_unchecked(Quaternion::from([ arr[0].into_inner(), arr[1].into_inner(), arr[2].into_inner(), arr[3].into_inner(), arr[4].into_inner(), arr[5].into_inner(), arr[6].into_inner(), arr[7].into_inner(), ])) } } impl From<[UnitQuaternion; 16]> for UnitQuaternion where T: From<[::Element; 16]>, T::Element: Scalar + Copy, { #[inline] fn from(arr: [UnitQuaternion; 16]) -> Self { Self::new_unchecked(Quaternion::from([ arr[0].into_inner(), arr[1].into_inner(), arr[2].into_inner(), arr[3].into_inner(), arr[4].into_inner(), arr[5].into_inner(), arr[6].into_inner(), arr[7].into_inner(), arr[8].into_inner(), arr[9].into_inner(), arr[10].into_inner(), arr[11].into_inner(), arr[12].into_inner(), arr[13].into_inner(), arr[14].into_inner(), arr[15].into_inner(), ])) } }