First pass to migrate the geometry module to const-generics.

This commit is contained in:
Crozet Sébastien 2021-04-07 14:29:20 +02:00
parent 35ec135d2c
commit 8abbb35b40
46 changed files with 1048 additions and 1060 deletions

View File

@ -4,8 +4,7 @@ use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::base::storage::Owned; use crate::base::storage::Owned;
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage; use crate::base::vec_storage::VecStorage;
use crate::base::Matrix; use crate::base::{Const, Matrix, Unit};
use crate::base::Unit;
/* /*
* *
@ -24,11 +23,14 @@ pub type MatrixNM<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>; pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
pub type CMatrixMN<N, const R: usize, const C: usize> =
Matrix<N, Const<R>, Const<C>, Owned<N, Const<R>, Const<C>>>;
/// A statically sized column-major square matrix with `D` rows and columns. /// A statically sized column-major square matrix with `D` rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixN<N, D> = Matrix<N, D, D, Owned<N, D, D>>; pub type MatrixN<N, D> = Matrix<N, D, D, Owned<N, D, D>>;
pub type CMatrixN<N, const D: usize> = Matrix<N, Const<D>, Const<D>, Owned<N, Const<D>, Const<D>>>;
/// A dynamically sized column-major matrix. /// A dynamically sized column-major matrix.
/// ///
@ -266,6 +268,7 @@ pub type DVector<N> = Matrix<N, Dynamic, U1, VecStorage<N, Dynamic, U1>>;
/// A statically sized D-dimensional column vector. /// A statically sized D-dimensional column vector.
pub type VectorN<N, D> = Matrix<N, D, U1, Owned<N, D, U1>>; pub type VectorN<N, D> = Matrix<N, D, U1, Owned<N, D, U1>>;
pub type CVectorN<N, const D: usize> = Matrix<N, Const<D>, U1, Owned<N, Const<D>, U1>>;
/// A stack-allocated, 1-dimensional column vector. /// A stack-allocated, 1-dimensional column vector.
pub type Vector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>; pub type Vector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>;

View File

@ -416,8 +416,8 @@ where
#[inline] #[inline]
pub fn transform_point( pub fn transform_point(
&self, &self,
pt: &Point<N, DimNameDiff<D, U1>>, pt: &Point<N, { DimNameDiff::<D, U1>::USIZE }>,
) -> Point<N, DimNameDiff<D, U1>> { ) -> Point<N, { DimNameDiff::<D, U1>::USIZE }> {
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0); let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1); let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1);
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0); let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);

View File

@ -201,6 +201,8 @@ pub struct Const<const R: usize>;
/// Trait implemented exclusively by type-level integers. /// Trait implemented exclusively by type-level integers.
pub trait DimName: Dim { pub trait DimName: Dim {
const USIZE: usize;
/// The name of this dimension, i.e., the singleton `Self`. /// The name of this dimension, i.e., the singleton `Self`.
fn name() -> Self; fn name() -> Self;
@ -233,6 +235,8 @@ impl<const T: usize> Dim for Const<T> {
} }
impl<const T: usize> DimName for Const<T> { impl<const T: usize> DimName for Const<T> {
const USIZE: usize = T;
#[inline] #[inline]
fn name() -> Self { fn name() -> Self {
Self Self

View File

@ -1,11 +1,10 @@
use crate::allocator::Allocator;
use crate::geometry::{Rotation, UnitComplex, UnitQuaternion}; use crate::geometry::{Rotation, UnitComplex, UnitQuaternion};
use crate::{DefaultAllocator, DimName, Point, Scalar, SimdRealField, Unit, VectorN, U2, U3}; use crate::{CVectorN, Const, Point, Scalar, SimdRealField, Unit, VectorN};
use simba::scalar::ClosedMul; use simba::scalar::ClosedMul;
/// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`. /// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`.
pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone { pub trait AbstractRotation<N: Scalar, const D: usize>: PartialEq + ClosedMul + Clone {
/// The rotation identity. /// The rotation identity.
fn identity() -> Self; fn identity() -> Self;
/// The rotation inverse. /// The rotation inverse.
@ -13,34 +12,34 @@ pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone
/// Change `self` to its inverse. /// Change `self` to its inverse.
fn inverse_mut(&mut self); fn inverse_mut(&mut self);
/// Apply the rotation to the given vector. /// Apply the rotation to the given vector.
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>;
where // where
DefaultAllocator: Allocator<N, D>; // DefaultAllocator: Allocator<N, D>;
/// Apply the rotation to the given point. /// Apply the rotation to the given point.
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D> fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>;
where // where
DefaultAllocator: Allocator<N, D>; // DefaultAllocator: Allocator<N, D>;
/// Apply the inverse rotation to the given vector. /// Apply the inverse rotation to the given vector.
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> fn inverse_transform_vector(&self, v: &VectorN<N, Const<D>>) -> VectorN<N, Const<D>>;
where // where
DefaultAllocator: Allocator<N, D>; // DefaultAllocator: Allocator<N, D>;
/// Apply the inverse rotation to the given unit vector. /// Apply the inverse rotation to the given unit vector.
fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
Unit::new_unchecked(self.inverse_transform_vector(&**v)) Unit::new_unchecked(self.inverse_transform_vector(&**v))
} }
/// Apply the inverse rotation to the given point. /// Apply the inverse rotation to the given point.
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D> fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>;
where // where
DefaultAllocator: Allocator<N, D>; // DefaultAllocator: Allocator<N, D>;
} }
impl<N: SimdRealField, D: DimName> AbstractRotation<N, D> for Rotation<N, D> impl<N: SimdRealField, const D: usize> AbstractRotation<N, D> for Rotation<N, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -58,47 +57,47 @@ where
} }
#[inline] #[inline]
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
self * v self * v
} }
#[inline] #[inline]
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D> fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
self * p self * p
} }
#[inline] #[inline]
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
self.inverse_transform_unit_vector(v) self.inverse_transform_unit_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D> fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
self.inverse_transform_point(p) self.inverse_transform_point(p)
} }
} }
impl<N: SimdRealField> AbstractRotation<N, U3> for UnitQuaternion<N> impl<N: SimdRealField> AbstractRotation<N, 3> for UnitQuaternion<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
@ -118,27 +117,27 @@ where
} }
#[inline] #[inline]
fn transform_vector(&self, v: &VectorN<N, U3>) -> VectorN<N, U3> { fn transform_vector(&self, v: &CVectorN<N, 3>) -> CVectorN<N, 3> {
self * v self * v
} }
#[inline] #[inline]
fn transform_point(&self, p: &Point<N, U3>) -> Point<N, U3> { fn transform_point(&self, p: &Point<N, 3>) -> Point<N, 3> {
self * p self * p
} }
#[inline] #[inline]
fn inverse_transform_vector(&self, v: &VectorN<N, U3>) -> VectorN<N, U3> { fn inverse_transform_vector(&self, v: &CVectorN<N, 3>) -> CVectorN<N, 3> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_point(&self, p: &Point<N, U3>) -> Point<N, U3> { fn inverse_transform_point(&self, p: &Point<N, 3>) -> Point<N, 3> {
self.inverse_transform_point(p) self.inverse_transform_point(p)
} }
} }
impl<N: SimdRealField> AbstractRotation<N, U2> for UnitComplex<N> impl<N: SimdRealField> AbstractRotation<N, 2> for UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
@ -158,22 +157,22 @@ where
} }
#[inline] #[inline]
fn transform_vector(&self, v: &VectorN<N, U2>) -> VectorN<N, U2> { fn transform_vector(&self, v: &CVectorN<N, 2>) -> CVectorN<N, 2> {
self * v self * v
} }
#[inline] #[inline]
fn transform_point(&self, p: &Point<N, U2>) -> Point<N, U2> { fn transform_point(&self, p: &Point<N, 2>) -> Point<N, 2> {
self * p self * p
} }
#[inline] #[inline]
fn inverse_transform_vector(&self, v: &VectorN<N, U2>) -> VectorN<N, U2> { fn inverse_transform_vector(&self, v: &CVectorN<N, 2>) -> CVectorN<N, 2> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_point(&self, p: &Point<N, U2>) -> Point<N, U2> { fn inverse_transform_point(&self, p: &Point<N, 2>) -> Point<N, 2> {
self.inverse_transform_point(p) self.inverse_transform_point(p)
} }
} }

View File

@ -1,7 +1,6 @@
use simba::scalar::{RealField, SubsetOf, SupersetOf}; use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::dimension::U3;
use crate::base::{Matrix4, Vector4}; use crate::base::{Matrix4, Vector4};
use crate::geometry::{ use crate::geometry::{
DualQuaternion, Isometry3, Similarity3, SuperTCategoryOf, TAffine, Transform, Translation3, DualQuaternion, Isometry3, Similarity3, SuperTCategoryOf, TAffine, Transform, Translation3,
@ -14,9 +13,9 @@ use crate::geometry::{
* *
* DualQuaternion -> DualQuaternion * DualQuaternion -> DualQuaternion
* UnitDualQuaternion -> UnitDualQuaternion * UnitDualQuaternion -> UnitDualQuaternion
* UnitDualQuaternion -> Isometry<U3> * UnitDualQuaternion -> Isometry<3>
* UnitDualQuaternion -> Similarity<U3> * UnitDualQuaternion -> Similarity<3>
* UnitDualQuaternion -> Transform<U3> * UnitDualQuaternion -> Transform<3>
* UnitDualQuaternion -> Matrix<U4> (homogeneous) * UnitDualQuaternion -> Matrix<U4> (homogeneous)
* *
* NOTE: * NOTE:
@ -115,24 +114,24 @@ where
} }
} }
impl<N1, N2, C> SubsetOf<Transform<N2, U3, C>> for UnitDualQuaternion<N1> impl<N1, N2, C> SubsetOf<Transform<N2, C, 3>> for UnitDualQuaternion<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, U3, C> { fn to_superset(&self) -> Transform<N2, C, 3> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, U3, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, 3>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, U3, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, 3>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }

View File

@ -14,9 +14,9 @@ use simba::scalar::{RealField, SubsetOf};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::storage::Owned; use crate::base::storage::Owned;
use crate::base::{DefaultAllocator, MatrixN, Scalar, Unit, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar, Unit};
use crate::geometry::{AbstractRotation, Point, Translation}; use crate::geometry::{AbstractRotation, Point, Translation};
/// A direct isometry, i.e., a rotation followed by a translation (aka. a rigid-body motion). /// A direct isometry, i.e., a rotation followed by a translation (aka. a rigid-body motion).
@ -68,9 +68,9 @@ use crate::geometry::{AbstractRotation, Point, Translation};
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Deserialize<'de>")) Owned<N, D>: Deserialize<'de>"))
)] )]
pub struct Isometry<N: Scalar, D: DimName, R> pub struct Isometry<N: Scalar, R, const D: usize>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// The pure rotational part of this isometry. /// The pure rotational part of this isometry.
pub rotation: R, pub rotation: R,
@ -79,13 +79,12 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N, D, R> Abomonation for Isometry<N, D, R> impl<N, R, const D: usize> Abomonation for Isometry<N, R, D>
where where
N: SimdRealField, N: SimdRealField,
D: DimName,
R: Abomonation, R: Abomonation,
Translation<N, D>: Abomonation, Translation<N, D>: Abomonation,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.rotation.entomb(writer)?; self.rotation.entomb(writer)?;
@ -103,11 +102,10 @@ where
} }
} }
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Isometry<N, R, D>
for Isometry<N, D, R>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: hash::Hash, Owned<N, Const<D>>: hash::Hash,
{ {
fn hash<H: hash::Hasher>(&self, state: &mut H) { fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.translation.hash(state); self.translation.hash(state);
@ -115,16 +113,15 @@ where
} }
} }
impl<N: Scalar + Copy, D: DimName + Copy, R: Copy> Copy for Isometry<N, D, R> impl<N: Scalar + Copy, R: Copy, const D: usize> Copy for Isometry<N, R, D> where
where // DefaultAllocator: Allocator<N, D>,
DefaultAllocator: Allocator<N, D>, Owned<N, Const<D>>: Copy
Owned<N, D>: Copy,
{ {
} }
impl<N: Scalar, D: DimName, R: Clone> Clone for Isometry<N, D, R> impl<N: Scalar, R: Clone, const D: usize> Clone for Isometry<N, R, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -135,9 +132,9 @@ where
} }
} }
/// # From the translation and rotation parts /// # From the translation and rotation parts
impl<N: Scalar, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R> impl<N: Scalar, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new isometry from its rotational and translational parts. /// Creates a new isometry from its rotational and translational parts.
/// ///
@ -163,10 +160,10 @@ where
} }
/// # Inversion and in-place composition /// # Inversion and in-place composition
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R> impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Inverts `self`. /// Inverts `self`.
/// ///
@ -223,7 +220,7 @@ where
/// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2)); /// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2));
/// ``` /// ```
#[inline] #[inline]
pub fn inv_mul(&self, rhs: &Isometry<N, D, R>) -> Self { pub fn inv_mul(&self, rhs: &Isometry<N, R, D>) -> Self {
let inv_rot1 = self.rotation.inverse(); let inv_rot1 = self.rotation.inverse();
let tr_12 = rhs.translation.vector.clone() - self.translation.vector.clone(); let tr_12 = rhs.translation.vector.clone() - self.translation.vector.clone();
Isometry::from_parts( Isometry::from_parts(
@ -318,10 +315,10 @@ where
} }
/// # Transformation of a vector or a point /// # Transformation of a vector or a point
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R> impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Transform the given point by this isometry. /// Transform the given point by this isometry.
/// ///
@ -364,7 +361,7 @@ where
/// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6); /// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self * v self * v
} }
@ -410,7 +407,7 @@ where
/// assert_relative_eq!(transformed_point, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6); /// assert_relative_eq!(transformed_point, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self.rotation.inverse_transform_vector(v) self.rotation.inverse_transform_vector(v)
} }
@ -433,7 +430,7 @@ where
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6); /// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> { pub fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>> {
self.rotation.inverse_transform_unit_vector(v) self.rotation.inverse_transform_unit_vector(v)
} }
} }
@ -443,9 +440,9 @@ where
// This is OK since all constructors of the isometry enforce the Rotation bound already (and // This is OK since all constructors of the isometry enforce the Rotation bound already (and
// explicit struct construction is prevented by the dummy ZST field). // explicit struct construction is prevented by the dummy ZST field).
/// # Conversion to a matrix /// # Conversion to a matrix
impl<N: SimdRealField, D: DimName, R> Isometry<N, D, R> impl<N: SimdRealField, R, const D: usize> Isometry<N, R, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Converts this isometry into its equivalent homogeneous transformation matrix. /// Converts this isometry into its equivalent homogeneous transformation matrix.
/// ///
@ -465,14 +462,14 @@ where
/// assert_relative_eq!(iso.to_homogeneous(), expected, epsilon = 1.0e-6); /// assert_relative_eq!(iso.to_homogeneous(), expected, epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
let mut res: MatrixN<N, _> = crate::convert_ref(&self.rotation); let mut res: MatrixN<N, _> = crate::convert_ref(&self.rotation);
res.fixed_slice_mut::<D, U1>(0, D::dim()) res.fixed_slice_mut::<Const<D>, U1>(0, D)
.copy_from(&self.translation.vector); .copy_from(&self.translation.vector);
res res
@ -496,27 +493,25 @@ where
/// assert_relative_eq!(iso.to_matrix(), expected, epsilon = 1.0e-6); /// assert_relative_eq!(iso.to_matrix(), expected, epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn to_matrix(&self) -> MatrixN<N, DimNameSum<D, U1>> pub fn to_matrix(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
self.to_homogeneous() self.to_homogeneous()
} }
} }
impl<N: SimdRealField, D: DimName, R> Eq for Isometry<N, D, R> impl<N: SimdRealField, R, const D: usize> Eq for Isometry<N, R, D> where
where R: AbstractRotation<N, D> + Eq // DefaultAllocator: Allocator<N, D>,
R: AbstractRotation<N, D> + Eq,
DefaultAllocator: Allocator<N, D>,
{ {
} }
impl<N: SimdRealField, D: DimName, R> PartialEq for Isometry<N, D, R> impl<N: SimdRealField, R, const D: usize> PartialEq for Isometry<N, R, D>
where where
R: AbstractRotation<N, D> + PartialEq, R: AbstractRotation<N, D> + PartialEq,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -524,10 +519,10 @@ where
} }
} }
impl<N: RealField, D: DimName, R> AbsDiffEq for Isometry<N, D, R> impl<N: RealField, R, const D: usize> AbsDiffEq for Isometry<N, R, D>
where where
R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>, R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -544,10 +539,10 @@ where
} }
} }
impl<N: RealField, D: DimName, R> RelativeEq for Isometry<N, D, R> impl<N: RealField, R, const D: usize> RelativeEq for Isometry<N, R, D>
where where
R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>, R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -570,10 +565,10 @@ where
} }
} }
impl<N: RealField, D: DimName, R> UlpsEq for Isometry<N, D, R> impl<N: RealField, R, const D: usize> UlpsEq for Isometry<N, R, D>
where where
R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>, R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -594,10 +589,10 @@ where
* Display * Display
* *
*/ */
impl<N: RealField + fmt::Display, D: DimName, R> fmt::Display for Isometry<N, D, R> impl<N: RealField + fmt::Display, R, const D: usize> fmt::Display for Isometry<N, R, D>
where where
R: fmt::Display, R: fmt::Display,
DefaultAllocator: Allocator<N, D> + Allocator<usize, D>, // DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);

View File

@ -1,5 +1,3 @@
use crate::base::dimension::{U2, U3};
use crate::geometry::{Isometry, Rotation2, Rotation3, UnitComplex, UnitQuaternion}; use crate::geometry::{Isometry, Rotation2, Rotation3, UnitComplex, UnitQuaternion};
/// A 2-dimensional direct isometry using a unit complex number for its rotational part. /// A 2-dimensional direct isometry using a unit complex number for its rotational part.
@ -8,28 +6,28 @@ use crate::geometry::{Isometry, Rotation2, Rotation3, UnitComplex, UnitQuaternio
/// ///
/// Also known as a 2D rigid-body motion, or as an element of SE(2). /// Also known as a 2D rigid-body motion, or as an element of SE(2).
pub type Isometry2<N> = Isometry<N, U2, UnitComplex<N>>; pub type Isometry2<N> = Isometry<N, UnitComplex<N>, 2>;
/// A 3-dimensional direct isometry using a unit quaternion for its rotational part. /// A 3-dimensional direct isometry using a unit quaternion for its rotational part.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
/// ///
/// Also known as a rigid-body motion, or as an element of SE(3). /// Also known as a rigid-body motion, or as an element of SE(3).
pub type Isometry3<N> = Isometry<N, U3, UnitQuaternion<N>>; pub type Isometry3<N> = Isometry<N, UnitQuaternion<N>, 3>;
/// A 2-dimensional direct isometry using a rotation matrix for its rotational part. /// A 2-dimensional direct isometry using a rotation matrix for its rotational part.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
/// ///
/// Also known as a rigid-body motion, or as an element of SE(2). /// Also known as a rigid-body motion, or as an element of SE(2).
pub type IsometryMatrix2<N> = Isometry<N, U2, Rotation2<N>>; pub type IsometryMatrix2<N> = Isometry<N, Rotation2<N>, 2>;
/// A 3-dimensional direct isometry using a rotation matrix for its rotational part. /// A 3-dimensional direct isometry using a rotation matrix for its rotational part.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
/// ///
/// Also known as a rigid-body motion, or as an element of SE(3). /// Also known as a rigid-body motion, or as an element of SE(3).
pub type IsometryMatrix3<N> = Isometry<N, U3, Rotation3<N>>; pub type IsometryMatrix3<N> = Isometry<N, Rotation3<N>, 3>;
// This tests that the types correctly implement `Copy`, without having to run tests // This tests that the types correctly implement `Copy`, without having to run tests
// (when targeting no-std for example). // (when targeting no-std for example).

View File

@ -13,9 +13,8 @@ use rand::{
use simba::scalar::SupersetOf; use simba::scalar::SupersetOf;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::dimension::U2;
use crate::base::dimension::{DimName, U2}; use crate::base::{Vector2, Vector3};
use crate::base::{DefaultAllocator, Vector2, Vector3};
use crate::{ use crate::{
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point, AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point,
@ -23,10 +22,10 @@ use crate::{
UnitQuaternion, UnitQuaternion,
}; };
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R> impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new identity isometry. /// Creates a new identity isometry.
/// ///
@ -71,10 +70,10 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> One for Isometry<N, D, R> impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> One for Isometry<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new identity isometry. /// Creates a new identity isometry.
#[inline] #[inline]
@ -84,26 +83,26 @@ where
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: crate::RealField, D: DimName, R> Distribution<Isometry<N, D, R>> for Standard impl<N: crate::RealField, R, const D: usize> Distribution<Isometry<N, R, D>> for Standard
where where
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
Standard: Distribution<N> + Distribution<R>, Standard: Distribution<N> + Distribution<R>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, D, R> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, R, D> {
Isometry::from_parts(rng.gen(), rng.gen()) Isometry::from_parts(rng.gen(), rng.gen())
} }
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N, D: DimName, R> Arbitrary for Isometry<N, D, R> impl<N, R, const D: usize> Arbitrary for Isometry<N, R, D>
where where
N: SimdRealField + Arbitrary + Send, N: SimdRealField + Arbitrary + Send,
N::Element: SimdRealField, N::Element: SimdRealField,
R: AbstractRotation<N, D> + Arbitrary + Send, R: AbstractRotation<N, D> + Arbitrary + Send,
Owned<N, D>: Send, Owned<N, D>: Send,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn arbitrary(rng: &mut Gen) -> Self { fn arbitrary(rng: &mut Gen) -> Self {

View File

@ -2,8 +2,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN, Scalar}; use crate::base::{Const, DefaultAllocator, MatrixN, Scalar};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Isometry3, Similarity, SuperTCategoryOf, TAffine, Transform, AbstractRotation, Isometry, Isometry3, Similarity, SuperTCategoryOf, TAffine, Transform,
@ -21,27 +21,27 @@ use crate::geometry::{
* Isometry -> Matrix (homogeneous) * Isometry -> Matrix (homogeneous)
*/ */
impl<N1, N2, D: DimName, R1, R2> SubsetOf<Isometry<N2, D, R2>> for Isometry<N1, D, R1> impl<N1, N2, R1, R2, const D: usize> SubsetOf<Isometry<N2, R2, D>> for Isometry<N1, R1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R1: AbstractRotation<N1, D> + SubsetOf<R2>, R1: AbstractRotation<N1, D> + SubsetOf<R2>,
R2: AbstractRotation<N2, D>, R2: AbstractRotation<N2, D>,
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, D, R2> { fn to_superset(&self) -> Isometry<N2, R2, D> {
Isometry::from_parts(self.translation.to_superset(), self.rotation.to_superset()) Isometry::from_parts(self.translation.to_superset(), self.rotation.to_superset())
} }
#[inline] #[inline]
fn is_in_subset(iso: &Isometry<N2, D, R2>) -> bool { fn is_in_subset(iso: &Isometry<N2, R2, D>) -> bool {
crate::is_convertible::<_, Translation<N1, D>>(&iso.translation) crate::is_convertible::<_, Translation<N1, D>>(&iso.translation)
&& crate::is_convertible::<_, R1>(&iso.rotation) && crate::is_convertible::<_, R1>(&iso.rotation)
} }
#[inline] #[inline]
fn from_superset_unchecked(iso: &Isometry<N2, D, R2>) -> Self { fn from_superset_unchecked(iso: &Isometry<N2, R2, D>) -> Self {
Isometry::from_parts( Isometry::from_parts(
iso.translation.to_subset_unchecked(), iso.translation.to_subset_unchecked(),
iso.rotation.to_subset_unchecked(), iso.rotation.to_subset_unchecked(),
@ -73,102 +73,101 @@ where
} }
} }
impl<N1, N2, D: DimName, R1, R2> SubsetOf<Similarity<N2, D, R2>> for Isometry<N1, D, R1> impl<N1, N2, R1, R2, const D: usize> SubsetOf<Similarity<N2, R2, D>> for Isometry<N1, R1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R1: AbstractRotation<N1, D> + SubsetOf<R2>, R1: AbstractRotation<N1, D> + SubsetOf<R2>,
R2: AbstractRotation<N2, D>, R2: AbstractRotation<N2, D>,
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, D, R2> { fn to_superset(&self) -> Similarity<N2, R2, D> {
Similarity::from_isometry(self.to_superset(), N2::one()) Similarity::from_isometry(self.to_superset(), N2::one())
} }
#[inline] #[inline]
fn is_in_subset(sim: &Similarity<N2, D, R2>) -> bool { fn is_in_subset(sim: &Similarity<N2, R2, D>) -> bool {
crate::is_convertible::<_, Isometry<N1, D, R1>>(&sim.isometry) && sim.scaling() == N2::one() crate::is_convertible::<_, Isometry<N1, R1, D>>(&sim.isometry) && sim.scaling() == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(sim: &Similarity<N2, D, R2>) -> Self { fn from_superset_unchecked(sim: &Similarity<N2, R2, D>) -> Self {
crate::convert_ref_unchecked(&sim.isometry) crate::convert_ref_unchecked(&sim.isometry)
} }
} }
impl<N1, N2, D, R, C> SubsetOf<Transform<N2, D, C>> for Isometry<N1, D, R> impl<N1, N2, R, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Isometry<N1, R, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
R: AbstractRotation<N1, D> R: AbstractRotation<N1, D>
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>> + SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>, + SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal() Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
DefaultAllocator: Allocator<N1, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, D, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N1, D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<(usize, usize), D>
+ Allocator<(usize, usize), D> // + Allocator<N2, D, D>
+ Allocator<N2, D, D> // + Allocator<N2, D>
+ Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, D, C> { fn to_superset(&self) -> Transform<N2, C, D> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, D, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }
impl<N1, N2, D, R> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Isometry<N1, D, R> impl<N1, N2, R, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>
for Isometry<N1, R, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N1, D> R: AbstractRotation<N1, D>
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>> + SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>, + SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal() Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
DefaultAllocator: Allocator<N1, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, D, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<(usize, usize), D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N2, D, D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N2, D>
+ Allocator<(usize, usize), D> // + Allocator<N1, D>
+ Allocator<N2, D, D> // + Allocator<N1, D, D>
+ Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> { fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
self.to_homogeneous().to_superset() self.to_homogeneous().to_superset()
} }
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool { fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
let rot = m.fixed_slice::<D, D>(0, 0); let rot = m.fixed_slice::<D, D>(0, 0);
let bottom = m.fixed_slice::<U1, D>(D::dim(), 0); let bottom = m.fixed_slice::<U1, D>(D, 0);
// Scalar types agree. // Scalar types agree.
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) && m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
// The block part is a rotation. // The block part is a rotation.
rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) && rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) &&
// The bottom row is (0, 0, ..., 1) // The bottom row is (0, 0, ..., 1)
bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one() bottom.iter().all(|e| e.is_zero()) && m[(D, D)] == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let t = m.fixed_slice::<D, U1>(0, D::dim()).into_owned(); let t = m.fixed_slice::<D, U1>(0, D).into_owned();
let t = Translation { let t = Translation {
vector: crate::convert_unchecked(t), vector: crate::convert_unchecked(t),
}; };
@ -177,10 +176,10 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> From<Translation<N, D>> impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> From<Translation<N, D>>
for Isometry<N, D, R> for Isometry<N, R, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn from(tra: Translation<N, D>) -> Self { fn from(tra: Translation<N, D>) -> Self {
@ -188,30 +187,31 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R> From<Isometry<N, D, R>> for MatrixN<N, DimNameSum<D, U1>> impl<N: SimdRealField, R, const D: usize> From<Isometry<N, R, D>>
for MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> + Allocator<N, D>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<N, D>,
{ {
#[inline] #[inline]
fn from(iso: Isometry<N, D, R>) -> Self { fn from(iso: Isometry<N, R, D>) -> Self {
iso.to_homogeneous() iso.to_homogeneous()
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 2]> impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
for Isometry<N, D, R> From<[Isometry<N::Element, R::Element, D>; 2]> for Isometry<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 2]>, N: From<[<N as SimdValue>::Element; 2]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
R::Element: Scalar + Copy, R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 2]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 2]) -> Self {
let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]); let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]);
let rot = R::from([arr[0].rotation, arr[0].rotation]); let rot = R::from([arr[0].rotation, arr[0].rotation]);
@ -219,18 +219,18 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 4]> impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
for Isometry<N, D, R> From<[Isometry<N::Element, R::Element, D>; 4]> for Isometry<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 4]>, N: From<[<N as SimdValue>::Element; 4]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
R::Element: Scalar + Copy, R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 4]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 4]) -> Self {
let tra = Translation::from([ let tra = Translation::from([
arr[0].translation.clone(), arr[0].translation.clone(),
arr[1].translation.clone(), arr[1].translation.clone(),
@ -248,18 +248,18 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 8]> impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
for Isometry<N, D, R> From<[Isometry<N::Element, R::Element, D>; 8]> for Isometry<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 8]>, N: From<[<N as SimdValue>::Element; 8]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
R::Element: Scalar + Copy, R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 8]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 8]) -> Self {
let tra = Translation::from([ let tra = Translation::from([
arr[0].translation.clone(), arr[0].translation.clone(),
arr[1].translation.clone(), arr[1].translation.clone(),
@ -285,18 +285,18 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 16]> impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
for Isometry<N, D, R> From<[Isometry<N::Element, R::Element, D>; 16]> for Isometry<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 16]>, N: From<[<N as SimdValue>::Element; 16]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
R::Element: Scalar + Copy, R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 16]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 16]) -> Self {
let tra = Translation::from([ let tra = Translation::from([
arr[0].translation.clone(), arr[0].translation.clone(),
arr[1].translation.clone(), arr[1].translation.clone(),

View File

@ -1,20 +1,17 @@
use simba::simd::SimdValue; use simba::simd::SimdValue;
use crate::base::allocator::Allocator;
use crate::base::dimension::DimName;
use crate::base::DefaultAllocator;
use crate::SimdRealField; use crate::SimdRealField;
use crate::geometry::{AbstractRotation, Isometry, Translation}; use crate::geometry::{AbstractRotation, Isometry, Translation};
impl<N: SimdRealField, D: DimName, R> SimdValue for Isometry<N, D, R> impl<N: SimdRealField, R, const D: usize> SimdValue for Isometry<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>, R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
type Element = Isometry<N::Element, D, R::Element>; type Element = Isometry<N::Element, R::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;
#[inline] #[inline]

View File

@ -40,54 +40,49 @@ use crate::base::{Const, DefaultAllocator, Scalar, VectorN};
/// of said transformations for details. /// of said transformations for details.
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Point<N: Scalar, D: DimName> pub struct Point<N: Scalar, const D: usize> {
where
DefaultAllocator: Allocator<N, D>,
{
/// The coordinates of this point, i.e., the shift from the origin. /// The coordinates of this point, i.e., the shift from the origin.
pub coords: VectorN<N, D>, pub coords: VectorN<N, Const<D>>,
} }
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash> hash::Hash for Point<N, D> impl<N: Scalar + hash::Hash, const D: usize> hash::Hash for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
<DefaultAllocator as Allocator<N, D>>::Buffer: hash::Hash, // <DefaultAllocator as Allocator<N, D>>::Buffer: hash::Hash,
{ {
fn hash<H: hash::Hasher>(&self, state: &mut H) { fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.coords.hash(state) self.coords.hash(state)
} }
} }
impl<N: Scalar + Copy, D: DimName> Copy for Point<N, D> impl<N: Scalar + Copy, const D: usize> Copy for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
<DefaultAllocator as Allocator<N, D>>::Buffer: Copy, // <DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
{ {
} }
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<N: Scalar, D: DimName> bytemuck::Zeroable for Point<N, D> unsafe impl<N: Scalar, const D: usize> bytemuck::Zeroable for Point<N, D> where
where VectorN<N, Const<D>>: bytemuck::Zeroable // DefaultAllocator: Allocator<N, D>,
VectorN<N, D>: bytemuck::Zeroable,
DefaultAllocator: Allocator<N, D>,
{ {
} }
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<N: Scalar, D: DimName> bytemuck::Pod for Point<N, D> unsafe impl<N: Scalar, const D: usize> bytemuck::Pod for Point<N, D>
where where
N: Copy, N: Copy,
VectorN<N, D>: bytemuck::Pod, VectorN<N, Const<D>>: bytemuck::Pod,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
<DefaultAllocator as Allocator<N, D>>::Buffer: Copy, // <DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
{ {
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: Scalar, D: DimName> Serialize for Point<N, D> impl<N: Scalar, const D: usize> Serialize for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
<DefaultAllocator as Allocator<N, D>>::Buffer: Serialize, // <DefaultAllocator as Allocator<N, D>>::Buffer: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -98,10 +93,10 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: Scalar, D: DimName> Deserialize<'a> for Point<N, D> impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
<DefaultAllocator as Allocator<N, D>>::Buffer: Deserialize<'a>, // <DefaultAllocator as Allocator<N, D>>::Buffer: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where where
@ -114,12 +109,11 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N, D> Abomonation for Point<N, D> impl<N, const D: usize> Abomonation for Point<N, D>
where where
N: Scalar, N: Scalar,
D: DimName, VectorN<N, Const<D>>: Abomonation,
VectorN<N, D>: Abomonation, // DefaultAllocator: Allocator<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.coords.entomb(writer) self.coords.entomb(writer)
@ -134,9 +128,9 @@ where
} }
} }
impl<N: Scalar, D: DimName> Point<N, D> impl<N: Scalar, const D: usize> Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Returns a point containing the result of `f` applied to each of its entries. /// Returns a point containing the result of `f` applied to each of its entries.
/// ///
@ -152,8 +146,8 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, f: F) -> Point<N2, D> pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, f: F) -> Point<N2, D>
where // where
DefaultAllocator: Allocator<N2, D>, // DefaultAllocator: Allocator<N2, D>,
{ {
self.coords.map(f).into() self.coords.map(f).into()
} }
@ -193,20 +187,21 @@ where
/// assert_eq!(p.to_homogeneous(), Vector4::new(10.0, 20.0, 30.0, 1.0)); /// assert_eq!(p.to_homogeneous(), Vector4::new(10.0, 20.0, 30.0, 1.0));
/// ``` /// ```
#[inline] #[inline]
pub fn to_homogeneous(&self) -> VectorN<N, DimNameSum<D, U1>> pub fn to_homogeneous(&self) -> VectorN<N, DimNameSum<Const<D>, U1>>
where where
N: One, N: One,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>>,
{ {
let mut res = unsafe { let mut res = unsafe {
crate::unimplemented_or_uninitialized_generic!( crate::unimplemented_or_uninitialized_generic!(
<DimNameSum<D, U1> as DimName>::name(), <DimNameSum<Const<D>, U1> as DimName>::name(),
Const::<1> Const::<1>
) )
}; };
res.fixed_slice_mut::<D, U1>(0, 0).copy_from(&self.coords); res.fixed_slice_mut::<Const<D>, U1>(0, 0)
res[(D::dim(), 0)] = N::one(); .copy_from(&self.coords);
res[(D, 0)] = N::one();
res res
} }
@ -214,7 +209,7 @@ where
/// Creates a new point with the given coordinates. /// Creates a new point with the given coordinates.
#[deprecated(note = "Use Point::from(vector) instead.")] #[deprecated(note = "Use Point::from(vector) instead.")]
#[inline] #[inline]
pub fn from_coordinates(coords: VectorN<N, D>) -> Self { pub fn from_coordinates(coords: VectorN<N, Const<D>>) -> Self {
Self { coords } Self { coords }
} }
@ -269,7 +264,10 @@ where
/// assert_eq!(it.next(), Some(3.0)); /// assert_eq!(it.next(), Some(3.0));
/// assert_eq!(it.next(), None); /// assert_eq!(it.next(), None);
#[inline] #[inline]
pub fn iter(&self) -> MatrixIter<N, D, U1, <DefaultAllocator as Allocator<N, D>>::Buffer> { pub fn iter(
&self,
) -> MatrixIter<N, Const<D>, Const<1>, <DefaultAllocator as Allocator<N, Const<D>>>::Buffer>
{
self.coords.iter() self.coords.iter()
} }
@ -294,7 +292,8 @@ where
#[inline] #[inline]
pub fn iter_mut( pub fn iter_mut(
&mut self, &mut self,
) -> MatrixIterMut<N, D, U1, <DefaultAllocator as Allocator<N, D>>::Buffer> { ) -> MatrixIterMut<N, Const<D>, Const<1>, <DefaultAllocator as Allocator<N, Const<D>>>::Buffer>
{
self.coords.iter_mut() self.coords.iter_mut()
} }
@ -311,9 +310,9 @@ where
} }
} }
impl<N: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for Point<N, D> impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Point<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -329,9 +328,9 @@ where
} }
} }
impl<N: Scalar + RelativeEq, D: DimName> RelativeEq for Point<N, D> impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Point<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -351,9 +350,9 @@ where
} }
} }
impl<N: Scalar + UlpsEq, D: DimName> UlpsEq for Point<N, D> impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Point<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -367,11 +366,14 @@ where
} }
} }
impl<N: Scalar + Eq, D: DimName> Eq for Point<N, D> where DefaultAllocator: Allocator<N, D> {} impl<N: Scalar + Eq, const D: usize> Eq for Point<N, D>
// where DefaultAllocator: Allocator<N, D>
{
}
impl<N: Scalar, D: DimName> PartialEq for Point<N, D> impl<N: Scalar, const D: usize> PartialEq for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -379,9 +381,9 @@ where
} }
} }
impl<N: Scalar + PartialOrd, D: DimName> PartialOrd for Point<N, D> impl<N: Scalar + PartialOrd, const D: usize> PartialOrd for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
@ -412,9 +414,9 @@ where
/* /*
* inf/sup * inf/sup
*/ */
impl<N: Scalar + SimdPartialOrd, D: DimName> Point<N, D> impl<N: Scalar + SimdPartialOrd, const D: usize> Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Computes the infimum (aka. componentwise min) of two points. /// Computes the infimum (aka. componentwise min) of two points.
#[inline] #[inline]
@ -441,9 +443,9 @@ where
* Display * Display
* *
*/ */
impl<N: Scalar + fmt::Display, D: DimName> fmt::Display for Point<N, D> impl<N: Scalar + fmt::Display, const D: usize> fmt::Display for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{")?; write!(f, "{{")?;

View File

@ -1,28 +1,26 @@
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::geometry::Point; use crate::geometry::Point;
/// A statically sized 1-dimensional column point. /// A statically sized 1-dimensional column point.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
pub type Point1<N> = Point<N, U1>; pub type Point1<N> = Point<N, 1>;
/// A statically sized 2-dimensional column point. /// A statically sized 2-dimensional column point.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
pub type Point2<N> = Point<N, U2>; pub type Point2<N> = Point<N, 2>;
/// A statically sized 3-dimensional column point. /// A statically sized 3-dimensional column point.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
pub type Point3<N> = Point<N, U3>; pub type Point3<N> = Point<N, 3>;
/// A statically sized 4-dimensional column point. /// A statically sized 4-dimensional column point.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
pub type Point4<N> = Point<N, U4>; pub type Point4<N> = Point<N, 4>;
/// A statically sized 5-dimensional column point. /// A statically sized 5-dimensional column point.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
pub type Point5<N> = Point<N, U5>; pub type Point5<N> = Point<N, 5>;
/// A statically sized 6-dimensional column point. /// A statically sized 6-dimensional column point.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
pub type Point6<N> = Point<N, U6>; pub type Point6<N> = Point<N, 6>;

View File

@ -9,7 +9,7 @@ use rand::{
}; };
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, Scalar, VectorN}; use crate::base::{DefaultAllocator, Scalar, VectorN};
use crate::{ use crate::{
Const, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4, Const, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4,
@ -20,16 +20,15 @@ use simba::scalar::{ClosedDiv, SupersetOf};
use crate::geometry::Point; use crate::geometry::Point;
/// # Other construction methods /// # Other construction methods
impl<N: Scalar, D: DimName> Point<N, D> impl<N: Scalar, const D: usize> Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new point with uninitialized coordinates. /// Creates a new point with uninitialized coordinates.
#[inline] #[inline]
pub unsafe fn new_uninitialized() -> Self { pub unsafe fn new_uninitialized() -> Self {
Self::from(crate::unimplemented_or_uninitialized_generic!( Self::from(crate::unimplemented_or_uninitialized_generic!(
D::name(), Const::<D>, Const::<1>
Const::<1>
)) ))
} }
@ -106,14 +105,14 @@ where
/// assert_eq!(pt, Some(Point2::new(1.0, 2.0))); /// assert_eq!(pt, Some(Point2::new(1.0, 2.0)));
/// ``` /// ```
#[inline] #[inline]
pub fn from_homogeneous(v: VectorN<N, DimNameSum<D, U1>>) -> Option<Self> pub fn from_homogeneous(v: VectorN<N, DimNameSum<Const<D>, U1>>) -> Option<Self>
where where
N: Scalar + Zero + One + ClosedDiv, N: Scalar + Zero + One + ClosedDiv,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>>,
{ {
if !v[D::dim()].is_zero() { if !v[D].is_zero() {
let coords = v.fixed_slice::<D, U1>(0, 0) / v[D::dim()].inlined_clone(); let coords = v.fixed_slice::<Const<D>, U1>(0, 0) / v[D].inlined_clone();
Some(Self::from(coords)) Some(Self::from(coords))
} else { } else {
None None
@ -132,7 +131,7 @@ where
pub fn cast<To: Scalar>(self) -> Point<To, D> pub fn cast<To: Scalar>(self) -> Point<To, D>
where where
Point<To, D>: SupersetOf<Self>, Point<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D>, // DefaultAllocator: Allocator<To, D>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -143,9 +142,9 @@ where
* Traits that build points. * Traits that build points.
* *
*/ */
impl<N: Scalar + Bounded, D: DimName> Bounded for Point<N, D> impl<N: Scalar + Bounded, const D: usize> Bounded for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn max_value() -> Self { fn max_value() -> Self {
@ -159,9 +158,9 @@ where
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: Scalar, D: DimName> Distribution<Point<N, D>> for Standard impl<N: Scalar, const D: usize> Distribution<Point<N, D>> for Standard
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N>, Standard: Distribution<N>,
{ {
/// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`. /// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`.
@ -172,10 +171,10 @@ where
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: Scalar + Arbitrary + Send, D: DimName> Arbitrary for Point<N, D> impl<N: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Point<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
<DefaultAllocator as Allocator<N, D>>::Buffer: Send, <DefaultAllocator as Allocator<N, Const<D>>>::Buffer: Send,
{ {
#[inline] #[inline]
fn arbitrary(g: &mut Gen) -> Self { fn arbitrary(g: &mut Gen) -> Self {

View File

@ -3,8 +3,8 @@ use simba::scalar::{ClosedDiv, SubsetOf, SupersetOf};
use simba::simd::PrimitiveSimdValue; use simba::simd::PrimitiveSimdValue;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN}; use crate::base::{Const, DefaultAllocator, Matrix, Scalar, VectorN};
use crate::geometry::Point; use crate::geometry::Point;
@ -16,12 +16,11 @@ use crate::geometry::Point;
* Point -> Vector (homogeneous) * Point -> Vector (homogeneous)
*/ */
impl<N1, N2, D> SubsetOf<Point<N2, D>> for Point<N1, D> impl<N1, N2, const D: usize> SubsetOf<Point<N2, D>> for Point<N1, D>
where where
D: DimName,
N1: Scalar, N1: Scalar,
N2: Scalar + SupersetOf<N1>, N2: Scalar + SupersetOf<N1>,
DefaultAllocator: Allocator<N2, D> + Allocator<N1, D>, // DefaultAllocator: Allocator<N2, D> + Allocator<N1, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Point<N2, D> { fn to_superset(&self) -> Point<N2, D> {
@ -41,40 +40,41 @@ where
} }
} }
impl<N1, N2, D> SubsetOf<VectorN<N2, DimNameSum<D, U1>>> for Point<N1, D> impl<N1, N2, const D: usize> SubsetOf<VectorN<N2, DimNameSum<Const<D>, U1>>> for Point<N1, D>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
N1: Scalar, N1: Scalar,
N2: Scalar + Zero + One + ClosedDiv + SupersetOf<N1>, N2: Scalar + Zero + One + ClosedDiv + SupersetOf<N1>,
DefaultAllocator: Allocator<N1, D> DefaultAllocator:
+ Allocator<N1, DimNameSum<D, U1>> Allocator<N1, DimNameSum<Const<D>, U1>> + Allocator<N2, DimNameSum<Const<D>, U1>>,
+ Allocator<N2, DimNameSum<D, U1>> // + Allocator<N1, D>
+ Allocator<N2, D>, // + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> VectorN<N2, DimNameSum<D, U1>> { fn to_superset(&self) -> VectorN<N2, DimNameSum<Const<D>, U1>> {
let p: Point<N2, D> = self.to_superset(); let p: Point<N2, D> = self.to_superset();
p.to_homogeneous() p.to_homogeneous()
} }
#[inline] #[inline]
fn is_in_subset(v: &VectorN<N2, DimNameSum<D, U1>>) -> bool { fn is_in_subset(v: &VectorN<N2, DimNameSum<Const<D>, U1>>) -> bool {
crate::is_convertible::<_, VectorN<N1, DimNameSum<D, U1>>>(v) && !v[D::dim()].is_zero() crate::is_convertible::<_, VectorN<N1, DimNameSum<D, U1>>>(v) && !v[D].is_zero()
} }
#[inline] #[inline]
fn from_superset_unchecked(v: &VectorN<N2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(v: &VectorN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let coords = v.fixed_slice::<D, U1>(0, 0) / v[D::dim()].inlined_clone(); let coords = v.fixed_slice::<D, U1>(0, 0) / v[D].inlined_clone();
Self { Self {
coords: crate::convert_unchecked(coords), coords: crate::convert_unchecked(coords),
} }
} }
} }
impl<N: Scalar + Zero + One, D: DimName> From<Point<N, D>> for VectorN<N, DimNameSum<D, U1>> impl<N: Scalar + Zero + One, const D: usize> From<Point<N, D>>
for VectorN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn from(t: Point<N, D>) -> Self { fn from(t: Point<N, D>) -> Self {
@ -82,23 +82,23 @@ where
} }
} }
impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Point<N, D> impl<N: Scalar, const D: usize> From<VectorN<N, Const<D>>> for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn from(coords: VectorN<N, D>) -> Self { fn from(coords: VectorN<N, Const<D>>) -> Self {
Point { coords } Point { coords }
} }
} }
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 2]> impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 2]>
for Point<N, D> for Point<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 2]>, N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
fn from(arr: [Point<N::Element, D>; 2]) -> Self { fn from(arr: [Point<N::Element, D>; 2]) -> Self {
@ -106,13 +106,13 @@ where
} }
} }
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 4]> impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 4]>
for Point<N, D> for Point<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 4]>, N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
fn from(arr: [Point<N::Element, D>; 4]) -> Self { fn from(arr: [Point<N::Element, D>; 4]) -> Self {
@ -125,13 +125,13 @@ where
} }
} }
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 8]> impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 8]>
for Point<N, D> for Point<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 8]>, N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
fn from(arr: [Point<N::Element, D>; 8]) -> Self { fn from(arr: [Point<N::Element, D>; 8]) -> Self {
@ -148,13 +148,13 @@ where
} }
} }
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 16]> impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 16]>
for Point<N, D> for Point<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 16]>, N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
fn from(arr: [Point<N::Element, D>; 16]) -> Self { fn from(arr: [Point<N::Element, D>; 16]) -> Self {

View File

@ -1,9 +1,7 @@
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use crate::base::allocator::Allocator;
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB}; use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
use crate::base::dimension::{U1, U2, U3, U4, U5, U6}; use crate::base::Scalar;
use crate::base::{DefaultAllocator, Scalar};
use crate::geometry::Point; use crate::geometry::Point;
@ -14,9 +12,10 @@ use crate::geometry::Point;
*/ */
macro_rules! deref_impl( macro_rules! deref_impl(
($D: ty, $Target: ident $(, $comps: ident)*) => { ($D: expr, $Target: ident $(, $comps: ident)*) => {
impl<N: Scalar> Deref for Point<N, $D> impl<N: Scalar> Deref for Point<N, $D>
where DefaultAllocator: Allocator<N, $D> { // where DefaultAllocator: Allocator<N, $D>
{
type Target = $Target<N>; type Target = $Target<N>;
#[inline] #[inline]
@ -26,7 +25,8 @@ macro_rules! deref_impl(
} }
impl<N: Scalar> DerefMut for Point<N, $D> impl<N: Scalar> DerefMut for Point<N, $D>
where DefaultAllocator: Allocator<N, $D> { // where DefaultAllocator: Allocator<N, $D>
{
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut *self.coords &mut *self.coords
@ -35,9 +35,9 @@ macro_rules! deref_impl(
} }
); );
deref_impl!(U1, X, x); deref_impl!(1, X, x);
deref_impl!(U2, XY, x, y); deref_impl!(2, XY, x, y);
deref_impl!(U3, XYZ, x, y, z); deref_impl!(3, XYZ, x, y, z);
deref_impl!(U4, XYZW, x, y, z, w); deref_impl!(4, XYZW, x, y, z, w);
deref_impl!(U5, XYZWA, x, y, z, w, a); deref_impl!(5, XYZWA, x, y, z, w, a);
deref_impl!(U6, XYZWAB, x, y, z, w, a, b); deref_impl!(6, XYZWAB, x, y, z, w, a, b);

View File

@ -11,7 +11,7 @@ use crate::base::constraint::{
}; };
use crate::base::dimension::{Dim, DimName, U1}; use crate::base::dimension::{Dim, DimName, U1};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Matrix, Scalar, Vector, VectorSum}; use crate::base::{Const, DefaultAllocator, Matrix, Scalar, Vector, VectorSum};
use crate::geometry::Point; use crate::geometry::Point;
@ -20,9 +20,9 @@ use crate::geometry::Point;
* Indexing. * Indexing.
* *
*/ */
impl<N: Scalar, D: DimName> Index<usize> for Point<N, D> impl<N: Scalar, const D: usize> Index<usize> for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
type Output = N; type Output = N;
@ -32,9 +32,9 @@ where
} }
} }
impl<N: Scalar, D: DimName> IndexMut<usize> for Point<N, D> impl<N: Scalar, const D: usize> IndexMut<usize> for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn index_mut(&mut self, i: usize) -> &mut Self::Output { fn index_mut(&mut self, i: usize) -> &mut Self::Output {
@ -47,9 +47,9 @@ where
* Neg. * Neg.
* *
*/ */
impl<N: Scalar + ClosedNeg, D: DimName> Neg for Point<N, D> impl<N: Scalar + ClosedNeg, const D: usize> Neg for Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
type Output = Self; type Output = Self;
@ -59,9 +59,9 @@ where
} }
} }
impl<'a, N: Scalar + ClosedNeg, D: DimName> Neg for &'a Point<N, D> impl<'a, N: Scalar + ClosedNeg, const D: usize> Neg for &'a Point<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
type Output = Point<N, D>; type Output = Point<N, D>;
@ -79,22 +79,22 @@ where
// Point - Point // Point - Point
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D, U1), (D, U1) for D: DimName; (D, U1), (D, U1);
self: &'a Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>; self: &'a Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>;
&self.coords - &right.coords; 'a, 'b); &self.coords - &right.coords; 'a, 'b);
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D, U1), (D, U1) for D: DimName; (D, U1), (D, U1);
self: &'a Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>; self: &'a Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>;
&self.coords - right.coords; 'a); &self.coords - right.coords; 'a);
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D, U1), (D, U1) for D: DimName; (D, U1), (D, U1);
self: Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>; self: Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>;
self.coords - &right.coords; 'b); self.coords - &right.coords; 'b);
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D, U1), (D, U1) for D: DimName; (D, U1), (D, U1);
self: Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>; self: Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>;
self.coords - right.coords; ); self.coords - right.coords; );
@ -143,11 +143,11 @@ add_sub_impl!(Add, add, ClosedAdd;
// XXX: replace by the shared macro: add_sub_assign_impl // XXX: replace by the shared macro: add_sub_assign_impl
macro_rules! op_assign_impl( macro_rules! op_assign_impl(
($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$( ($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$(
impl<'b, N, D1: DimName, D2: Dim, SB> $TraitAssign<&'b Vector<N, D2, SB>> for Point<N, D1> impl<'b, N, D2: Dim, SB, const D1: usize> $TraitAssign<&'b Vector<N, D2, SB>> for Point<N, D1>
where N: Scalar + $bound, where N: Scalar + $bound,
SB: Storage<N, D2>, SB: Storage<N, D2>,
DefaultAllocator: Allocator<N, D1>, // DefaultAllocator: Allocator<N, D1>,
ShapeConstraint: SameNumberOfRows<D1, D2> { ShapeConstraint: SameNumberOfRows<Const<D1>, D2> {
#[inline] #[inline]
fn $method_assign(&mut self, right: &'b Vector<N, D2, SB>) { fn $method_assign(&mut self, right: &'b Vector<N, D2, SB>) {
@ -155,10 +155,10 @@ macro_rules! op_assign_impl(
} }
} }
impl<N, D1: DimName, D2: Dim, SB> $TraitAssign<Vector<N, D2, SB>> for Point<N, D1> impl<N, D2: Dim, SB, const D1: usize> $TraitAssign<Vector<N, D2, SB>> for Point<N, D1>
where N: Scalar + $bound, where N: Scalar + $bound,
SB: Storage<N, D2>, SB: Storage<N, D2>,
DefaultAllocator: Allocator<N, D1>, // DefaultAllocator: Allocator<N, D1>,
ShapeConstraint: SameNumberOfRows<D1, D2> { ShapeConstraint: SameNumberOfRows<D1, D2> {
#[inline] #[inline]
@ -198,8 +198,9 @@ md_impl_all!(
macro_rules! componentwise_scalarop_impl( macro_rules! componentwise_scalarop_impl(
($Trait: ident, $method: ident, $bound: ident; ($Trait: ident, $method: ident, $bound: ident;
$TraitAssign: ident, $method_assign: ident) => { $TraitAssign: ident, $method_assign: ident) => {
impl<N: Scalar + $bound, D: DimName> $Trait<N> for Point<N, D> impl<N: Scalar + $bound, const D: usize> $Trait<N> for Point<N, D>
where DefaultAllocator: Allocator<N, D> { // where DefaultAllocator: Allocator<N, D>
{
type Output = Point<N, D>; type Output = Point<N, D>;
#[inline] #[inline]
@ -208,8 +209,9 @@ macro_rules! componentwise_scalarop_impl(
} }
} }
impl<'a, N: Scalar + $bound, D: DimName> $Trait<N> for &'a Point<N, D> impl<'a, N: Scalar + $bound, const D: usize> $Trait<N> for &'a Point<N, D>
where DefaultAllocator: Allocator<N, D> { // where DefaultAllocator: Allocator<N, D>
{
type Output = Point<N, D>; type Output = Point<N, D>;
#[inline] #[inline]
@ -218,8 +220,9 @@ macro_rules! componentwise_scalarop_impl(
} }
} }
impl<N: Scalar + $bound, D: DimName> $TraitAssign<N> for Point<N, D> impl<N: Scalar + $bound, const D: usize> $TraitAssign<N> for Point<N, D>
where DefaultAllocator: Allocator<N, D> { /* where DefaultAllocator: Allocator<N, D> */
{
#[inline] #[inline]
fn $method_assign(&mut self, right: N) { fn $method_assign(&mut self, right: N) {
self.coords.$method_assign(right) self.coords.$method_assign(right)
@ -233,8 +236,9 @@ componentwise_scalarop_impl!(Div, div, ClosedDiv; DivAssign, div_assign);
macro_rules! left_scalar_mul_impl( macro_rules! left_scalar_mul_impl(
($($T: ty),* $(,)*) => {$( ($($T: ty),* $(,)*) => {$(
impl<D: DimName> Mul<Point<$T, D>> for $T impl<const D: usize> Mul<Point<$T, D>> for $T
where DefaultAllocator: Allocator<$T, D> { // where DefaultAllocator: Allocator<$T, D>
{
type Output = Point<$T, D>; type Output = Point<$T, D>;
#[inline] #[inline]
@ -243,8 +247,9 @@ macro_rules! left_scalar_mul_impl(
} }
} }
impl<'b, D: DimName> Mul<&'b Point<$T, D>> for $T impl<'b, const D: usize> Mul<&'b Point<$T, D>> for $T
where DefaultAllocator: Allocator<$T, D> { // where DefaultAllocator: Allocator<$T, D>
{
type Output = Point<$T, D>; type Output = Point<$T, D>;
#[inline] #[inline]

View File

@ -1,15 +1,13 @@
use simba::simd::SimdValue; use simba::simd::SimdValue;
use crate::base::allocator::Allocator; use crate::base::{Scalar, VectorN};
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, Scalar, VectorN};
use crate::geometry::Point; use crate::geometry::Point;
impl<N: Scalar + SimdValue, D: DimName> SimdValue for Point<N, D> impl<N: Scalar + SimdValue, const D: usize> SimdValue for Point<N, D>
where where
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
type Element = Point<N::Element, D>; type Element = Point<N::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -1367,7 +1367,7 @@ where
/// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6); /// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn to_rotation_matrix(&self) -> Rotation<N, U3> { pub fn to_rotation_matrix(&self) -> Rotation<N, 3> {
let i = self.as_ref()[0]; let i = self.as_ref()[0];
let j = self.as_ref()[1]; let j = self.as_ref()[1];
let k = self.as_ref()[2]; let k = self.as_ref()[2];

View File

@ -3,7 +3,6 @@ use num::Zero;
use simba::scalar::{RealField, SubsetOf, SupersetOf}; use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
use crate::base::dimension::U3;
use crate::base::{Matrix3, Matrix4, Scalar, Vector4}; use crate::base::{Matrix3, Matrix4, Scalar, Vector4};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf, AbstractRotation, Isometry, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf,
@ -16,11 +15,11 @@ use crate::geometry::{
* *
* Quaternion -> Quaternion * Quaternion -> Quaternion
* UnitQuaternion -> UnitQuaternion * UnitQuaternion -> UnitQuaternion
* UnitQuaternion -> Rotation<U3> * UnitQuaternion -> Rotation<3>
* UnitQuaternion -> Isometry<U3> * UnitQuaternion -> Isometry<3>
* UnitQuaternion -> UnitDualQuaternion * UnitQuaternion -> UnitDualQuaternion
* UnitQuaternion -> Similarity<U3> * UnitQuaternion -> Similarity<3>
* UnitQuaternion -> Transform<U3> * UnitQuaternion -> Transform<3>
* UnitQuaternion -> Matrix<U4> (homogeneous) * UnitQuaternion -> Matrix<U4> (homogeneous)
* *
* NOTE: * NOTE:
@ -71,7 +70,7 @@ where
} }
} }
impl<N1, N2> SubsetOf<Rotation<N2, U3>> for UnitQuaternion<N1> impl<N1, N2> SubsetOf<Rotation<N2, 3>> for UnitQuaternion<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
@ -94,24 +93,24 @@ where
} }
} }
impl<N1, N2, R> SubsetOf<Isometry<N2, U3, R>> for UnitQuaternion<N1> impl<N1, N2, R> SubsetOf<Isometry<N2, R, 3>> for UnitQuaternion<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, U3> + SupersetOf<Self>, R: AbstractRotation<N2, 3> + SupersetOf<Self>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, U3, R> { fn to_superset(&self) -> Isometry<N2, R, 3> {
Isometry::from_parts(Translation::identity(), crate::convert_ref(self)) Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
} }
#[inline] #[inline]
fn is_in_subset(iso: &Isometry<N2, U3, R>) -> bool { fn is_in_subset(iso: &Isometry<N2, R, 3>) -> bool {
iso.translation.vector.is_zero() iso.translation.vector.is_zero()
} }
#[inline] #[inline]
fn from_superset_unchecked(iso: &Isometry<N2, U3, R>) -> Self { fn from_superset_unchecked(iso: &Isometry<N2, R, 3>) -> Self {
crate::convert_ref_unchecked(&iso.rotation) crate::convert_ref_unchecked(&iso.rotation)
} }
} }
@ -138,46 +137,46 @@ where
} }
} }
impl<N1, N2, R> SubsetOf<Similarity<N2, U3, R>> for UnitQuaternion<N1> impl<N1, N2, R> SubsetOf<Similarity<N2, R, 3>> for UnitQuaternion<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, U3> + SupersetOf<Self>, R: AbstractRotation<N2, 3> + SupersetOf<Self>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, U3, R> { fn to_superset(&self) -> Similarity<N2, R, 3> {
Similarity::from_isometry(crate::convert_ref(self), N2::one()) Similarity::from_isometry(crate::convert_ref(self), N2::one())
} }
#[inline] #[inline]
fn is_in_subset(sim: &Similarity<N2, U3, R>) -> bool { fn is_in_subset(sim: &Similarity<N2, R, 3>) -> bool {
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one() sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(sim: &Similarity<N2, U3, R>) -> Self { fn from_superset_unchecked(sim: &Similarity<N2, R, 3>) -> Self {
crate::convert_ref_unchecked(&sim.isometry) crate::convert_ref_unchecked(&sim.isometry)
} }
} }
impl<N1, N2, C> SubsetOf<Transform<N2, U3, C>> for UnitQuaternion<N1> impl<N1, N2, C> SubsetOf<Transform<N2, C, 3>> for UnitQuaternion<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, U3, C> { fn to_superset(&self) -> Transform<N2, C, 3> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, U3, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, 3>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, U3, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, 3>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }

View File

@ -1,7 +1,6 @@
use crate::base::allocator::Allocator;
use crate::base::constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint};
use crate::base::{DefaultAllocator, Matrix, Scalar, Unit, Vector}; use crate::base::{Const, Matrix, Scalar, Unit, Vector};
use crate::dimension::{Dim, DimName, U1}; use crate::dimension::{Dim, U1};
use crate::storage::{Storage, StorageMut}; use crate::storage::{Storage, StorageMut};
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -13,6 +12,15 @@ pub struct Reflection<N: Scalar, D: Dim, S: Storage<N, D>> {
bias: N, bias: N,
} }
impl<N: ComplexField, S: Storage<N, Const<D>>, const D: usize> Reflection<N, Const<D>, S> {
/// Creates a new reflection wrt. the plane orthogonal to the given axis and that contains the
/// point `pt`.
pub fn new_containing_point(axis: Unit<Vector<N, Const<D>, S>>, pt: &Point<N, D>) -> Self {
let bias = axis.dotc(&pt.coords);
Self::new(axis, bias)
}
}
impl<N: ComplexField, D: Dim, S: Storage<N, D>> Reflection<N, D, S> { impl<N: ComplexField, D: Dim, S: Storage<N, D>> Reflection<N, D, S> {
/// Creates a new reflection wrt the plane orthogonal to the given axis and bias. /// Creates a new reflection wrt the plane orthogonal to the given axis and bias.
/// ///
@ -25,17 +33,6 @@ impl<N: ComplexField, D: Dim, S: Storage<N, D>> Reflection<N, D, S> {
} }
} }
/// Creates a new reflection wrt. the plane orthogonal to the given axis and that contains the
/// point `pt`.
pub fn new_containing_point(axis: Unit<Vector<N, D, S>>, pt: &Point<N, D>) -> Self
where
D: DimName,
DefaultAllocator: Allocator<N, D>,
{
let bias = axis.dotc(&pt.coords);
Self::new(axis, bias)
}
/// The reflexion axis. /// The reflexion axis.
pub fn axis(&self) -> &Vector<N, D, S> { pub fn axis(&self) -> &Vector<N, D, S> {
&self.axis &self.axis

View File

@ -18,8 +18,8 @@ use simba::scalar::RealField;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN, Scalar, Unit, VectorN}; use crate::base::{CMatrixN, CVectorN, Const, DefaultAllocator, MatrixN, Scalar, Unit};
use crate::geometry::Point; use crate::geometry::Point;
/// A rotation matrix. /// A rotation matrix.
@ -55,34 +55,33 @@ use crate::geometry::Point;
/// ///
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct Rotation<N: Scalar, D: DimName> pub struct Rotation<N: Scalar, const D: usize>
where // where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
matrix: MatrixN<N, D>, matrix: CMatrixN<N, D>,
} }
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash> hash::Hash for Rotation<N, D> impl<N: Scalar + hash::Hash, const D: usize> hash::Hash for Rotation<N, D>
where where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
<DefaultAllocator as Allocator<N, D, D>>::Buffer: hash::Hash, <DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: hash::Hash,
{ {
fn hash<H: hash::Hasher>(&self, state: &mut H) { fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.matrix.hash(state) self.matrix.hash(state)
} }
} }
impl<N: Scalar + Copy, D: DimName> Copy for Rotation<N, D> impl<N: Scalar + Copy, const D: usize> Copy for Rotation<N, D> where
where // DefaultAllocator: Allocator<N, D, D>,
DefaultAllocator: Allocator<N, D, D>, <DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Copy
<DefaultAllocator as Allocator<N, D, D>>::Buffer: Copy,
{ {
} }
impl<N: Scalar, D: DimName> Clone for Rotation<N, D> impl<N: Scalar, const D: usize> Clone for Rotation<N, D>
where where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
<DefaultAllocator as Allocator<N, D, D>>::Buffer: Clone, <DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Clone,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -91,12 +90,11 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N, D> Abomonation for Rotation<N, D> impl<N, const D: usize> Abomonation for Rotation<N, D>
where where
N: Scalar, N: Scalar,
D: DimName, CMatrixN<N, Const<D>>: Abomonation,
MatrixN<N, D>: Abomonation, // DefaultAllocator: Allocator<N, D, D>,
DefaultAllocator: Allocator<N, D, D>,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.matrix.entomb(writer) self.matrix.entomb(writer)
@ -112,9 +110,9 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: Scalar, D: DimName> Serialize for Rotation<N, D> impl<N: Scalar, const D: usize> Serialize for Rotation<N, D>
where where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
Owned<N, D, D>: Serialize, Owned<N, D, D>: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@ -126,24 +124,24 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: Scalar, D: DimName> Deserialize<'a> for Rotation<N, D> impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Rotation<N, D>
where where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
Owned<N, D, D>: Deserialize<'a>, Owned<N, D, D>: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where where
Des: Deserializer<'a>, Des: Deserializer<'a>,
{ {
let matrix = MatrixN::<N, D>::deserialize(deserializer)?; let matrix = CMatrixN::<N, D>::deserialize(deserializer)?;
Ok(Self::from_matrix_unchecked(matrix)) Ok(Self::from_matrix_unchecked(matrix))
} }
} }
impl<N: Scalar, D: DimName> Rotation<N, D> impl<N: Scalar, const D: usize> Rotation<N, D>
where // where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
/// Creates a new rotation from the given square matrix. /// Creates a new rotation from the given square matrix.
/// ///
@ -168,7 +166,7 @@ where
/// assert_eq!(*rot.matrix(), mat); /// assert_eq!(*rot.matrix(), mat);
/// ``` /// ```
#[inline] #[inline]
pub fn from_matrix_unchecked(matrix: MatrixN<N, D>) -> Self { pub fn from_matrix_unchecked(matrix: CMatrixN<N, D>) -> Self {
assert!( assert!(
matrix.is_square(), matrix.is_square(),
"Unable to create a rotation from a non-square matrix." "Unable to create a rotation from a non-square matrix."
@ -179,9 +177,9 @@ where
} }
/// # Conversion to a matrix /// # Conversion to a matrix
impl<N: Scalar, D: DimName> Rotation<N, D> impl<N: Scalar, const D: usize> Rotation<N, D>
where // where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
/// A reference to the underlying matrix representation of this rotation. /// A reference to the underlying matrix representation of this rotation.
/// ///
@ -202,14 +200,14 @@ where
/// assert_eq!(*rot.matrix(), expected); /// assert_eq!(*rot.matrix(), expected);
/// ``` /// ```
#[inline] #[inline]
pub fn matrix(&self) -> &MatrixN<N, D> { pub fn matrix(&self) -> &CMatrixN<N, D> {
&self.matrix &self.matrix
} }
/// A mutable reference to the underlying matrix representation of this rotation. /// A mutable reference to the underlying matrix representation of this rotation.
#[inline] #[inline]
#[deprecated(note = "Use `.matrix_mut_unchecked()` instead.")] #[deprecated(note = "Use `.matrix_mut_unchecked()` instead.")]
pub unsafe fn matrix_mut(&mut self) -> &mut MatrixN<N, D> { pub unsafe fn matrix_mut(&mut self) -> &mut CMatrixN<N, D> {
&mut self.matrix &mut self.matrix
} }
@ -219,7 +217,7 @@ where
/// non-square, non-inversible, or non-orthonormal. If one of those properties is broken, /// non-square, non-inversible, or non-orthonormal. If one of those properties is broken,
/// subsequent method calls may be UB. /// subsequent method calls may be UB.
#[inline] #[inline]
pub fn matrix_mut_unchecked(&mut self) -> &mut MatrixN<N, D> { pub fn matrix_mut_unchecked(&mut self) -> &mut CMatrixN<N, D> {
&mut self.matrix &mut self.matrix
} }
@ -244,7 +242,7 @@ where
/// assert_eq!(mat, expected); /// assert_eq!(mat, expected);
/// ``` /// ```
#[inline] #[inline]
pub fn into_inner(self) -> MatrixN<N, D> { pub fn into_inner(self) -> CMatrixN<N, D> {
self.matrix self.matrix
} }
@ -252,7 +250,7 @@ where
/// Deprecated: Use [Rotation::into_inner] instead. /// Deprecated: Use [Rotation::into_inner] instead.
#[deprecated(note = "use `.into_inner()` instead")] #[deprecated(note = "use `.into_inner()` instead")]
#[inline] #[inline]
pub fn unwrap(self) -> MatrixN<N, D> { pub fn unwrap(self) -> CMatrixN<N, D> {
self.matrix self.matrix
} }
@ -279,13 +277,13 @@ where
/// assert_eq!(rot.to_homogeneous(), expected); /// assert_eq!(rot.to_homogeneous(), expected);
/// ``` /// ```
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
where where
N: Zero + One, N: Zero + One,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
// We could use `MatrixN::to_homogeneous()` here, but that would imply // We could use `CMatrixN::to_homogeneous()` here, but that would imply
// adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe // adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe
// these things will get nicer once specialization lands in Rust. // these things will get nicer once specialization lands in Rust.
let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity(); let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity();
@ -296,9 +294,9 @@ where
} }
/// # Transposition and inversion /// # Transposition and inversion
impl<N: Scalar, D: DimName> Rotation<N, D> impl<N: Scalar, const D: usize> Rotation<N, D>
where // where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
/// Transposes `self`. /// Transposes `self`.
/// ///
@ -404,10 +402,10 @@ where
} }
/// # Transformation of a vector or a point /// # Transformation of a vector or a point
impl<N: SimdRealField, D: DimName> Rotation<N, D> impl<N: SimdRealField, const D: usize> Rotation<N, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
/// Rotate the given point. /// Rotate the given point.
/// ///
@ -443,7 +441,7 @@ where
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6); /// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self * v self * v
} }
@ -481,7 +479,7 @@ where
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6); /// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self.matrix().tr_mul(v) self.matrix().tr_mul(v)
} }
@ -500,16 +498,19 @@ where
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6); /// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> { pub fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>> {
Unit::new_unchecked(self.inverse_transform_vector(&**v)) Unit::new_unchecked(self.inverse_transform_vector(&**v))
} }
} }
impl<N: Scalar + Eq, D: DimName> Eq for Rotation<N, D> where DefaultAllocator: Allocator<N, D, D> {} impl<N: Scalar + Eq, const D: usize> Eq for Rotation<N, D>
// where DefaultAllocator: Allocator<N, D, D>
{
}
impl<N: Scalar + PartialEq, D: DimName> PartialEq for Rotation<N, D> impl<N: Scalar + PartialEq, const D: usize> PartialEq for Rotation<N, D>
where // where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -517,10 +518,10 @@ where
} }
} }
impl<N, D: DimName> AbsDiffEq for Rotation<N, D> impl<N, const D: usize> AbsDiffEq for Rotation<N, D>
where where
N: Scalar + AbsDiffEq, N: Scalar + AbsDiffEq,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -536,10 +537,10 @@ where
} }
} }
impl<N, D: DimName> RelativeEq for Rotation<N, D> impl<N, const D: usize> RelativeEq for Rotation<N, D>
where where
N: Scalar + RelativeEq, N: Scalar + RelativeEq,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -559,10 +560,10 @@ where
} }
} }
impl<N, D: DimName> UlpsEq for Rotation<N, D> impl<N, const D: usize> UlpsEq for Rotation<N, D>
where where
N: Scalar + UlpsEq, N: Scalar + UlpsEq,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -581,10 +582,10 @@ where
* Display * Display
* *
*/ */
impl<N, D: DimName> fmt::Display for Rotation<N, D> impl<N, const D: usize> fmt::Display for Rotation<N, D>
where where
N: RealField + fmt::Display, N: RealField + fmt::Display,
DefaultAllocator: Allocator<N, D, D> + Allocator<usize, D, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<usize, D, D>,
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);

View File

@ -1,13 +1,11 @@
use crate::base::dimension::{U2, U3};
use crate::geometry::Rotation; use crate::geometry::Rotation;
/// A 2-dimensional rotation matrix. /// A 2-dimensional rotation matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.**
pub type Rotation2<N> = Rotation<N, U2>; pub type Rotation2<N> = Rotation<N, 2>;
/// A 3-dimensional rotation matrix. /// A 3-dimensional rotation matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.**
pub type Rotation3<N> = Rotation<N, U3>; pub type Rotation3<N> = Rotation<N, 3>;

View File

@ -2,17 +2,15 @@ use num::{One, Zero};
use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf}; use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
use crate::base::allocator::Allocator; use crate::base::{MatrixN, Scalar};
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, MatrixN, Scalar};
use crate::geometry::Rotation; use crate::geometry::Rotation;
/// # Identity /// # Identity
impl<N, D: DimName> Rotation<N, D> impl<N, const D: usize> Rotation<N, D>
where where
N: Scalar + Zero + One, N: Scalar + Zero + One,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
/// Creates a new square identity rotation of the given `dimension`. /// Creates a new square identity rotation of the given `dimension`.
/// ///
@ -31,9 +29,9 @@ where
} }
} }
impl<N: Scalar, D: DimName> Rotation<N, D> impl<N: Scalar, const D: usize> Rotation<N, D>
where // where
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
/// Cast the components of `self` to another type. /// Cast the components of `self` to another type.
/// ///
@ -47,16 +45,16 @@ where
pub fn cast<To: Scalar>(self) -> Rotation<To, D> pub fn cast<To: Scalar>(self) -> Rotation<To, D>
where where
Rotation<To, D>: SupersetOf<Self>, Rotation<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D, D>, // DefaultAllocator: Allocator<To, D, D>,
{ {
crate::convert(self) crate::convert(self)
} }
} }
impl<N, D: DimName> One for Rotation<N, D> impl<N, const D: usize> One for Rotation<N, D>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, N: Scalar + Zero + One + ClosedAdd + ClosedMul,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {

View File

@ -4,8 +4,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar}; use crate::base::{Const, DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Rotation, Rotation2, Rotation3, Similarity, SuperTCategoryOf, AbstractRotation, Isometry, Rotation, Rotation2, Rotation3, Similarity, SuperTCategoryOf,
@ -27,11 +27,11 @@ use crate::geometry::{
*/ */
impl<N1, N2, D: DimName> SubsetOf<Rotation<N2, D>> for Rotation<N1, D> impl<N1, N2, const D: usize> SubsetOf<Rotation<N2, D>> for Rotation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D, D>, // DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Rotation<N2, D> { fn to_superset(&self) -> Rotation<N2, D> {
@ -120,113 +120,112 @@ where
} }
} }
impl<N1, N2, D: DimName, R> SubsetOf<Isometry<N2, D, R>> for Rotation<N1, D> impl<N1, N2, R, const D: usize> SubsetOf<Isometry<N2, R, D>> for Rotation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, D> + SupersetOf<Self>, R: AbstractRotation<N2, D> + SupersetOf<Self>,
DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, D, R> { fn to_superset(&self) -> Isometry<N2, R, D> {
Isometry::from_parts(Translation::identity(), crate::convert_ref(self)) Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
} }
#[inline] #[inline]
fn is_in_subset(iso: &Isometry<N2, D, R>) -> bool { fn is_in_subset(iso: &Isometry<N2, R, D>) -> bool {
iso.translation.vector.is_zero() iso.translation.vector.is_zero()
} }
#[inline] #[inline]
fn from_superset_unchecked(iso: &Isometry<N2, D, R>) -> Self { fn from_superset_unchecked(iso: &Isometry<N2, R, D>) -> Self {
crate::convert_ref_unchecked(&iso.rotation) crate::convert_ref_unchecked(&iso.rotation)
} }
} }
impl<N1, N2, D: DimName, R> SubsetOf<Similarity<N2, D, R>> for Rotation<N1, D> impl<N1, N2, R, const D: usize> SubsetOf<Similarity<N2, R, D>> for Rotation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, D> + SupersetOf<Self>, R: AbstractRotation<N2, D> + SupersetOf<Self>,
DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, D, R> { fn to_superset(&self) -> Similarity<N2, R, D> {
Similarity::from_parts(Translation::identity(), crate::convert_ref(self), N2::one()) Similarity::from_parts(Translation::identity(), crate::convert_ref(self), N2::one())
} }
#[inline] #[inline]
fn is_in_subset(sim: &Similarity<N2, D, R>) -> bool { fn is_in_subset(sim: &Similarity<N2, R, D>) -> bool {
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one() sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(sim: &Similarity<N2, D, R>) -> Self { fn from_superset_unchecked(sim: &Similarity<N2, R, D>) -> Self {
crate::convert_ref_unchecked(&sim.isometry.rotation) crate::convert_ref_unchecked(&sim.isometry.rotation)
} }
} }
impl<N1, N2, D, C> SubsetOf<Transform<N2, D, C>> for Rotation<N1, D> impl<N1, N2, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Rotation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal() Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
DefaultAllocator: Allocator<N1, D, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N2, D, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<(usize, usize), D>,
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // Allocator<N1, D, D>
+ Allocator<(usize, usize), D>, // + Allocator<N2, D, D>
{ {
// needed by .is_special_orthogonal() // needed by .is_special_orthogonal()
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, D, C> { fn to_superset(&self) -> Transform<N2, C, D> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, D, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }
impl<N1, N2, D> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Rotation<N1, D> impl<N1, N2, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>> for Rotation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal() Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
DefaultAllocator: Allocator<N1, D, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N2, D, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<(usize, usize), D>,
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N1, D, D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N2, D, D>
+ Allocator<(usize, usize), D>,
{ {
// needed by .is_special_orthogonal() // needed by .is_special_orthogonal()
#[inline] #[inline]
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> { fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
self.to_homogeneous().to_superset() self.to_homogeneous().to_superset()
} }
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool { fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
let rot = m.fixed_slice::<D, D>(0, 0); let rot = m.fixed_slice::<D, D>(0, 0);
let bottom = m.fixed_slice::<U1, D>(D::dim(), 0); let bottom = m.fixed_slice::<U1, D>(D, 0);
// Scalar types agree. // Scalar types agree.
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) && m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
// The block part is a rotation. // The block part is a rotation.
rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) && rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) &&
// The bottom row is (0, 0, ..., 1) // The bottom row is (0, 0, ..., 1)
bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one() bottom.iter().all(|e| e.is_zero()) && m[(D, D)] == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let r = m.fixed_slice::<D, D>(0, 0); let r = m.fixed_slice::<D, D>(0, 0);
Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned())) Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned()))
} }
@ -260,12 +259,12 @@ impl<N: RealField> From<Rotation3<N>> for Matrix3<N> {
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 2]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 2]>
for Rotation<N, D> for Rotation<N, D>
where where
N: From<[<N as SimdValue>::Element; 2]>, N: From<[<N as SimdValue>::Element; 2]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 2]) -> Self { fn from(arr: [Rotation<N::Element, D>; 2]) -> Self {
@ -276,12 +275,12 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 4]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 4]>
for Rotation<N, D> for Rotation<N, D>
where where
N: From<[<N as SimdValue>::Element; 4]>, N: From<[<N as SimdValue>::Element; 4]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 4]) -> Self { fn from(arr: [Rotation<N::Element, D>; 4]) -> Self {
@ -294,12 +293,12 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 8]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 8]>
for Rotation<N, D> for Rotation<N, D>
where where
N: From<[<N as SimdValue>::Element; 8]>, N: From<[<N as SimdValue>::Element; 8]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 8]) -> Self { fn from(arr: [Rotation<N::Element, D>; 8]) -> Self {
@ -316,12 +315,12 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 16]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 16]>
for Rotation<N, D> for Rotation<N, D>
where where
N: From<[<N as SimdValue>::Element; 16]>, N: From<[<N as SimdValue>::Element; 16]>,
N::Element: Scalar + Copy, N::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 16]) -> Self { fn from(arr: [Rotation<N::Element, D>; 16]) -> Self {

View File

@ -1,17 +1,14 @@
use simba::simd::SimdValue; use simba::simd::SimdValue;
use crate::base::allocator::Allocator; use crate::base::{MatrixN, Scalar};
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, MatrixN, Scalar};
use crate::geometry::Rotation; use crate::geometry::Rotation;
impl<N, D> SimdValue for Rotation<N, D> impl<N, const D: usize> SimdValue for Rotation<N, D>
where where
N: Scalar + SimdValue, N: Scalar + SimdValue,
D: DimName,
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>, // DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
{ {
type Element = Rotation<N::Element, D>; type Element = Rotation<N::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -16,9 +16,9 @@ use simba::scalar::{RealField, SubsetOf};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::storage::Owned; use crate::base::storage::Owned;
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar};
use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation. /// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
@ -39,20 +39,20 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Deserialize<'de>")) Owned<N, D>: Deserialize<'de>"))
)] )]
pub struct Similarity<N: Scalar, D: DimName, R> pub struct Similarity<N: Scalar, R, const D: usize>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// The part of this similarity that does not include the scaling factor. /// The part of this similarity that does not include the scaling factor.
pub isometry: Isometry<N, D, R>, pub isometry: Isometry<N, R, D>,
scaling: N, scaling: N,
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N: Scalar, D: DimName, R> Abomonation for Similarity<N, D, R> impl<N: Scalar, R, const D: usize> Abomonation for Similarity<N, R, D>
where where
Isometry<N, D, R>: Abomonation, Isometry<N, R, D>: Abomonation,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.isometry.entomb(writer) self.isometry.entomb(writer)
@ -67,11 +67,10 @@ where
} }
} }
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Similarity<N, R, D>
for Similarity<N, D, R>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: hash::Hash, Owned<N, Const<D>>: hash::Hash,
{ {
fn hash<H: hash::Hasher>(&self, state: &mut H) { fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.isometry.hash(state); self.isometry.hash(state);
@ -79,17 +78,18 @@ where
} }
} }
impl<N: Scalar + Copy + Zero, D: DimName + Copy, R: AbstractRotation<N, D> + Copy> Copy impl<N: Scalar + Copy + Zero, R: AbstractRotation<N, D> + Copy, const D: usize> Copy
for Similarity<N, D, R> for Similarity<N, R, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Copy, Owned<N, Const<D>>: Copy,
{ {
} }
impl<N: Scalar + Zero, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Similarity<N, D, R> impl<N: Scalar + Zero, R: AbstractRotation<N, D> + Clone, const D: usize> Clone
where for Similarity<N, R, D>
DefaultAllocator: Allocator<N, D>, // where
// DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -97,10 +97,10 @@ where
} }
} }
impl<N: Scalar + Zero, D: DimName, R> Similarity<N, D, R> impl<N: Scalar + Zero, R, const D: usize> Similarity<N, R, D>
where where
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new similarity from its rotational and translational parts. /// Creates a new similarity from its rotational and translational parts.
#[inline] #[inline]
@ -110,7 +110,7 @@ where
/// Creates a new similarity from its rotational and translational parts. /// Creates a new similarity from its rotational and translational parts.
#[inline] #[inline]
pub fn from_isometry(isometry: Isometry<N, D, R>, scaling: N) -> Self { pub fn from_isometry(isometry: Isometry<N, R, D>, scaling: N) -> Self {
assert!(!scaling.is_zero(), "The scaling factor must not be zero."); assert!(!scaling.is_zero(), "The scaling factor must not be zero.");
Self { isometry, scaling } Self { isometry, scaling }
@ -128,9 +128,9 @@ where
} }
} }
impl<N: Scalar, D: DimName, R> Similarity<N, D, R> impl<N: Scalar, R, const D: usize> Similarity<N, R, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// The scaling factor of this similarity transformation. /// The scaling factor of this similarity transformation.
#[inline] #[inline]
@ -139,11 +139,11 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new similarity that applies only a scaling factor. /// Creates a new similarity that applies only a scaling factor.
#[inline] #[inline]
@ -282,7 +282,7 @@ where
/// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5); /// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5);
/// ``` /// ```
#[inline] #[inline]
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self * v self * v
} }
@ -322,7 +322,7 @@ where
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.5, 2.0), epsilon = 1.0e-5); /// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.5, 2.0), epsilon = 1.0e-5);
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self.isometry.inverse_transform_vector(v) / self.scaling() self.isometry.inverse_transform_vector(v) / self.scaling()
} }
} }
@ -331,17 +331,17 @@ where
// and makes it harder to use it, e.g., for Transform × Isometry implementation. // and makes it harder to use it, e.g., for Transform × Isometry implementation.
// This is OK since all constructors of the isometry enforce the Rotation bound already (and // This is OK since all constructors of the isometry enforce the Rotation bound already (and
// explicit struct construction is prevented by the private scaling factor). // explicit struct construction is prevented by the private scaling factor).
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Converts this similarity into its equivalent homogeneous transformation matrix. /// Converts this similarity into its equivalent homogeneous transformation matrix.
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
let mut res = self.isometry.to_homogeneous(); let mut res = self.isometry.to_homogeneous();
@ -353,17 +353,15 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R> Eq for Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> Eq for Similarity<N, R, D> where
where R: AbstractRotation<N, D> + Eq // DefaultAllocator: Allocator<N, D>,
R: AbstractRotation<N, D> + Eq,
DefaultAllocator: Allocator<N, D>,
{ {
} }
impl<N: SimdRealField, D: DimName, R> PartialEq for Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> PartialEq for Similarity<N, R, D>
where where
R: AbstractRotation<N, D> + PartialEq, R: AbstractRotation<N, D> + PartialEq,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -371,10 +369,10 @@ where
} }
} }
impl<N: RealField, D: DimName, R> AbsDiffEq for Similarity<N, D, R> impl<N: RealField, R, const D: usize> AbsDiffEq for Similarity<N, R, D>
where where
R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>, R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -391,10 +389,10 @@ where
} }
} }
impl<N: RealField, D: DimName, R> RelativeEq for Similarity<N, D, R> impl<N: RealField, R, const D: usize> RelativeEq for Similarity<N, R, D>
where where
R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>, R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -417,10 +415,9 @@ where
} }
} }
impl<N: RealField, D: DimName, R> UlpsEq for Similarity<N, D, R> impl<N: RealField, R, const D: usize> UlpsEq for Similarity<N, R, D>
where where
R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>, R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -440,11 +437,11 @@ where
* Display * Display
* *
*/ */
impl<N, D: DimName, R> fmt::Display for Similarity<N, D, R> impl<N, R, const D: usize> fmt::Display for Similarity<N, R, D>
where where
N: RealField + fmt::Display, N: RealField + fmt::Display,
R: AbstractRotation<N, D> + fmt::Display, R: AbstractRotation<N, D> + fmt::Display,
DefaultAllocator: Allocator<N, D> + Allocator<usize, D>, // DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);

View File

@ -1,15 +1,13 @@
use crate::base::dimension::{U2, U3};
use crate::geometry::{Rotation2, Rotation3, Similarity, UnitComplex, UnitQuaternion}; use crate::geometry::{Rotation2, Rotation3, Similarity, UnitComplex, UnitQuaternion};
/// A 2-dimensional similarity. /// A 2-dimensional similarity.
pub type Similarity2<N> = Similarity<N, U2, UnitComplex<N>>; pub type Similarity2<N> = Similarity<N, UnitComplex<N>, 2>;
/// A 3-dimensional similarity. /// A 3-dimensional similarity.
pub type Similarity3<N> = Similarity<N, U3, UnitQuaternion<N>>; pub type Similarity3<N> = Similarity<N, UnitQuaternion<N>, 3>;
/// A 2-dimensional similarity using a rotation matrix for its rotation part. /// A 2-dimensional similarity using a rotation matrix for its rotation part.
pub type SimilarityMatrix2<N> = Similarity<N, U2, Rotation2<N>>; pub type SimilarityMatrix2<N> = Similarity<N, Rotation2<N>, 2>;
/// A 3-dimensional similarity using a rotation matrix for its rotation part. /// A 3-dimensional similarity using a rotation matrix for its rotation part.
pub type SimilarityMatrix3<N> = Similarity<N, U3, Rotation3<N>>; pub type SimilarityMatrix3<N> = Similarity<N, Rotation3<N>, 3>;

View File

@ -13,20 +13,18 @@ use rand::{
use simba::scalar::SupersetOf; use simba::scalar::SupersetOf;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::{Vector2, Vector3};
use crate::base::dimension::{DimName, U2, U3};
use crate::base::{DefaultAllocator, Vector2, Vector3};
use crate::{ use crate::{
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity, AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity,
Translation, UnitComplex, UnitQuaternion, Translation, UnitComplex, UnitQuaternion,
}; };
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new identity similarity. /// Creates a new identity similarity.
/// ///
@ -49,11 +47,11 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R> One for Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> One for Similarity<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new identity similarity. /// Creates a new identity similarity.
#[inline] #[inline]
@ -63,15 +61,15 @@ where
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: crate::RealField, D: DimName, R> Distribution<Similarity<N, D, R>> for Standard impl<N: crate::RealField, R, const D: usize> Distribution<Similarity<N, R, D>> for Standard
where where
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N> + Distribution<R>, Standard: Distribution<N> + Distribution<R>,
{ {
/// Generate an arbitrary random variate for testing purposes. /// Generate an arbitrary random variate for testing purposes.
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Similarity<N, D, R> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Similarity<N, R, D> {
let mut s = rng.gen(); let mut s = rng.gen();
while relative_eq!(s, N::zero()) { while relative_eq!(s, N::zero()) {
s = rng.gen() s = rng.gen()
@ -81,11 +79,11 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// The similarity that applies the scaling factor `scaling`, followed by the rotation `r` with /// The similarity that applies the scaling factor `scaling`, followed by the rotation `r` with
/// its axis passing through the point `p`. /// its axis passing through the point `p`.
@ -110,12 +108,12 @@ where
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N, D: DimName, R> Arbitrary for Similarity<N, D, R> impl<N, R, const D: usize> Arbitrary for Similarity<N, R, D>
where where
N: crate::RealField + Arbitrary + Send, N: crate::RealField + Arbitrary + Send,
N::Element: crate::RealField, N::Element: crate::RealField,
R: AbstractRotation<N, D> + Arbitrary + Send, R: AbstractRotation<N, D> + Arbitrary + Send,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Send, Owned<N, D>: Send,
{ {
#[inline] #[inline]
@ -136,7 +134,7 @@ where
*/ */
// 2D similarity. // 2D similarity.
impl<N: SimdRealField> Similarity<N, U2, Rotation2<N>> impl<N: SimdRealField> Similarity<N, Rotation2<N>, 2>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
@ -170,15 +168,15 @@ where
/// let sim2 = sim.cast::<f32>(); /// let sim2 = sim.cast::<f32>();
/// assert_eq!(sim2, SimilarityMatrix2::<f32>::identity()); /// assert_eq!(sim2, SimilarityMatrix2::<f32>::identity());
/// ``` /// ```
pub fn cast<To: Scalar>(self) -> Similarity<To, U2, Rotation2<To>> pub fn cast<To: Scalar>(self) -> Similarity<To, Rotation2<To>, 2>
where where
Similarity<To, U2, Rotation2<To>>: SupersetOf<Self>, Similarity<To, Rotation2<To>, 2>: SupersetOf<Self>,
{ {
crate::convert(self) crate::convert(self)
} }
} }
impl<N: SimdRealField> Similarity<N, U2, UnitComplex<N>> impl<N: SimdRealField> Similarity<N, UnitComplex<N>, 2>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
@ -212,9 +210,9 @@ where
/// let sim2 = sim.cast::<f32>(); /// let sim2 = sim.cast::<f32>();
/// assert_eq!(sim2, Similarity2::<f32>::identity()); /// assert_eq!(sim2, Similarity2::<f32>::identity());
/// ``` /// ```
pub fn cast<To: Scalar>(self) -> Similarity<To, U2, UnitComplex<To>> pub fn cast<To: Scalar>(self) -> Similarity<To, UnitComplex<To>, 2>
where where
Similarity<To, U2, UnitComplex<To>>: SupersetOf<Self>, Similarity<To, UnitComplex<To>, 2>: SupersetOf<Self>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -223,7 +221,7 @@ where
// 3D rotation. // 3D rotation.
macro_rules! similarity_construction_impl( macro_rules! similarity_construction_impl(
($Rot: ident) => { ($Rot: ident) => {
impl<N: SimdRealField> Similarity<N, U3, $Rot<N>> impl<N: SimdRealField> Similarity<N, $Rot<N>, 3>
where N::Element: SimdRealField { where N::Element: SimdRealField {
/// Creates a new similarity from a translation, rotation axis-angle, and scaling /// Creates a new similarity from a translation, rotation axis-angle, and scaling
/// factor. /// factor.
@ -253,7 +251,7 @@ macro_rules! similarity_construction_impl(
#[inline] #[inline]
pub fn new(translation: Vector3<N>, axisangle: Vector3<N>, scaling: N) -> Self pub fn new(translation: Vector3<N>, axisangle: Vector3<N>, scaling: N) -> Self
{ {
Self::from_isometry(Isometry::<_, U3, $Rot<N>>::new(translation, axisangle), scaling) Self::from_isometry(Isometry::<_, $Rot<N>, 3>::new(translation, axisangle), scaling)
} }
/// Cast the components of `self` to another type. /// Cast the components of `self` to another type.
@ -265,9 +263,9 @@ macro_rules! similarity_construction_impl(
/// let sim2 = sim.cast::<f32>(); /// let sim2 = sim.cast::<f32>();
/// assert_eq!(sim2, Similarity3::<f32>::identity()); /// assert_eq!(sim2, Similarity3::<f32>::identity());
/// ``` /// ```
pub fn cast<To: Scalar>(self) -> Similarity<To, U3, $Rot<To>> pub fn cast<To: Scalar>(self) -> Similarity<To, $Rot<To>, 3>
where where
Similarity<To, U3, $Rot<To>>: SupersetOf<Self>, Similarity<To, $Rot<To>, 3>: SupersetOf<Self>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -310,7 +308,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>, up: &Vector3<N>,
scaling: N) scaling: N)
-> Self { -> Self {
Self::from_isometry(Isometry::<_, U3, $Rot<N>>::face_towards(eye, target, up), scaling) Self::from_isometry(Isometry::<_, $Rot<N>, 3>::face_towards(eye, target, up), scaling)
} }
/// Deprecated: Use [SimilarityMatrix3::face_towards] instead. /// Deprecated: Use [SimilarityMatrix3::face_towards] instead.
@ -358,7 +356,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>, up: &Vector3<N>,
scaling: N) scaling: N)
-> Self { -> Self {
Self::from_isometry(Isometry::<_, U3, $Rot<N>>::look_at_rh(eye, target, up), scaling) Self::from_isometry(Isometry::<_, $Rot<N>, 3>::look_at_rh(eye, target, up), scaling)
} }
/// Builds a left-handed look-at view matrix including a scaling factor. /// Builds a left-handed look-at view matrix including a scaling factor.
@ -396,7 +394,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>, up: &Vector3<N>,
scaling: N) scaling: N)
-> Self { -> Self {
Self::from_isometry(Isometry::<_, _, $Rot<N>>::look_at_lh(eye, target, up), scaling) Self::from_isometry(Isometry::<_, $Rot<N>, _>::look_at_lh(eye, target, up), scaling)
} }
} }
} }

View File

@ -4,8 +4,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN, Scalar}; use crate::base::{Const, DefaultAllocator, MatrixN, Scalar};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
@ -20,27 +20,27 @@ use crate::geometry::{
* Similarity -> Matrix (homogeneous) * Similarity -> Matrix (homogeneous)
*/ */
impl<N1, N2, D: DimName, R1, R2> SubsetOf<Similarity<N2, D, R2>> for Similarity<N1, D, R1> impl<N1, N2, R1, R2, const D: usize> SubsetOf<Similarity<N2, R2, D>> for Similarity<N1, R1, D>
where where
N1: RealField + SubsetOf<N2>, N1: RealField + SubsetOf<N2>,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R1: AbstractRotation<N1, D> + SubsetOf<R2>, R1: AbstractRotation<N1, D> + SubsetOf<R2>,
R2: AbstractRotation<N2, D>, R2: AbstractRotation<N2, D>,
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, D, R2> { fn to_superset(&self) -> Similarity<N2, R2, D> {
Similarity::from_isometry(self.isometry.to_superset(), self.scaling().to_superset()) Similarity::from_isometry(self.isometry.to_superset(), self.scaling().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(sim: &Similarity<N2, D, R2>) -> bool { fn is_in_subset(sim: &Similarity<N2, R2, D>) -> bool {
crate::is_convertible::<_, Isometry<N1, D, R1>>(&sim.isometry) crate::is_convertible::<_, Isometry<N1, R1, D>>(&sim.isometry)
&& crate::is_convertible::<_, N1>(&sim.scaling()) && crate::is_convertible::<_, N1>(&sim.scaling())
} }
#[inline] #[inline]
fn from_superset_unchecked(sim: &Similarity<N2, D, R2>) -> Self { fn from_superset_unchecked(sim: &Similarity<N2, R2, D>) -> Self {
Similarity::from_isometry( Similarity::from_isometry(
sim.isometry.to_subset_unchecked(), sim.isometry.to_subset_unchecked(),
sim.scaling().to_subset_unchecked(), sim.scaling().to_subset_unchecked(),
@ -48,64 +48,64 @@ where
} }
} }
impl<N1, N2, D, R, C> SubsetOf<Transform<N2, D, C>> for Similarity<N1, D, R> impl<N1, N2, R, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Similarity<N1, R, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
R: AbstractRotation<N1, D> R: AbstractRotation<N1, D>
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>> + SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>, + SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .determinant() Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .determinant()
DefaultAllocator: Allocator<N1, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, D, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<(usize, usize), D>
+ Allocator<(usize, usize), D> // + Allocator<N1, D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N1, D, D>
+ Allocator<N2, D, D> // + Allocator<N2, D, D>
+ Allocator<N2, D>, // + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, D, C> { fn to_superset(&self) -> Transform<N2, C, D> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, D, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }
impl<N1, N2, D, R> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Similarity<N1, D, R> impl<N1, N2, R, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>
for Similarity<N1, R, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N1, D> R: AbstractRotation<N1, D>
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>> + SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>, + SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .determinant() Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .determinant()
DefaultAllocator: Allocator<N1, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, D, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<(usize, usize), D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N1, D>
+ Allocator<(usize, usize), D> // + Allocator<N1, D, D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N2, D, D>
+ Allocator<N2, D, D> // + Allocator<N2, D>
+ Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> { fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
self.to_homogeneous().to_superset() self.to_homogeneous().to_superset()
} }
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool { fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
let mut rot = m.fixed_slice::<D, D>(0, 0).clone_owned(); let mut rot = m.fixed_slice::<D, D>(0, 0).clone_owned();
if rot if rot
.fixed_columns_mut::<U1>(0) .fixed_columns_mut::<U1>(0)
@ -128,20 +128,20 @@ where
rot.fixed_columns_mut::<U1>(2).neg_mut(); rot.fixed_columns_mut::<U1>(2).neg_mut();
} }
let bottom = m.fixed_slice::<U1, D>(D::dim(), 0); let bottom = m.fixed_slice::<U1, D>(D, 0);
// Scalar types agree. // Scalar types agree.
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) && m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
// The normalized block part is a rotation. // The normalized block part is a rotation.
// rot.is_special_orthogonal(N2::default_epsilon().sqrt()) && // rot.is_special_orthogonal(N2::default_epsilon().sqrt()) &&
// The bottom row is (0, 0, ..., 1) // The bottom row is (0, 0, ..., 1)
bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one() bottom.iter().all(|e| e.is_zero()) && m[(D, D)] == N2::one()
} else { } else {
false false
} }
} }
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let mut mm = m.clone_owned(); let mut mm = m.clone_owned();
let na = mm.fixed_slice_mut::<D, U1>(0, 0).normalize_mut(); let na = mm.fixed_slice_mut::<D, U1>(0, 0).normalize_mut();
let nb = mm.fixed_slice_mut::<D, U1>(0, 1).normalize_mut(); let nb = mm.fixed_slice_mut::<D, U1>(0, 1).normalize_mut();
@ -158,7 +158,7 @@ where
scale = -scale; scale = -scale;
} }
let t = m.fixed_slice::<D, U1>(0, D::dim()).into_owned(); let t = m.fixed_slice::<D, U1>(0, D).into_owned();
let t = Translation { let t = Translation {
vector: crate::convert_unchecked(t), vector: crate::convert_unchecked(t),
}; };
@ -171,30 +171,31 @@ where
} }
} }
impl<N: SimdRealField, D: DimName, R> From<Similarity<N, D, R>> for MatrixN<N, DimNameSum<D, U1>> impl<N: SimdRealField, R, const D: usize> From<Similarity<N, R, D>>
for MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<N, D>
{ {
#[inline] #[inline]
fn from(sim: Similarity<N, D, R>) -> Self { fn from(sim: Similarity<N, R, D>) -> Self {
sim.to_homogeneous() sim.to_homogeneous()
} }
} }
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R> impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
From<[Similarity<N::Element, D, R::Element>; 2]> for Similarity<N, D, R> From<[Similarity<N::Element, R::Element, D>; 2]> for Similarity<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 2]>, N: From<[<N as SimdValue>::Element; 2]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy, N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy, R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 2]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 2]) -> Self {
let iso = Isometry::from([arr[0].isometry.clone(), arr[1].isometry.clone()]); let iso = Isometry::from([arr[0].isometry.clone(), arr[1].isometry.clone()]);
let scale = N::from([arr[0].scaling(), arr[1].scaling()]); let scale = N::from([arr[0].scaling(), arr[1].scaling()]);
@ -202,18 +203,18 @@ where
} }
} }
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R> impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
From<[Similarity<N::Element, D, R::Element>; 4]> for Similarity<N, D, R> From<[Similarity<N::Element, R::Element, D>; 4]> for Similarity<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 4]>, N: From<[<N as SimdValue>::Element; 4]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy, N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy, R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 4]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 4]) -> Self {
let iso = Isometry::from([ let iso = Isometry::from([
arr[0].isometry.clone(), arr[0].isometry.clone(),
arr[1].isometry.clone(), arr[1].isometry.clone(),
@ -231,18 +232,18 @@ where
} }
} }
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R> impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
From<[Similarity<N::Element, D, R::Element>; 8]> for Similarity<N, D, R> From<[Similarity<N::Element, R::Element, D>; 8]> for Similarity<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 8]>, N: From<[<N as SimdValue>::Element; 8]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy, N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy, R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 8]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 8]) -> Self {
let iso = Isometry::from([ let iso = Isometry::from([
arr[0].isometry.clone(), arr[0].isometry.clone(),
arr[1].isometry.clone(), arr[1].isometry.clone(),
@ -268,18 +269,18 @@ where
} }
} }
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R> impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
From<[Similarity<N::Element, D, R::Element>; 16]> for Similarity<N, D, R> From<[Similarity<N::Element, R::Element, D>; 16]> for Similarity<N, R, D>
where where
N: From<[<N as SimdValue>::Element; 16]>, N: From<[<N as SimdValue>::Element; 16]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>, R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy, N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy, R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 16]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 16]) -> Self {
let iso = Isometry::from([ let iso = Isometry::from([
arr[0].isometry.clone(), arr[0].isometry.clone(),
arr[1].isometry.clone(), arr[1].isometry.clone(),

View File

@ -144,7 +144,7 @@ macro_rules! similarity_binop_assign_impl_all(
// Similarity ÷ Similarity // Similarity ÷ Similarity
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>; self: Similarity<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -157,7 +157,7 @@ similarity_binop_impl_all!(
similarity_binop_impl_all!( similarity_binop_impl_all!(
Div, div; Div, div;
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>; self: Similarity<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
@ -167,7 +167,7 @@ similarity_binop_impl_all!(
// Similarity ×= Translation // Similarity ×= Translation
similarity_binop_assign_impl_all!( similarity_binop_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
self: Similarity<N, D, R>, rhs: Translation<N, D>; self: Similarity<N, R, D>, rhs: Translation<N, D>;
[val] => *self *= &rhs; [val] => *self *= &rhs;
[ref] => { [ref] => {
let shift = self.isometry.rotation.transform_vector(&rhs.vector) * self.scaling(); let shift = self.isometry.rotation.transform_vector(&rhs.vector) * self.scaling();
@ -179,7 +179,7 @@ similarity_binop_assign_impl_all!(
// Similarity ÷= Similarity // Similarity ÷= Similarity
similarity_binop_assign_impl_all!( similarity_binop_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>; self: Similarity<N, R, D>, rhs: Similarity<N, R, D>;
[val] => *self *= &rhs; [val] => *self *= &rhs;
[ref] => { [ref] => {
*self *= &rhs.isometry; *self *= &rhs.isometry;
@ -189,7 +189,7 @@ similarity_binop_assign_impl_all!(
similarity_binop_assign_impl_all!( similarity_binop_assign_impl_all!(
DivAssign, div_assign; DivAssign, div_assign;
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>; self: Similarity<N, R, D>, rhs: Similarity<N, R, D>;
[val] => *self /= &rhs; [val] => *self /= &rhs;
// TODO: don't invert explicitly. // TODO: don't invert explicitly.
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
@ -199,7 +199,7 @@ similarity_binop_assign_impl_all!(
// Similarity ÷= Isometry // Similarity ÷= Isometry
similarity_binop_assign_impl_all!( similarity_binop_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>; self: Similarity<N, R, D>, rhs: Isometry<N, R, D>;
[val] => *self *= &rhs; [val] => *self *= &rhs;
[ref] => { [ref] => {
let shift = self.isometry.rotation.transform_vector(&rhs.translation.vector) * self.scaling(); let shift = self.isometry.rotation.transform_vector(&rhs.translation.vector) * self.scaling();
@ -210,7 +210,7 @@ similarity_binop_assign_impl_all!(
similarity_binop_assign_impl_all!( similarity_binop_assign_impl_all!(
DivAssign, div_assign; DivAssign, div_assign;
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>; self: Similarity<N, R, D>, rhs: Isometry<N, R, D>;
[val] => *self /= &rhs; [val] => *self /= &rhs;
// TODO: don't invert explicitly. // TODO: don't invert explicitly.
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
@ -238,7 +238,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
MulAssign, mul_assign where N: SimdRealField for N::Element: SimdRealField; MulAssign, mul_assign where N: SimdRealField for N::Element: SimdRealField;
(U3, U3), (U3, U3) for; (U3, U3), (U3, U3) for;
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>; self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>;
[val] => self.isometry.rotation *= rhs; [val] => self.isometry.rotation *= rhs;
[ref] => self.isometry.rotation *= *rhs; [ref] => self.isometry.rotation *= *rhs;
); );
@ -246,7 +246,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
DivAssign, div_assign where N: SimdRealField for N::Element: SimdRealField; DivAssign, div_assign where N: SimdRealField for N::Element: SimdRealField;
(U3, U3), (U3, U3) for; (U3, U3), (U3, U3) for;
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>; self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>;
// TODO: don't invert explicitly? // TODO: don't invert explicitly?
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
@ -273,7 +273,7 @@ md_assign_impl_all!(
// Similarity ÷ Isometry // Similarity ÷ Isometry
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>, Output = Similarity<N, D, R>; self: Similarity<N, R, D>, rhs: Isometry<N, R, D>, Output = Similarity<N, R, D>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -289,7 +289,7 @@ similarity_binop_impl_all!(
similarity_binop_impl_all!( similarity_binop_impl_all!(
Div, div; Div, div;
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>, Output = Similarity<N, D, R>; self: Similarity<N, R, D>, rhs: Isometry<N, R, D>, Output = Similarity<N, R, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
@ -300,7 +300,7 @@ similarity_binop_impl_all!(
// Isometry ÷ Similarity // Isometry ÷ Similarity
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Isometry<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>; self: Isometry<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
[val val] => { [val val] => {
let scaling = rhs.scaling(); let scaling = rhs.scaling();
Similarity::from_isometry(self * rhs.isometry, scaling) Similarity::from_isometry(self * rhs.isometry, scaling)
@ -321,7 +321,7 @@ similarity_binop_impl_all!(
similarity_binop_impl_all!( similarity_binop_impl_all!(
Div, div; Div, div;
self: Isometry<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>; self: Isometry<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
@ -331,7 +331,7 @@ similarity_binop_impl_all!(
// Similarity × Point // Similarity × Point
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Similarity<N, D, R>, right: Point<N, D>, Output = Point<N, D>; self: Similarity<N, R, D>, right: Point<N, D>, Output = Point<N, D>;
[val val] => { [val val] => {
let scaling = self.scaling(); let scaling = self.scaling();
self.isometry.translation * (self.isometry.rotation.transform_point(&right) * scaling) self.isometry.translation * (self.isometry.rotation.transform_point(&right) * scaling)
@ -347,7 +347,7 @@ similarity_binop_impl_all!(
// Similarity × Vector // Similarity × Vector
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Similarity<N, D, R>, right: VectorN<N, D>, Output = VectorN<N, D>; self: Similarity<N, R, D>, right: VectorN<N, D>, Output = VectorN<N, D>;
[val val] => self.isometry.rotation.transform_vector(&right) * self.scaling(); [val val] => self.isometry.rotation.transform_vector(&right) * self.scaling();
[ref val] => self.isometry.rotation.transform_vector(&right) * self.scaling(); [ref val] => self.isometry.rotation.transform_vector(&right) * self.scaling();
[val ref] => self.isometry.rotation.transform_vector(right) * self.scaling(); [val ref] => self.isometry.rotation.transform_vector(right) * self.scaling();
@ -357,7 +357,7 @@ similarity_binop_impl_all!(
// Similarity × Translation // Similarity × Translation
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Similarity<N, D, R>, right: Translation<N, D>, Output = Similarity<N, D, R>; self: Similarity<N, R, D>, right: Translation<N, D>, Output = Similarity<N, R, D>;
[val val] => &self * &right; [val val] => &self * &right;
[ref val] => self * &right; [ref val] => self * &right;
[val ref] => &self * right; [val ref] => &self * right;
@ -374,7 +374,7 @@ similarity_binop_impl_all!(
// Translation × Similarity // Translation × Similarity
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Translation<N, D>, right: Similarity<N, D, R>, Output = Similarity<N, D, R>; self: Translation<N, D>, right: Similarity<N, R, D>, Output = Similarity<N, R, D>;
[val val] => { [val val] => {
let scaling = right.scaling(); let scaling = right.scaling();
Similarity::from_isometry(self * right.isometry, scaling) Similarity::from_isometry(self * right.isometry, scaling)
@ -506,8 +506,8 @@ similarity_from_composition_impl_all!(
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); (U4, U1), (U3, U1);
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>, self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
Output = Similarity<N, U3, UnitQuaternion<N>>; Output = Similarity<N, UnitQuaternion<N>, 3>;
[val val] => { [val val] => {
let scaling = self.scaling(); let scaling = self.scaling();
Similarity::from_isometry(self.isometry * rhs, scaling) Similarity::from_isometry(self.isometry * rhs, scaling)
@ -524,8 +524,8 @@ similarity_from_composition_impl_all!(
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); (U4, U1), (U3, U1);
self: UnitQuaternion<N>, right: Similarity<N, U3, UnitQuaternion<N>>, self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>,
Output = Similarity<N, U3, UnitQuaternion<N>>; Output = Similarity<N, UnitQuaternion<N>, 3>;
[val val] => &self * &right; [val val] => &self * &right;
[ref val] => self * &right; [ref val] => self * &right;
[val ref] => &self * right; [val ref] => &self * right;
@ -536,8 +536,8 @@ similarity_from_composition_impl_all!(
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(U4, U1), (U3, U1); (U4, U1), (U3, U1);
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>, self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
Output = Similarity<N, U3, UnitQuaternion<N>>; Output = Similarity<N, UnitQuaternion<N>, 3>;
[val val] => { [val val] => {
let scaling = self.scaling(); let scaling = self.scaling();
Similarity::from_isometry(self.isometry / rhs, scaling) Similarity::from_isometry(self.isometry / rhs, scaling)
@ -554,8 +554,8 @@ similarity_from_composition_impl_all!(
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(U4, U1), (U3, U1); (U4, U1), (U3, U1);
self: UnitQuaternion<N>, right: Similarity<N, U3, UnitQuaternion<N>>, self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>,
Output = Similarity<N, U3, UnitQuaternion<N>>; Output = Similarity<N, UnitQuaternion<N>, 3>;
// TODO: don't call inverse explicitly? // TODO: don't call inverse explicitly?
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };

View File

@ -1,19 +1,15 @@
use simba::simd::{SimdRealField, SimdValue}; use simba::simd::{SimdRealField, SimdValue};
use crate::base::allocator::Allocator;
use crate::base::dimension::DimName;
use crate::base::DefaultAllocator;
use crate::geometry::{AbstractRotation, Isometry, Similarity}; use crate::geometry::{AbstractRotation, Isometry, Similarity};
impl<N: SimdRealField, D: DimName, R> SimdValue for Similarity<N, D, R> impl<N: SimdRealField, R, const D: usize> SimdValue for Similarity<N, R, D>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>, R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>,
R::Element: AbstractRotation<N::Element, D>, R::Element: AbstractRotation<N::Element, D>,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
type Element = Similarity<N::Element, D, R::Element>; type Element = Similarity<N::Element, R::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;
#[inline] #[inline]

View File

@ -1,5 +1,4 @@
use crate::base::allocator::Allocator; use crate::base::{Const, Scalar, ToTypenum};
use crate::base::{DefaultAllocator, DimName, Scalar, ToTypenum};
use crate::geometry::{Point, Point2, Point3}; use crate::geometry::{Point, Point2, Point3};
use typenum::{self, Cmp, Greater}; use typenum::{self, Cmp, Greater};
@ -10,7 +9,7 @@ macro_rules! impl_swizzle {
/// Builds a new point from components of `self`. /// Builds a new point from components of `self`.
#[inline] #[inline]
pub fn $name(&self) -> $Result<N> pub fn $name(&self) -> $Result<N>
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> { where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
$Result::new($(self[$i].inlined_clone()),*) $Result::new($(self[$i].inlined_clone()),*)
} }
)* )*
@ -19,10 +18,10 @@ macro_rules! impl_swizzle {
} }
/// # Swizzling /// # Swizzling
impl<N: Scalar, D> Point<N, D> impl<N: Scalar, const D: usize> Point<N, D>
where where
D: DimName + ToTypenum, Const<D>: ToTypenum,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
impl_swizzle!( impl_swizzle!(
where U0: xx() -> Point2[0, 0], where U0: xx() -> Point2[0, 0],

View File

@ -9,9 +9,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use simba::scalar::RealField; use simba::scalar::RealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::storage::Owned; use crate::base::storage::Owned;
use crate::base::{DefaultAllocator, MatrixN, VectorN}; use crate::base::{CMatrixN, CVectorN, Const, DefaultAllocator, MatrixN};
use crate::geometry::Point; use crate::geometry::Point;
@ -28,10 +28,10 @@ pub trait TCategory: Any + Debug + Copy + PartialEq + Send {
/// Checks that the given matrix is a valid homogeneous representation of an element of the /// Checks that the given matrix is a valid homogeneous representation of an element of the
/// category `Self`. /// category `Self`.
fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, const D: usize>(mat: &CMatrixN<N, D>) -> bool
where where
N::Epsilon: Copy, N::Epsilon: Copy;
DefaultAllocator: Allocator<N, D, D>; // DefaultAllocator: Allocator<N, D, D>;
} }
/// Traits that gives the `Transform` category that is compatible with the result of the /// Traits that gives the `Transform` category that is compatible with the result of the
@ -71,10 +71,10 @@ pub enum TAffine {}
impl TCategory for TGeneral { impl TCategory for TGeneral {
#[inline] #[inline]
fn check_homogeneous_invariants<N: RealField, D: DimName>(_: &MatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, const D: usize>(_: &CMatrixN<N, D>) -> bool
where where
N::Epsilon: Copy, N::Epsilon: Copy,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
true true
} }
@ -82,10 +82,10 @@ impl TCategory for TGeneral {
impl TCategory for TProjective { impl TCategory for TProjective {
#[inline] #[inline]
fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, const D: usize>(mat: &CMatrixN<N, D>) -> bool
where where
N::Epsilon: Copy, N::Epsilon: Copy,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
mat.is_invertible() mat.is_invertible()
} }
@ -98,12 +98,12 @@ impl TCategory for TAffine {
} }
#[inline] #[inline]
fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, const D: usize>(mat: &CMatrixN<N, D>) -> bool
where where
N::Epsilon: Copy, N::Epsilon: Copy,
DefaultAllocator: Allocator<N, D, D>, // DefaultAllocator: Allocator<N, D, D>,
{ {
let last = D::dim() - 1; let last = D - 1;
mat.is_invertible() mat.is_invertible()
&& mat[(last, last)] == N::one() && mat[(last, last)] == N::one()
&& (0..last).all(|i| mat[(last, i)].is_zero()) && (0..last).all(|i| mat[(last, i)].is_zero())
@ -157,33 +157,36 @@ super_tcategory_impl!(
/// 3D transformation. /// 3D transformation.
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct Transform<N: RealField, D: DimNameAdd<U1>, C: TCategory> pub struct Transform<N: RealField, C: TCategory, const D: usize>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
matrix: MatrixN<N, DimNameSum<D, U1>>, matrix: MatrixN<N, DimNameSum<Const<D>, U1>>,
_phantom: PhantomData<C>, _phantom: PhantomData<C>,
} }
// TODO // TODO
// impl<N: RealField + hash::Hash, D: DimNameAdd<U1> + hash::Hash, C: TCategory> hash::Hash for Transform<N, D, C> // impl<N: RealField + hash::Hash, D: DimNameAdd<U1> + hash::Hash, C: TCategory> hash::Hash for Transform<N, C, D>
// where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, // where DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
// Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: hash::Hash { // Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: hash::Hash {
// fn hash<H: hash::Hasher>(&self, state: &mut H) { // fn hash<H: hash::Hasher>(&self, state: &mut H) {
// self.matrix.hash(state); // self.matrix.hash(state);
// } // }
// } // }
impl<N: RealField, D: DimNameAdd<U1> + Copy, C: TCategory> Copy for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Copy for Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Copy, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Copy,
{ {
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Clone for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Clone for Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -192,10 +195,11 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Serialize for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Serialize for Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Serialize, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -206,29 +210,33 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: RealField, D: DimNameAdd<U1>, C: TCategory> Deserialize<'a> for Transform<N, D, C> impl<'a, N: RealField, C: TCategory, const D: usize> Deserialize<'a> for Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Deserialize<'a>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where where
Des: Deserializer<'a>, Des: Deserializer<'a>,
{ {
let matrix = MatrixN::<N, DimNameSum<D, U1>>::deserialize(deserializer)?; let matrix = MatrixN::<N, DimNameSum<Const<D>, U1>>::deserialize(deserializer)?;
Ok(Transform::from_matrix_unchecked(matrix)) Ok(Transform::from_matrix_unchecked(matrix))
} }
} }
impl<N: RealField + Eq, D: DimNameAdd<U1>, C: TCategory> Eq for Transform<N, D, C> where impl<N: RealField + Eq, C: TCategory, const D: usize> Eq for Transform<N, C, D>
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> PartialEq for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> PartialEq for Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -236,14 +244,15 @@ where
} }
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
/// Creates a new transformation from the given homogeneous matrix. The transformation category /// Creates a new transformation from the given homogeneous matrix. The transformation category
/// of `Self` is not checked to be verified by the given matrix. /// of `Self` is not checked to be verified by the given matrix.
#[inline] #[inline]
pub fn from_matrix_unchecked(matrix: MatrixN<N, DimNameSum<D, U1>>) -> Self { pub fn from_matrix_unchecked(matrix: MatrixN<N, DimNameSum<Const<D>, U1>>) -> Self {
Transform { Transform {
matrix, matrix,
_phantom: PhantomData, _phantom: PhantomData,
@ -263,7 +272,7 @@ where
/// assert_eq!(t.into_inner(), m); /// assert_eq!(t.into_inner(), m);
/// ``` /// ```
#[inline] #[inline]
pub fn into_inner(self) -> MatrixN<N, DimNameSum<D, U1>> { pub fn into_inner(self) -> MatrixN<N, DimNameSum<Const<D>, U1>> {
self.matrix self.matrix
} }
@ -271,7 +280,7 @@ where
/// Deprecated: Use [Transform::into_inner] instead. /// Deprecated: Use [Transform::into_inner] instead.
#[deprecated(note = "use `.into_inner()` instead")] #[deprecated(note = "use `.into_inner()` instead")]
#[inline] #[inline]
pub fn unwrap(self) -> MatrixN<N, DimNameSum<D, U1>> { pub fn unwrap(self) -> MatrixN<N, DimNameSum<Const<D>, U1>> {
self.matrix self.matrix
} }
@ -288,7 +297,7 @@ where
/// assert_eq!(*t.matrix(), m); /// assert_eq!(*t.matrix(), m);
/// ``` /// ```
#[inline] #[inline]
pub fn matrix(&self) -> &MatrixN<N, DimNameSum<D, U1>> { pub fn matrix(&self) -> &MatrixN<N, DimNameSum<Const<D>, U1>> {
&self.matrix &self.matrix
} }
@ -315,7 +324,7 @@ where
/// assert_eq!(*t.matrix(), expected); /// assert_eq!(*t.matrix(), expected);
/// ``` /// ```
#[inline] #[inline]
pub fn matrix_mut_unchecked(&mut self) -> &mut MatrixN<N, DimNameSum<D, U1>> { pub fn matrix_mut_unchecked(&mut self) -> &mut MatrixN<N, DimNameSum<Const<D>, U1>> {
&mut self.matrix &mut self.matrix
} }
@ -326,7 +335,7 @@ where
/// `TAffine` because not all projective transformations are affine (the other way-round is /// `TAffine` because not all projective transformations are affine (the other way-round is
/// valid though). /// valid though).
#[inline] #[inline]
pub fn set_category<CNew: SuperTCategoryOf<C>>(self) -> Transform<N, D, CNew> { pub fn set_category<CNew: SuperTCategoryOf<C>>(self) -> Transform<N, CNew, D> {
Transform::from_matrix_unchecked(self.matrix) Transform::from_matrix_unchecked(self.matrix)
} }
@ -335,7 +344,7 @@ where
#[deprecated( #[deprecated(
note = "This method is redundant with automatic `Copy` and the `.clone()` method and will be removed in a future release." note = "This method is redundant with automatic `Copy` and the `.clone()` method and will be removed in a future release."
)] )]
pub fn clone_owned(&self) -> Transform<N, D, C> { pub fn clone_owned(&self) -> Transform<N, C, D> {
Transform::from_matrix_unchecked(self.matrix.clone_owned()) Transform::from_matrix_unchecked(self.matrix.clone_owned())
} }
@ -352,7 +361,7 @@ where
/// assert_eq!(t.into_inner(), m); /// assert_eq!(t.into_inner(), m);
/// ``` /// ```
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> { pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>> {
self.matrix().clone_owned() self.matrix().clone_owned()
} }
@ -381,7 +390,7 @@ where
/// ``` /// ```
#[inline] #[inline]
#[must_use = "Did you mean to use try_inverse_mut()?"] #[must_use = "Did you mean to use try_inverse_mut()?"]
pub fn try_inverse(self) -> Option<Transform<N, D, C>> { pub fn try_inverse(self) -> Option<Transform<N, C, D>> {
if let Some(m) = self.matrix.try_inverse() { if let Some(m) = self.matrix.try_inverse() {
Some(Transform::from_matrix_unchecked(m)) Some(Transform::from_matrix_unchecked(m))
} else { } else {
@ -407,7 +416,7 @@ where
/// ``` /// ```
#[inline] #[inline]
#[must_use = "Did you mean to use inverse_mut()?"] #[must_use = "Did you mean to use inverse_mut()?"]
pub fn inverse(self) -> Transform<N, D, C> pub fn inverse(self) -> Transform<N, C, D>
where where
C: SubTCategoryOf<TProjective>, C: SubTCategoryOf<TProjective>,
{ {
@ -470,14 +479,14 @@ where
} }
} }
impl<N, D: DimNameAdd<U1>, C> Transform<N, D, C> impl<N, C, const D: usize> Transform<N, C, D>
where where
N: RealField, N: RealField,
C: TCategory, C: TCategory,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> Const<D>: DimNameAdd<U1>,
+ Allocator<N, DimNameSum<D, U1>> DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N, D, D> + Allocator<N, DimNameSum<Const<D>, U1>>, // + Allocator<N, D, D>
+ Allocator<N, D>, // + Allocator<N, D>
{ {
/// Transform the given point by this transformation. /// Transform the given point by this transformation.
/// ///
@ -492,18 +501,18 @@ where
/// ///
/// This is the same as the multiplication `self * v`. /// This is the same as the multiplication `self * v`.
#[inline] #[inline]
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self * v self * v
} }
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Transform<N, C, D>
where where
Const<D>: DimNameAdd<U1>,
C: SubTCategoryOf<TProjective>, C: SubTCategoryOf<TProjective>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N, DimNameSum<D, U1>> + Allocator<N, DimNameSum<Const<D>, U1>>, // + Allocator<N, D, D>
+ Allocator<N, D, D> // + Allocator<N, D>
+ Allocator<N, D>,
{ {
/// Transform the given point by the inverse of this transformation. /// Transform the given point by the inverse of this transformation.
/// This may be cheaper than inverting the transformation and transforming /// This may be cheaper than inverting the transformation and transforming
@ -517,27 +526,29 @@ where
/// This may be cheaper than inverting the transformation and transforming /// This may be cheaper than inverting the transformation and transforming
/// the vector. /// the vector.
#[inline] #[inline]
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> { pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
self.clone().inverse() * v self.clone().inverse() * v
} }
} }
impl<N: RealField, D: DimNameAdd<U1>> Transform<N, D, TGeneral> impl<N: RealField, const D: usize> Transform<N, TGeneral, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
/// A mutable reference to underlying matrix. Use `.matrix_mut_unchecked` instead if this /// A mutable reference to underlying matrix. Use `.matrix_mut_unchecked` instead if this
/// transformation category is not `TGeneral`. /// transformation category is not `TGeneral`.
#[inline] #[inline]
pub fn matrix_mut(&mut self) -> &mut MatrixN<N, DimNameSum<D, U1>> { pub fn matrix_mut(&mut self) -> &mut MatrixN<N, DimNameSum<Const<D>, U1>> {
self.matrix_mut_unchecked() self.matrix_mut_unchecked()
} }
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> AbsDiffEq for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> AbsDiffEq for Transform<N, C, D>
where where
Const<D>: DimNameAdd<U1>,
N::Epsilon: Copy, N::Epsilon: Copy,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -552,10 +563,11 @@ where
} }
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> RelativeEq for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> RelativeEq for Transform<N, C, D>
where where
Const<D>: DimNameAdd<U1>,
N::Epsilon: Copy, N::Epsilon: Copy,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -574,10 +586,11 @@ where
} }
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> UlpsEq for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> UlpsEq for Transform<N, C, D>
where where
Const<D>: DimNameAdd<U1>,
N::Epsilon: Copy, N::Epsilon: Copy,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {

View File

@ -1,17 +1,15 @@
use crate::base::dimension::{U2, U3};
use crate::geometry::{TAffine, TGeneral, TProjective, Transform}; use crate::geometry::{TAffine, TGeneral, TProjective, Transform};
/// A 2D general transformation that may not be invertible. Stored as a homogeneous 3x3 matrix. /// A 2D general transformation that may not be invertible. Stored as a homogeneous 3x3 matrix.
pub type Transform2<N> = Transform<N, U2, TGeneral>; pub type Transform2<N> = Transform<N, TGeneral, 2>;
/// An invertible 2D general transformation. Stored as a homogeneous 3x3 matrix. /// An invertible 2D general transformation. Stored as a homogeneous 3x3 matrix.
pub type Projective2<N> = Transform<N, U2, TProjective>; pub type Projective2<N> = Transform<N, TProjective, 2>;
/// A 2D affine transformation. Stored as a homogeneous 3x3 matrix. /// A 2D affine transformation. Stored as a homogeneous 3x3 matrix.
pub type Affine2<N> = Transform<N, U2, TAffine>; pub type Affine2<N> = Transform<N, TAffine, 2>;
/// A 3D general transformation that may not be inversible. Stored as a homogeneous 4x4 matrix. /// A 3D general transformation that may not be inversible. Stored as a homogeneous 4x4 matrix.
pub type Transform3<N> = Transform<N, U3, TGeneral>; pub type Transform3<N> = Transform<N, TGeneral, 3>;
/// An invertible 3D general transformation. Stored as a homogeneous 4x4 matrix. /// An invertible 3D general transformation. Stored as a homogeneous 4x4 matrix.
pub type Projective3<N> = Transform<N, U3, TProjective>; pub type Projective3<N> = Transform<N, TProjective, 3>;
/// A 3D affine transformation. Stored as a homogeneous 4x4 matrix. /// A 3D affine transformation. Stored as a homogeneous 4x4 matrix.
pub type Affine3<N> = Transform<N, U3, TAffine>; pub type Affine3<N> = Transform<N, TAffine, 3>;

View File

@ -4,13 +4,14 @@ use simba::scalar::RealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN}; use crate::base::{Const, DefaultAllocator, MatrixN};
use crate::geometry::{TCategory, Transform}; use crate::geometry::{TCategory, Transform};
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
/// Creates a new identity transform. /// Creates a new identity transform.
/// ///
@ -42,13 +43,14 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn identity() -> Self { pub fn identity() -> Self {
Self::from_matrix_unchecked(MatrixN::<_, DimNameSum<D, U1>>::identity()) Self::from_matrix_unchecked(MatrixN::<_, DimNameSum<Const<D>, U1>>::identity())
} }
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> One for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> One for Transform<N, C, D>
where where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
/// Creates a new identity transform. /// Creates a new identity transform.
#[inline] #[inline]

View File

@ -1,74 +1,76 @@
use simba::scalar::{RealField, SubsetOf}; use simba::scalar::{RealField, SubsetOf};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN}; use crate::base::{Const, DefaultAllocator, MatrixN};
use crate::geometry::{SuperTCategoryOf, TCategory, Transform}; use crate::geometry::{SuperTCategoryOf, TCategory, Transform};
impl<N1, N2, D: DimName, C1, C2> SubsetOf<Transform<N2, D, C2>> for Transform<N1, D, C1> impl<N1, N2, C1, C2, const D: usize> SubsetOf<Transform<N2, C2, D>> for Transform<N1, C1, D>
where where
N1: RealField + SubsetOf<N2>, N1: RealField + SubsetOf<N2>,
N2: RealField, N2: RealField,
C1: TCategory, C1: TCategory,
C2: SuperTCategoryOf<C1>, C2: SuperTCategoryOf<C1>,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>, + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
N1::Epsilon: Copy, N1::Epsilon: Copy,
N2::Epsilon: Copy, N2::Epsilon: Copy,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, D, C2> { fn to_superset(&self) -> Transform<N2, C2, D> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, D, C2>) -> bool { fn is_in_subset(t: &Transform<N2, C2, D>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, D, C2>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C2, D>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }
impl<N1, N2, D: DimName, C> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Transform<N1, D, C> impl<N1, N2, C, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>
for Transform<N1, C, D>
where where
N1: RealField + SubsetOf<N2>, N1: RealField + SubsetOf<N2>,
N2: RealField, N2: RealField,
C: TCategory, C: TCategory,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>, + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
N1::Epsilon: Copy, N1::Epsilon: Copy,
N2::Epsilon: Copy, N2::Epsilon: Copy,
{ {
#[inline] #[inline]
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> { fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
self.matrix().to_superset() self.matrix().to_superset()
} }
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool { fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
C::check_homogeneous_invariants(m) C::check_homogeneous_invariants(m)
} }
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
Self::from_matrix_unchecked(crate::convert_ref_unchecked(m)) Self::from_matrix_unchecked(crate::convert_ref_unchecked(m))
} }
} }
impl<N: RealField, D: DimName, C> From<Transform<N, D, C>> for MatrixN<N, DimNameSum<D, U1>> impl<N: RealField, C, const D: usize> From<Transform<N, C, D>>
for MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
C: TCategory, C: TCategory,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn from(t: Transform<N, D, C>) -> Self { fn from(t: Transform<N, C, D>) -> Self {
t.to_homogeneous() t.to_homogeneous()
} }
} }

View File

@ -79,10 +79,10 @@ use crate::geometry::{
* Indexing. * Indexing.
* *
*/ */
impl<N: RealField, D, C: TCategory> Index<(usize, usize)> for Transform<N, D, C> impl<N: RealField, C: TCategory, const D: usize> Index<(usize, usize)> for Transform<N, C, D>
where where
D: DimName + DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
type Output = N; type Output = N;
@ -93,10 +93,10 @@ where
} }
// Only general transformations are mutably indexable. // Only general transformations are mutably indexable.
impl<N: RealField, D> IndexMut<(usize, usize)> for Transform<N, D, TGeneral> impl<N: RealField, const D: usize> IndexMut<(usize, usize)> for Transform<N, TGeneral, D>
where where
D: DimName + DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
fn index_mut(&mut self, ij: (usize, usize)) -> &mut N { fn index_mut(&mut self, ij: (usize, usize)) -> &mut N {
@ -108,7 +108,7 @@ where
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
self: Transform<N, D, C>, rhs: VectorN<N, D>, Output = VectorN<N, D>; self: Transform<N, C, D>, rhs: VectorN<N, D>, Output = VectorN<N, D>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -133,7 +133,7 @@ md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
where DefaultAllocator: Allocator<N, D, D>; where DefaultAllocator: Allocator<N, D, D>;
self: Transform<N, D, C>, rhs: Point<N, D>, Output = Point<N, D>; self: Transform<N, C, D>, rhs: Point<N, D>, Output = Point<N, D>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -170,7 +170,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, D, C>, rhs: Rotation<N, D>, Output = Transform<N, D, C::Representative>; self: Transform<N, C, D>, rhs: Rotation<N, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
@ -181,7 +181,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; (D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Rotation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; self: Rotation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -192,7 +192,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>; (U4, U4), (U4, U1) for C: TCategoryMul<TAffine>;
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>, Output = Transform<N, U3, C::Representative>; self: Transform<N, C, 3>, rhs: UnitQuaternion<N>, Output = Transform<N, C::Representative, 3>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
@ -203,7 +203,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>; (U4, U1), (U4, U4) for C: TCategoryMul<TAffine>;
self: UnitQuaternion<N>, rhs: Transform<N, U3, C>, Output = Transform<N, U3, C::Representative>; self: UnitQuaternion<N>, rhs: Transform<N, C, 3>, Output = Transform<N, C::Representative, 3>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -215,7 +215,7 @@ md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
self: Transform<N, D, C>, rhs: Isometry<N, D, R>, Output = Transform<N, D, C::Representative>; self: Transform<N, C, D>, rhs: Isometry<N, R, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
@ -227,7 +227,7 @@ md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
self: Isometry<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; self: Isometry<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -239,7 +239,7 @@ md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
self: Transform<N, D, C>, rhs: Similarity<N, D, R>, Output = Transform<N, D, C::Representative>; self: Transform<N, C, D>, rhs: Similarity<N, R, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
@ -251,7 +251,7 @@ md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
self: Similarity<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; self: Similarity<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -270,7 +270,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, D, C>, rhs: Translation<N, D>, Output = Transform<N, D, C::Representative>; self: Transform<N, C, D>, rhs: Translation<N, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
@ -282,7 +282,7 @@ md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Translation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; self: Translation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -304,7 +304,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, D, C>, rhs: Rotation<N, D>, Output = Transform<N, D, C::Representative>; self: Transform<N, C, D>, rhs: Rotation<N, D>, Output = Transform<N, C::Representative, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
@ -315,7 +315,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; (D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Rotation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; self: Rotation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
@ -326,7 +326,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>; (U4, U4), (U4, U1) for C: TCategoryMul<TAffine>;
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>, Output = Transform<N, U3, C::Representative>; self: Transform<N, C, 3>, rhs: UnitQuaternion<N>, Output = Transform<N, C::Representative, 3>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
@ -337,7 +337,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>; (U4, U1), (U4, U4) for C: TCategoryMul<TAffine>;
self: UnitQuaternion<N>, rhs: Transform<N, U3, C>, Output = Transform<N, U3, C::Representative>; self: UnitQuaternion<N>, rhs: Transform<N, C, 3>, Output = Transform<N, C::Representative, 3>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
@ -350,7 +350,7 @@ md_impl_all!(
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >; // where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: Transform<N, D, C>, rhs: Isometry<N, D, R>, Output = Transform<N, D, C::Representative>; // self: Transform<N, C, D>, rhs: Isometry<N, R, D>, Output = Transform<N, C::Representative, D>;
// [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous()); // [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous());
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.inverse().to_homogeneous()); // [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.inverse().to_homogeneous());
// [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous()); // [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous());
@ -363,7 +363,7 @@ md_impl_all!(
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) // (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >; // where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: Isometry<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; // self: Isometry<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); // [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); // [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); // [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -377,7 +377,7 @@ md_impl_all!(
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
// where SB::Alloc: Allocator<N, D, D > // where SB::Alloc: Allocator<N, D, D >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >; // where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: Transform<N, D, C>, rhs: Similarity<N, D, R>, Output = Transform<N, D, C::Representative>; // self: Transform<N, C, D>, rhs: Similarity<N, R, D>, Output = Transform<N, C::Representative, D>;
// [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); // [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); // [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
// [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); // [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
@ -391,7 +391,7 @@ md_impl_all!(
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
// where SA::Alloc: Allocator<N, D, D > // where SA::Alloc: Allocator<N, D, D >
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >; // where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: Similarity<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; // self: Similarity<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); // [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); // [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); // [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
@ -402,7 +402,7 @@ md_impl_all!(
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, D, C>, rhs: Translation<N, D>, Output = Transform<N, D, C::Representative>; self: Transform<N, C, D>, rhs: Translation<N, D>, Output = Transform<N, C::Representative, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
@ -414,7 +414,7 @@ md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Translation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>; self: Translation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
@ -435,7 +435,7 @@ md_assign_impl_all!(
MulAssign, mul_assign where N: RealField; MulAssign, mul_assign where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
self: Transform<N, D, C>, rhs: Similarity<N, D, R>; self: Transform<N, C, D>, rhs: Similarity<N, R, D>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
); );
@ -445,7 +445,7 @@ md_assign_impl_all!(
MulAssign, mul_assign where N: RealField; MulAssign, mul_assign where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
self: Transform<N, D, C>, rhs: Isometry<N, D, R>; self: Transform<N, C, D>, rhs: Isometry<N, R, D>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
); );
@ -462,7 +462,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
MulAssign, mul_assign where N: RealField; MulAssign, mul_assign where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
self: Transform<N, D, C>, rhs: Translation<N, D>; self: Transform<N, C, D>, rhs: Translation<N, D>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
); );
@ -471,7 +471,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
MulAssign, mul_assign where N: RealField; MulAssign, mul_assign where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory;
self: Transform<N, D, C>, rhs: Rotation<N, D>; self: Transform<N, C, D>, rhs: Rotation<N, D>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
); );
@ -480,7 +480,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
MulAssign, mul_assign where N: RealField; MulAssign, mul_assign where N: RealField;
(U4, U4), (U4, U1) for C: TCategory; (U4, U4), (U4, U1) for C: TCategory;
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>; self: Transform<N, C, 3>, rhs: UnitQuaternion<N>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
); );
@ -500,7 +500,7 @@ md_assign_impl_all!(
// DivAssign, div_assign; // DivAssign, div_assign;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; // for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
// self: Transform<N, D, C>, rhs: Similarity<N, D, R>; // self: Transform<N, C, D>, rhs: Similarity<N, R, D>;
// [val] => *self *= rhs.inverse(); // [val] => *self *= rhs.inverse();
// [ref] => *self *= rhs.inverse(); // [ref] => *self *= rhs.inverse();
// ); // );
@ -511,7 +511,7 @@ md_assign_impl_all!(
// DivAssign, div_assign; // DivAssign, div_assign;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; // for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
// self: Transform<N, D, C>, rhs: Isometry<N, D, R>; // self: Transform<N, C, D>, rhs: Isometry<N, R, D>;
// [val] => *self *= rhs.inverse(); // [val] => *self *= rhs.inverse();
// [ref] => *self *= rhs.inverse(); // [ref] => *self *= rhs.inverse();
// ); // );
@ -520,7 +520,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
DivAssign, div_assign where N: RealField; DivAssign, div_assign where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
self: Transform<N, D, C>, rhs: Translation<N, D>; self: Transform<N, C, D>, rhs: Translation<N, D>;
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
); );
@ -529,7 +529,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
DivAssign, div_assign where N: RealField; DivAssign, div_assign where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory; (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory;
self: Transform<N, D, C>, rhs: Rotation<N, D>; self: Transform<N, C, D>, rhs: Rotation<N, D>;
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
); );
@ -538,7 +538,7 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
DivAssign, div_assign where N: RealField; DivAssign, div_assign where N: RealField;
(U4, U4), (U4, U1) for C: TCategory; (U4, U4), (U4, U1) for C: TCategory;
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>; self: Transform<N, C, 3>, rhs: UnitQuaternion<N>;
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
); );

View File

@ -2,19 +2,20 @@ use simba::simd::SimdValue;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN, Scalar}; use crate::base::{Const, DefaultAllocator, MatrixN, Scalar};
use crate::RealField; use crate::RealField;
use crate::geometry::{TCategory, Transform}; use crate::geometry::{TCategory, Transform};
impl<N: RealField, D: DimNameAdd<U1>, C> SimdValue for Transform<N, D, C> impl<N: RealField, C, const D: usize> SimdValue for Transform<N, C, D>
where where
N::Element: Scalar, N::Element: Scalar,
C: TCategory, C: TCategory,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> Const<D>: DimNameAdd<U1>,
+ Allocator<N::Element, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N::Element, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
type Element = Transform<N::Element, D, C>; type Element = Transform<N::Element, C, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;
#[inline] #[inline]

View File

@ -14,45 +14,44 @@ use abomonation::Abomonation;
use simba::scalar::{ClosedAdd, ClosedNeg, ClosedSub}; use simba::scalar::{ClosedAdd, ClosedNeg, ClosedSub};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::storage::Owned; use crate::base::storage::Owned;
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar};
use crate::geometry::Point; use crate::geometry::Point;
/// A translation. /// A translation.
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct Translation<N: Scalar, D: DimName> pub struct Translation<N: Scalar, const D: usize>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is /// The translation coordinates, i.e., how much is added to a point's coordinates when it is
/// translated. /// translated.
pub vector: VectorN<N, D>, pub vector: CVectorN<N, D>,
} }
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash> hash::Hash for Translation<N, D> impl<N: Scalar + hash::Hash, const D: usize> hash::Hash for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: hash::Hash, Owned<N, Const<D>>: hash::Hash,
{ {
fn hash<H: hash::Hasher>(&self, state: &mut H) { fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.vector.hash(state) self.vector.hash(state)
} }
} }
impl<N: Scalar + Copy, D: DimName> Copy for Translation<N, D> impl<N: Scalar + Copy, const D: usize> Copy for Translation<N, D> where
where // DefaultAllocator: Allocator<N, D>,
DefaultAllocator: Allocator<N, D>, Owned<N, Const<D>>: Copy
Owned<N, D>: Copy,
{ {
} }
impl<N: Scalar, D: DimName> Clone for Translation<N, D> impl<N: Scalar, const D: usize> Clone for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Clone, Owned<N, Const<D>>: Clone,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -65,8 +64,8 @@ impl<N, D> Abomonation for Translation<N, D>
where where
N: Scalar, N: Scalar,
D: DimName, D: DimName,
VectorN<N, D>: Abomonation, CVectorN<N, D>: Abomonation,
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.vector.entomb(writer) self.vector.entomb(writer)
@ -82,9 +81,9 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: Scalar, D: DimName> Serialize for Translation<N, D> impl<N: Scalar, const D: usize> Serialize for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Serialize, Owned<N, D>: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@ -96,29 +95,29 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: Scalar, D: DimName> Deserialize<'a> for Translation<N, D> impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Deserialize<'a>, Owned<N, D>: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where where
Des: Deserializer<'a>, Des: Deserializer<'a>,
{ {
let matrix = VectorN::<N, D>::deserialize(deserializer)?; let matrix = CVectorN::<N, D>::deserialize(deserializer)?;
Ok(Translation::from(matrix)) Ok(Translation::from(matrix))
} }
} }
impl<N: Scalar, D: DimName> Translation<N, D> impl<N: Scalar, const D: usize> Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new translation from the given vector. /// Creates a new translation from the given vector.
#[inline] #[inline]
#[deprecated(note = "Use `::from` instead.")] #[deprecated(note = "Use `::from` instead.")]
pub fn from_vector(vector: VectorN<N, D>) -> Translation<N, D> { pub fn from_vector(vector: CVectorN<N, D>) -> Translation<N, D> {
Translation { vector } Translation { vector }
} }
@ -164,15 +163,14 @@ where
/// assert_eq!(t.to_homogeneous(), expected); /// assert_eq!(t.to_homogeneous(), expected);
/// ``` /// ```
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
where where
N: Zero + One, N: Zero + One,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity(); let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity();
res.fixed_slice_mut::<D, U1>(0, D::dim()) res.fixed_slice_mut::<D, U1>(0, D).copy_from(&self.vector);
.copy_from(&self.vector);
res res
} }
@ -204,9 +202,9 @@ where
} }
} }
impl<N: Scalar + ClosedAdd, D: DimName> Translation<N, D> impl<N: Scalar + ClosedAdd, const D: usize> Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Translate the given point. /// Translate the given point.
/// ///
@ -224,9 +222,9 @@ where
} }
} }
impl<N: Scalar + ClosedSub, D: DimName> Translation<N, D> impl<N: Scalar + ClosedSub, const D: usize> Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Translate the given point by the inverse of this translation. /// Translate the given point by the inverse of this translation.
/// ///
@ -242,11 +240,14 @@ where
} }
} }
impl<N: Scalar + Eq, D: DimName> Eq for Translation<N, D> where DefaultAllocator: Allocator<N, D> {} impl<N: Scalar + Eq, const D: usize> Eq for Translation<N, D>
// where DefaultAllocator: Allocator<N, D>
{
}
impl<N: Scalar + PartialEq, D: DimName> PartialEq for Translation<N, D> impl<N: Scalar + PartialEq, const D: usize> PartialEq for Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Translation<N, D>) -> bool { fn eq(&self, right: &Translation<N, D>) -> bool {
@ -254,9 +255,9 @@ where
} }
} }
impl<N: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for Translation<N, D> impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -272,9 +273,9 @@ where
} }
} }
impl<N: Scalar + RelativeEq, D: DimName> RelativeEq for Translation<N, D> impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -294,9 +295,9 @@ where
} }
} }
impl<N: Scalar + UlpsEq, D: DimName> UlpsEq for Translation<N, D> impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -315,9 +316,9 @@ where
* Display * Display
* *
*/ */
impl<N: Scalar + fmt::Display, D: DimName> fmt::Display for Translation<N, D> impl<N: Scalar + fmt::Display, const D: usize> fmt::Display for Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D> + Allocator<usize, D>, // DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);

View File

@ -1,21 +1,19 @@
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::geometry::Translation; use crate::geometry::Translation;
/// A 1-dimensional translation. /// A 1-dimensional translation.
pub type Translation1<N> = Translation<N, U1>; pub type Translation1<N> = Translation<N, 1>;
/// A 2-dimensional translation. /// A 2-dimensional translation.
pub type Translation2<N> = Translation<N, U2>; pub type Translation2<N> = Translation<N, 2>;
/// A 3-dimensional translation. /// A 3-dimensional translation.
pub type Translation3<N> = Translation<N, U3>; pub type Translation3<N> = Translation<N, 3>;
/// A 4-dimensional translation. /// A 4-dimensional translation.
pub type Translation4<N> = Translation<N, U4>; pub type Translation4<N> = Translation<N, 4>;
/// A 5-dimensional translation. /// A 5-dimensional translation.
pub type Translation5<N> = Translation<N, U5>; pub type Translation5<N> = Translation<N, 5>;
/// A 6-dimensional translation. /// A 6-dimensional translation.
pub type Translation6<N> = Translation<N, U6>; pub type Translation6<N> = Translation<N, 6>;

View File

@ -12,15 +12,13 @@ use rand::{
use simba::scalar::{ClosedAdd, SupersetOf}; use simba::scalar::{ClosedAdd, SupersetOf};
use crate::base::allocator::Allocator; use crate::base::{CVectorN, Scalar};
use crate::base::dimension::{DimName, U1, U2, U3, U4, U5, U6};
use crate::base::{DefaultAllocator, Scalar, VectorN};
use crate::geometry::Translation; use crate::geometry::Translation;
impl<N: Scalar, D: DimName> Translation<N, D> impl<N: Scalar, const D: usize> Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new identity translation. /// Creates a new identity translation.
/// ///
@ -41,7 +39,7 @@ where
where where
N: Zero, N: Zero,
{ {
Self::from(VectorN::<N, D>::from_element(N::zero())) Self::from(CVectorN::<N, D>::from_element(N::zero()))
} }
/// Cast the components of `self` to another type. /// Cast the components of `self` to another type.
@ -56,15 +54,15 @@ where
pub fn cast<To: Scalar>(self) -> Translation<To, D> pub fn cast<To: Scalar>(self) -> Translation<To, D>
where where
Translation<To, D>: SupersetOf<Self>, Translation<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D>, // DefaultAllocator: Allocator<To, D>,
{ {
crate::convert(self) crate::convert(self)
} }
} }
impl<N: Scalar + Zero + ClosedAdd, D: DimName> One for Translation<N, D> impl<N: Scalar + Zero + ClosedAdd, const D: usize> One for Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {
@ -73,27 +71,27 @@ where
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: Scalar, D: DimName> Distribution<Translation<N, D>> for Standard impl<N: Scalar, const D: usize> Distribution<Translation<N, D>> for Standard
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N>, Standard: Distribution<N>,
{ {
/// Generate an arbitrary random variate for testing purposes. /// Generate an arbitrary random variate for testing purposes.
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> {
Translation::from(rng.gen::<VectorN<N, D>>()) Translation::from(rng.gen::<CVectorN<N, D>>())
} }
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: Scalar + Arbitrary + Send, D: DimName> Arbitrary for Translation<N, D> impl<N: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Send, Owned<N, D>: Send,
{ {
#[inline] #[inline]
fn arbitrary(rng: &mut Gen) -> Self { fn arbitrary(rng: &mut Gen) -> Self {
let v: VectorN<N, D> = Arbitrary::arbitrary(rng); let v: CVectorN<N, D> = Arbitrary::arbitrary(rng);
Self::from(v) Self::from(v)
} }
} }
@ -104,16 +102,17 @@ where
* *
*/ */
macro_rules! componentwise_constructors_impl( macro_rules! componentwise_constructors_impl(
($($doc: expr; $D: ty, $($args: ident:$irow: expr),*);* $(;)*) => {$( ($($doc: expr; $D: expr, $($args: ident:$irow: expr),*);* $(;)*) => {$(
impl<N: Scalar> Translation<N, $D> impl<N: Scalar> Translation<N, $D>
where DefaultAllocator: Allocator<N, $D> { // where DefaultAllocator: Allocator<N, $D>
{
#[doc = "Initializes this translation from its components."] #[doc = "Initializes this translation from its components."]
#[doc = "# Example\n```"] #[doc = "# Example\n```"]
#[doc = $doc] #[doc = $doc]
#[doc = "```"] #[doc = "```"]
#[inline] #[inline]
pub fn new($($args: N),*) -> Self { pub fn new($($args: N),*) -> Self {
Self::from(VectorN::<N, $D>::new($($args),*)) Self::from(CVectorN::<N, $D>::new($($args),*))
} }
} }
)*} )*}
@ -121,15 +120,15 @@ macro_rules! componentwise_constructors_impl(
componentwise_constructors_impl!( componentwise_constructors_impl!(
"# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);"; "# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);";
U1, x:0; 1, x:0;
"# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);"; "# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);";
U2, x:0, y:1; 2, x:0, y:1;
"# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);"; "# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);";
U3, x:0, y:1, z:2; 3, x:0, y:1, z:2;
"# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);"; "# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);";
U4, x:0, y:1, z:2, w:3; 4, x:0, y:1, z:2, w:3;
"# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);"; "# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);";
U5, x:0, y:1, z:2, w:3, a:4; 5, x:0, y:1, z:2, w:3, a:4;
"# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);"; "# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);";
U6, x:0, y:1, z:2, w:3, a:4, b:5; 6, x:0, y:1, z:2, w:3, a:4, b:5;
); );

View File

@ -4,8 +4,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::PrimitiveSimdValue; use simba::simd::PrimitiveSimdValue;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::base::{Const, DefaultAllocator, MatrixN, Scalar, VectorN};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
@ -24,11 +24,11 @@ use crate::geometry::{
* Translation -> Matrix (homogeneous) * Translation -> Matrix (homogeneous)
*/ */
impl<N1, N2, D: DimName> SubsetOf<Translation<N2, D>> for Translation<N1, D> impl<N1, N2, const D: usize> SubsetOf<Translation<N2, D>> for Translation<N1, D>
where where
N1: Scalar, N1: Scalar,
N2: Scalar + SupersetOf<N1>, N2: Scalar + SupersetOf<N1>,
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Translation<N2, D> { fn to_superset(&self) -> Translation<N2, D> {
@ -48,25 +48,25 @@ where
} }
} }
impl<N1, N2, D: DimName, R> SubsetOf<Isometry<N2, D, R>> for Translation<N1, D> impl<N1, N2, R, const D: usize> SubsetOf<Isometry<N2, R, D>> for Translation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, D>, R: AbstractRotation<N2, D>,
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, D, R> { fn to_superset(&self) -> Isometry<N2, R, D> {
Isometry::from_parts(self.to_superset(), R::identity()) Isometry::from_parts(self.to_superset(), R::identity())
} }
#[inline] #[inline]
fn is_in_subset(iso: &Isometry<N2, D, R>) -> bool { fn is_in_subset(iso: &Isometry<N2, R, D>) -> bool {
iso.rotation == R::identity() iso.rotation == R::identity()
} }
#[inline] #[inline]
fn from_superset_unchecked(iso: &Isometry<N2, D, R>) -> Self { fn from_superset_unchecked(iso: &Isometry<N2, R, D>) -> Self {
Self::from_superset_unchecked(&iso.translation) Self::from_superset_unchecked(&iso.translation)
} }
} }
@ -95,96 +95,96 @@ where
} }
} }
impl<N1, N2, D: DimName, R> SubsetOf<Similarity<N2, D, R>> for Translation<N1, D> impl<N1, N2, R, const D: usize> SubsetOf<Similarity<N2, R, D>> for Translation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, D>, R: AbstractRotation<N2, D>,
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, // DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, D, R> { fn to_superset(&self) -> Similarity<N2, R, D> {
Similarity::from_parts(self.to_superset(), R::identity(), N2::one()) Similarity::from_parts(self.to_superset(), R::identity(), N2::one())
} }
#[inline] #[inline]
fn is_in_subset(sim: &Similarity<N2, D, R>) -> bool { fn is_in_subset(sim: &Similarity<N2, R, D>) -> bool {
sim.isometry.rotation == R::identity() && sim.scaling() == N2::one() sim.isometry.rotation == R::identity() && sim.scaling() == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(sim: &Similarity<N2, D, R>) -> Self { fn from_superset_unchecked(sim: &Similarity<N2, R, D>) -> Self {
Self::from_superset_unchecked(&sim.isometry.translation) Self::from_superset_unchecked(&sim.isometry.translation)
} }
} }
impl<N1, N2, D, C> SubsetOf<Transform<N2, D, C>> for Translation<N1, D> impl<N1, N2, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Translation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N1, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N2, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, D, C> { fn to_superset(&self) -> Transform<N2, C, D> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, D, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }
impl<N1, N2, D> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Translation<N1, D> impl<N1, N2, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>> for Translation<N1, D>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N1, D> DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
+ Allocator<N2, D> + Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> // + Allocator<N1, D>
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>, // + Allocator<N2, D>
{ {
#[inline] #[inline]
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> { fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
self.to_homogeneous().to_superset() self.to_homogeneous().to_superset()
} }
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool { fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
let id = m.fixed_slice::<DimNameSum<D, U1>, D>(0, 0); let id = m.fixed_slice::<DimNameSum<Const<D>, U1>, D>(0, 0);
// Scalar types agree. // Scalar types agree.
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) && m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
// The block part does nothing. // The block part does nothing.
id.is_identity(N2::zero()) && id.is_identity(N2::zero()) &&
// The normalization factor is one. // The normalization factor is one.
m[(D::dim(), D::dim())] == N2::one() m[(D, D)] == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let t = m.fixed_slice::<D, U1>(0, D::dim()); let t = m.fixed_slice::<D, U1>(0, D);
Self { Self {
vector: crate::convert_unchecked(t.into_owned()), vector: crate::convert_unchecked(t.into_owned()),
} }
} }
} }
impl<N: Scalar + Zero + One, D: DimName> From<Translation<N, D>> for MatrixN<N, DimNameSum<D, U1>> impl<N: Scalar + Zero + One, const D: usize> From<Translation<N, D>>
for MatrixN<N, DimNameSum<Const<D>, U1>>
where where
D: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, DefaultAllocator:
Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> + Allocator<N, Const<D>>,
{ {
#[inline] #[inline]
fn from(t: Translation<N, D>) -> Self { fn from(t: Translation<N, D>) -> Self {
@ -192,22 +192,22 @@ where
} }
} }
impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Translation<N, D> impl<N: Scalar, const D: usize> From<VectorN<N, Const<D>>> for Translation<N, D>
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn from(vector: VectorN<N, D>) -> Self { fn from(vector: VectorN<N, Const<D>>) -> Self {
Translation { vector } Translation { vector }
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 2]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 2]>
for Translation<N, D> for Translation<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 2]>, N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 2]) -> Self { fn from(arr: [Translation<N::Element, D>; 2]) -> Self {
@ -218,12 +218,12 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 4]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 4]>
for Translation<N, D> for Translation<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 4]>, N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 4]) -> Self { fn from(arr: [Translation<N::Element, D>; 4]) -> Self {
@ -236,12 +236,12 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 8]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 8]>
for Translation<N, D> for Translation<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 8]>, N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 8]) -> Self { fn from(arr: [Translation<N::Element, D>; 8]) -> Self {
@ -258,12 +258,12 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 16]> impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 16]>
for Translation<N, D> for Translation<N, D>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 16]>, N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 16]) -> Self { fn from(arr: [Translation<N::Element, D>; 16]) -> Self {

View File

@ -1,10 +1,8 @@
use std::mem; use std::mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use crate::base::allocator::Allocator;
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB}; use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
use crate::base::dimension::{U1, U2, U3, U4, U5, U6}; use crate::base::Scalar;
use crate::base::{DefaultAllocator, Scalar};
use crate::geometry::Translation; use crate::geometry::Translation;
@ -15,9 +13,10 @@ use crate::geometry::Translation;
*/ */
macro_rules! deref_impl( macro_rules! deref_impl(
($D: ty, $Target: ident $(, $comps: ident)*) => { ($D: expr, $Target: ident $(, $comps: ident)*) => {
impl<N: Scalar> Deref for Translation<N, $D> impl<N: Scalar> Deref for Translation<N, $D>
where DefaultAllocator: Allocator<N, $D> { // where DefaultAllocator: Allocator<N, $D>
{
type Target = $Target<N>; type Target = $Target<N>;
#[inline] #[inline]
@ -27,7 +26,8 @@ macro_rules! deref_impl(
} }
impl<N: Scalar> DerefMut for Translation<N, $D> impl<N: Scalar> DerefMut for Translation<N, $D>
where DefaultAllocator: Allocator<N, $D> { // where DefaultAllocator: Allocator<N, $D>
{
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { mem::transmute(self) } unsafe { mem::transmute(self) }
@ -36,9 +36,9 @@ macro_rules! deref_impl(
} }
); );
deref_impl!(U1, X, x); deref_impl!(1, X, x);
deref_impl!(U2, XY, x, y); deref_impl!(2, XY, x, y);
deref_impl!(U3, XYZ, x, y, z); deref_impl!(3, XYZ, x, y, z);
deref_impl!(U4, XYZW, x, y, z, w); deref_impl!(4, XYZW, x, y, z, w);
deref_impl!(U5, XYZWA, x, y, z, w, a); deref_impl!(5, XYZWA, x, y, z, w, a);
deref_impl!(U6, XYZWAB, x, y, z, w, a, b); deref_impl!(6, XYZWAB, x, y, z, w, a, b);

View File

@ -1,16 +1,14 @@
use simba::simd::SimdValue; use simba::simd::SimdValue;
use crate::base::allocator::Allocator; use crate::base::VectorN;
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, VectorN};
use crate::Scalar; use crate::Scalar;
use crate::geometry::Translation; use crate::geometry::Translation;
impl<N: Scalar + SimdValue, D: DimName> SimdValue for Translation<N, D> impl<N: Scalar + SimdValue, const D: usize> SimdValue for Translation<N, D>
where where
N::Element: Scalar, N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>, // DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{ {
type Element = Translation<N::Element, D>; type Element = Translation<N::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -4,7 +4,6 @@ use num_complex::Complex;
use simba::scalar::{RealField, SubsetOf, SupersetOf}; use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdRealField}; use simba::simd::{PrimitiveSimdValue, SimdRealField};
use crate::base::dimension::U2;
use crate::base::{Matrix2, Matrix3, Scalar}; use crate::base::{Matrix2, Matrix3, Scalar};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Rotation2, Similarity, SuperTCategoryOf, TAffine, Transform, AbstractRotation, Isometry, Rotation2, Similarity, SuperTCategoryOf, TAffine, Transform,
@ -17,9 +16,9 @@ use crate::geometry::{
* *
* UnitComplex -> UnitComplex * UnitComplex -> UnitComplex
* UnitComplex -> Rotation<U1> * UnitComplex -> Rotation<U1>
* UnitComplex -> Isometry<U2> * UnitComplex -> Isometry<2>
* UnitComplex -> Similarity<U2> * UnitComplex -> Similarity<2>
* UnitComplex -> Transform<U2> * UnitComplex -> Transform<2>
* UnitComplex -> Matrix<U3> (homogeneous) * UnitComplex -> Matrix<U3> (homogeneous)
* *
* NOTE: * NOTE:
@ -70,68 +69,68 @@ where
} }
} }
impl<N1, N2, R> SubsetOf<Isometry<N2, U2, R>> for UnitComplex<N1> impl<N1, N2, R> SubsetOf<Isometry<N2, R, 2>> for UnitComplex<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, U2> + SupersetOf<Self>, R: AbstractRotation<N2, 2> + SupersetOf<Self>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, U2, R> { fn to_superset(&self) -> Isometry<N2, R, 2> {
Isometry::from_parts(Translation::identity(), crate::convert_ref(self)) Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
} }
#[inline] #[inline]
fn is_in_subset(iso: &Isometry<N2, U2, R>) -> bool { fn is_in_subset(iso: &Isometry<N2, R, 2>) -> bool {
iso.translation.vector.is_zero() iso.translation.vector.is_zero()
} }
#[inline] #[inline]
fn from_superset_unchecked(iso: &Isometry<N2, U2, R>) -> Self { fn from_superset_unchecked(iso: &Isometry<N2, R, 2>) -> Self {
crate::convert_ref_unchecked(&iso.rotation) crate::convert_ref_unchecked(&iso.rotation)
} }
} }
impl<N1, N2, R> SubsetOf<Similarity<N2, U2, R>> for UnitComplex<N1> impl<N1, N2, R> SubsetOf<Similarity<N2, R, 2>> for UnitComplex<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
R: AbstractRotation<N2, U2> + SupersetOf<Self>, R: AbstractRotation<N2, 2> + SupersetOf<Self>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, U2, R> { fn to_superset(&self) -> Similarity<N2, R, 2> {
Similarity::from_isometry(crate::convert_ref(self), N2::one()) Similarity::from_isometry(crate::convert_ref(self), N2::one())
} }
#[inline] #[inline]
fn is_in_subset(sim: &Similarity<N2, U2, R>) -> bool { fn is_in_subset(sim: &Similarity<N2, R, 2>) -> bool {
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one() sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
} }
#[inline] #[inline]
fn from_superset_unchecked(sim: &Similarity<N2, U2, R>) -> Self { fn from_superset_unchecked(sim: &Similarity<N2, R, 2>) -> Self {
crate::convert_ref_unchecked(&sim.isometry) crate::convert_ref_unchecked(&sim.isometry)
} }
} }
impl<N1, N2, C> SubsetOf<Transform<N2, U2, C>> for UnitComplex<N1> impl<N1, N2, C> SubsetOf<Transform<N2, C, 2>> for UnitComplex<N1>
where where
N1: RealField, N1: RealField,
N2: RealField + SupersetOf<N1>, N2: RealField + SupersetOf<N1>,
C: SuperTCategoryOf<TAffine>, C: SuperTCategoryOf<TAffine>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<N2, U2, C> { fn to_superset(&self) -> Transform<N2, C, 2> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
} }
#[inline] #[inline]
fn is_in_subset(t: &Transform<N2, U2, C>) -> bool { fn is_in_subset(t: &Transform<N2, C, 2>) -> bool {
<Self as SubsetOf<_>>::is_in_subset(t.matrix()) <Self as SubsetOf<_>>::is_in_subset(t.matrix())
} }
#[inline] #[inline]
fn from_superset_unchecked(t: &Transform<N2, U2, C>) -> Self { fn from_superset_unchecked(t: &Transform<N2, C, 2>) -> Self {
Self::from_superset_unchecked(t.matrix()) Self::from_superset_unchecked(t.matrix())
} }
} }

View File

@ -384,9 +384,12 @@ pub fn partial_sort2<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<(&'a T, &'
/// * [distance](fn.distance.html) /// * [distance](fn.distance.html)
/// * [distance_squared](fn.distance_squared.html) /// * [distance_squared](fn.distance_squared.html)
#[inline] #[inline]
pub fn center<N: SimdComplexField, D: DimName>(p1: &Point<N, D>, p2: &Point<N, D>) -> Point<N, D> pub fn center<N: SimdComplexField, const D: usize>(
where p1: &Point<N, D>,
DefaultAllocator: Allocator<N, D>, p2: &Point<N, D>,
) -> Point<N, D>
// where
// DefaultAllocator: Allocator<N, D>,
{ {
((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into() ((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into()
} }
@ -398,12 +401,12 @@ where
/// * [center](fn.center.html) /// * [center](fn.center.html)
/// * [distance_squared](fn.distance_squared.html) /// * [distance_squared](fn.distance_squared.html)
#[inline] #[inline]
pub fn distance<N: SimdComplexField, D: DimName>( pub fn distance<N: SimdComplexField, const D: usize>(
p1: &Point<N, D>, p1: &Point<N, D>,
p2: &Point<N, D>, p2: &Point<N, D>,
) -> N::SimdRealField ) -> N::SimdRealField
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
(&p2.coords - &p1.coords).norm() (&p2.coords - &p1.coords).norm()
} }
@ -415,12 +418,12 @@ where
/// * [center](fn.center.html) /// * [center](fn.center.html)
/// * [distance](fn.distance.html) /// * [distance](fn.distance.html)
#[inline] #[inline]
pub fn distance_squared<N: SimdComplexField, D: DimName>( pub fn distance_squared<N: SimdComplexField, const D: usize>(
p1: &Point<N, D>, p1: &Point<N, D>,
p2: &Point<N, D>, p2: &Point<N, D>,
) -> N::SimdRealField ) -> N::SimdRealField
where // where
DefaultAllocator: Allocator<N, D>, // DefaultAllocator: Allocator<N, D>,
{ {
(&p2.coords - &p1.coords).norm_squared() (&p2.coords - &p1.coords).norm_squared()
} }