First compiling version after migrating the geometry module to const-generics.

This commit is contained in:
Crozet Sébastien 2021-04-08 11:53:01 +02:00
parent 8abbb35b40
commit 23a7d7475b
44 changed files with 934 additions and 954 deletions

View File

@ -11,8 +11,8 @@ use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1}; use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{ use crate::base::{
DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, Vector2, Const, DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector,
Vector3, VectorN, Vector2, Vector3, VectorN,
}; };
use crate::geometry::{ use crate::geometry::{
Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point2, Point3, Rotation2, Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point2, Point3, Rotation2,
@ -411,18 +411,33 @@ where
transform * v transform * v
} }
}
impl<N: RealField, S: Storage<N, Const<3>, Const<3>>> SquareMatrix<N, Const<3>, S> {
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_point( pub fn transform_point(&self, pt: &Point<N, 2>) -> Point<N, 2> {
&self, let transform = self.fixed_slice::<Const<2>, Const<2>>(0, 0);
pt: &Point<N, { DimNameDiff::<D, U1>::USIZE }>, let translation = self.fixed_slice::<Const<2>, U1>(0, 2);
) -> Point<N, { DimNameDiff::<D, U1>::USIZE }> { let normalizer = self.fixed_slice::<U1, Const<2>>(2, 0);
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0); let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((2, 2)) };
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); if !n.is_zero() {
let n = normalizer.tr_dot(&pt.coords) (transform * pt + translation) / n
+ unsafe { *self.get_unchecked((D::dim() - 1, D::dim() - 1)) }; } else {
transform * pt + translation
}
}
}
impl<N: RealField, S: Storage<N, Const<4>, Const<4>>> SquareMatrix<N, Const<4>, S> {
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
#[inline]
pub fn transform_point(&self, pt: &Point<N, 3>) -> Point<N, 3> {
let transform = self.fixed_slice::<Const<3>, Const<3>>(0, 0);
let translation = self.fixed_slice::<Const<3>, U1>(0, 3);
let normalizer = self.fixed_slice::<U1, Const<3>>(3, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((3, 3)) };
if !n.is_zero() { if !n.is_zero() {
(transform * pt + translation) / n (transform * pt + translation) / n

View File

@ -39,7 +39,6 @@ pub trait AbstractRotation<N: Scalar, const D: usize>: PartialEq + ClosedMul + C
impl<N: SimdRealField, const D: usize> 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>,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {

View File

@ -59,14 +59,14 @@ use crate::geometry::{AbstractRotation, Point, Translation};
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "R: Serialize, serde(bound(serialize = "R: Serialize,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, Const<D>>,
Owned<N, D>: Serialize")) Owned<N, Const<D>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "R: Deserialize<'de>, serde(bound(deserialize = "R: Deserialize<'de>,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, Const<D>>,
Owned<N, D>: Deserialize<'de>")) Owned<N, Const<D>>: Deserialize<'de>"))
)] )]
pub struct Isometry<N: Scalar, R, const D: usize> pub struct Isometry<N: Scalar, R, const D: usize>
// where // where
@ -84,7 +84,6 @@ where
N: SimdRealField, N: SimdRealField,
R: Abomonation, R: Abomonation,
Translation<N, D>: Abomonation, Translation<N, D>: Abomonation,
// 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)?;
@ -104,7 +103,6 @@ where
impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Isometry<N, R, D> impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Isometry<N, R, D>
where where
// DefaultAllocator: Allocator<N, D>,
Owned<N, Const<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) {
@ -114,7 +112,6 @@ where
} }
impl<N: Scalar + Copy, R: Copy, const D: usize> Copy for Isometry<N, R, D> where impl<N: Scalar + Copy, R: Copy, const D: usize> Copy for Isometry<N, R, D> where
// DefaultAllocator: Allocator<N, D>,
Owned<N, Const<D>>: Copy Owned<N, Const<D>>: Copy
{ {
} }
@ -163,7 +160,6 @@ impl<N: Scalar, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D> 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>,
{ {
/// Inverts `self`. /// Inverts `self`.
/// ///
@ -318,7 +314,6 @@ where
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D> 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>,
{ {
/// Transform the given point by this isometry. /// Transform the given point by this isometry.
/// ///
@ -504,14 +499,13 @@ impl<N: SimdRealField, R, const D: usize> Isometry<N, R, D>
} }
impl<N: SimdRealField, R, const D: usize> Eq for Isometry<N, R, D> where impl<N: SimdRealField, R, const D: usize> Eq for Isometry<N, R, D> where
R: AbstractRotation<N, D> + Eq // DefaultAllocator: Allocator<N, D>, R: AbstractRotation<N, D> + Eq
{ {
} }
impl<N: SimdRealField, R, const D: usize> PartialEq for Isometry<N, R, D> 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>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -522,7 +516,6 @@ where
impl<N: RealField, R, const D: usize> AbsDiffEq for Isometry<N, R, D> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -542,7 +535,6 @@ where
impl<N: RealField, R, const D: usize> RelativeEq for Isometry<N, R, D> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -568,7 +560,6 @@ where
impl<N: RealField, R, const D: usize> UlpsEq for Isometry<N, R, D> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -592,7 +583,6 @@ where
impl<N: RealField + fmt::Display, R, const D: usize> fmt::Display for Isometry<N, R, D> 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>,
{ {
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

@ -13,19 +13,17 @@ use rand::{
use simba::scalar::SupersetOf; use simba::scalar::SupersetOf;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::dimension::U2;
use crate::base::{Vector2, Vector3}; use crate::base::{Vector2, Vector3};
use crate::{ use crate::{
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point, AbstractRotation, Const, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3,
Point3, Rotation, Rotation3, Scalar, Translation, Translation2, Translation3, UnitComplex, Point, Point3, Rotation, Rotation3, Scalar, Translation, Translation2, Translation3,
UnitQuaternion, UnitComplex, UnitQuaternion,
}; };
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D> 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>,
{ {
/// Creates a new identity isometry. /// Creates a new identity isometry.
/// ///
@ -73,7 +71,6 @@ where
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> One for Isometry<N, R, D> 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>,
{ {
/// Creates a new identity isometry. /// Creates a new identity isometry.
#[inline] #[inline]
@ -87,7 +84,6 @@ impl<N: crate::RealField, R, const D: usize> Distribution<Isometry<N, R, D>> for
where where
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>,
Standard: Distribution<N> + Distribution<R>, Standard: Distribution<N> + Distribution<R>,
// DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, R, D> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, R, D> {
@ -101,8 +97,7 @@ 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, Const<D>>: Send,
// DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn arbitrary(rng: &mut Gen) -> Self { fn arbitrary(rng: &mut Gen) -> Self {
@ -136,10 +131,7 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn new(translation: Vector2<N>, angle: N) -> Self { pub fn new(translation: Vector2<N>, angle: N) -> Self {
Self::from_parts( Self::from_parts(Translation::from(translation), Rotation::<N, 2>::new(angle))
Translation::from(translation),
Rotation::<N, U2>::new(angle),
)
} }
/// Creates a new isometry from the given translation coordinates. /// Creates a new isometry from the given translation coordinates.

View File

@ -27,7 +27,6 @@ where
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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, R2, D> { fn to_superset(&self) -> Isometry<N2, R2, D> {
@ -63,7 +62,7 @@ where
#[inline] #[inline]
fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool { fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool {
crate::is_convertible::<_, UnitQuaternion<N1>>(&dq.rotation()) crate::is_convertible::<_, UnitQuaternion<N1>>(&dq.rotation())
&& crate::is_convertible::<_, Translation<N1, _>>(&dq.translation()) && crate::is_convertible::<_, Translation<N1, 3>>(&dq.translation())
} }
#[inline] #[inline]
@ -79,7 +78,6 @@ where
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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, R2, D> { fn to_superset(&self) -> Similarity<N2, R2, D> {
@ -154,8 +152,8 @@ where
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<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::<Const<D>, Const<D>>(0, 0);
let bottom = m.fixed_slice::<U1, D>(D, 0); let bottom = m.fixed_slice::<U1, Const<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)) &&
@ -167,7 +165,7 @@ where
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let t = m.fixed_slice::<D, U1>(0, D).into_owned(); let t = m.fixed_slice::<Const<D>, U1>(0, D).into_owned();
let t = Translation { let t = Translation {
vector: crate::convert_unchecked(t), vector: crate::convert_unchecked(t),
}; };
@ -208,7 +206,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, R::Element, D>; 2]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 2]) -> Self {
@ -227,7 +224,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, R::Element, D>; 4]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 4]) -> Self {
@ -256,7 +252,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, R::Element, D>; 8]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 8]) -> Self {
@ -293,7 +288,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Isometry<N::Element, R::Element, D>; 16]) -> Self { fn from(arr: [Isometry<N::Element, R::Element, D>; 16]) -> Self {

View File

@ -5,8 +5,8 @@ use simba::scalar::{ClosedAdd, ClosedMul};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U1, U2, U3, U4}; use crate::base::dimension::{U1, U2, U3};
use crate::base::{DefaultAllocator, Unit, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, Unit};
use crate::Scalar; use crate::Scalar;
use crate::geometry::{ use crate::geometry::{
@ -68,10 +68,9 @@ macro_rules! isometry_binop_impl(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField, D: DimName, R> $Op<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField, R, const D: usize> $Op<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>, {
DefaultAllocator: Allocator<N, D> {
type Output = $Output; type Output = $Output;
#[inline] #[inline]
@ -116,20 +115,18 @@ macro_rules! isometry_binop_assign_impl_all(
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
[val] => $action_val: expr; [val] => $action_val: expr;
[ref] => $action_ref: expr;) => { [ref] => $action_ref: expr;) => {
impl<N: SimdRealField, D: DimName, R> $OpAssign<$Rhs> for $Lhs impl<N: SimdRealField, R, const D: usize> $OpAssign<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D> {
DefaultAllocator: Allocator<N, D> {
#[inline] #[inline]
fn $op_assign(&mut $lhs, $rhs: $Rhs) { fn $op_assign(&mut $lhs, $rhs: $Rhs) {
$action_val $action_val
} }
} }
impl<'b, N: SimdRealField, D: DimName, R> $OpAssign<&'b $Rhs> for $Lhs impl<'b, N: SimdRealField, R, const D: usize> $OpAssign<&'b $Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D> {
DefaultAllocator: Allocator<N, D> {
#[inline] #[inline]
fn $op_assign(&mut $lhs, $rhs: &'b $Rhs) { fn $op_assign(&mut $lhs, $rhs: &'b $Rhs) {
$action_ref $action_ref
@ -142,7 +139,7 @@ macro_rules! isometry_binop_assign_impl_all(
// Isometry ÷ Isometry // Isometry ÷ Isometry
isometry_binop_impl_all!( isometry_binop_impl_all!(
Mul, mul; Mul, mul;
self: Isometry<N, D, R>, rhs: Isometry<N, D, R>, Output = Isometry<N, D, R>; self: Isometry<N, R, D>, rhs: Isometry<N, R, D>, Output = Isometry<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 +154,7 @@ isometry_binop_impl_all!(
isometry_binop_impl_all!( isometry_binop_impl_all!(
Div, div; Div, div;
self: Isometry<N, D, R>, rhs: Isometry<N, D, R>, Output = Isometry<N, D, R>; self: Isometry<N, R, D>, rhs: Isometry<N, R, D>, Output = Isometry<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 +164,7 @@ isometry_binop_impl_all!(
// Isometry ×= Translation // Isometry ×= Translation
isometry_binop_assign_impl_all!( isometry_binop_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
self: Isometry<N, D, R>, rhs: Translation<N, D>; self: Isometry<N, R, D>, rhs: Translation<N, D>;
[val] => *self *= &rhs; [val] => *self *= &rhs;
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { [ref] => #[allow(clippy::suspicious_op_assign_impl)] {
let shift = self.rotation.transform_vector(&rhs.vector); let shift = self.rotation.transform_vector(&rhs.vector);
@ -179,7 +176,7 @@ isometry_binop_assign_impl_all!(
// Isometry ÷= Isometry // Isometry ÷= Isometry
isometry_binop_assign_impl_all!( isometry_binop_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
self: Isometry<N, D, R>, rhs: Isometry<N, D, R>; self: Isometry<N, R, D>, rhs: Isometry<N, R, D>;
[val] => *self *= &rhs; [val] => *self *= &rhs;
[ref] => { [ref] => {
let shift = self.rotation.transform_vector(&rhs.translation.vector); let shift = self.rotation.transform_vector(&rhs.translation.vector);
@ -190,7 +187,7 @@ isometry_binop_assign_impl_all!(
isometry_binop_assign_impl_all!( isometry_binop_assign_impl_all!(
DivAssign, div_assign; DivAssign, div_assign;
self: Isometry<N, D, R>, rhs: Isometry<N, D, R>; self: Isometry<N, R, D>, rhs: Isometry<N, R, D>;
[val] => *self /= &rhs; [val] => *self /= &rhs;
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
); );
@ -199,16 +196,18 @@ isometry_binop_assign_impl_all!(
// Isometry ÷= R // Isometry ÷= R
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;
(D, U1), (D, D) for D: DimName; (Const<D>, U1), (Const<D>, Const<D>)
self: Isometry<N, D, Rotation<N, D>>, rhs: Rotation<N, D>; const D; for; where;
self: Isometry<N, Rotation<N, D>, D>, rhs: Rotation<N, D>;
[val] => self.rotation *= rhs; [val] => self.rotation *= rhs;
[ref] => self.rotation *= rhs.clone(); [ref] => self.rotation *= rhs.clone();
); );
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;
(D, U1), (D, D) for D: DimName; (Const<D>, U1), (Const<D>, Const<D>)
self: Isometry<N, D, Rotation<N, D>>, rhs: Rotation<N, D>; const D; for; where;
self: Isometry<N, Rotation<N, D>, D>, rhs: Rotation<N, D>;
// 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() };
@ -216,16 +215,18 @@ 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)
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>; const; for; where;
self: Isometry<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>;
[val] => self.rotation *= rhs; [val] => self.rotation *= rhs;
[ref] => self.rotation *= *rhs; [ref] => self.rotation *= *rhs;
); );
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)
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>; const; for; where;
self: Isometry<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() };
@ -233,16 +234,18 @@ 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;
(U2, U2), (U2, U2) for; (U2, U2), (U2, U2)
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>; const; for; where;
self: Isometry<N, UnitComplex<N>, 2>, rhs: UnitComplex<N>;
[val] => self.rotation *= rhs; [val] => self.rotation *= rhs;
[ref] => self.rotation *= *rhs; [ref] => self.rotation *= *rhs;
); );
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;
(U2, U2), (U2, U2) for; (U2, U2), (U2, U2)
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>; const; for; where;
self: Isometry<N, UnitComplex<N>, 2>, rhs: UnitComplex<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() };
@ -251,7 +254,7 @@ md_assign_impl_all!(
// Isometry × Point // Isometry × Point
isometry_binop_impl_all!( isometry_binop_impl_all!(
Mul, mul; Mul, mul;
self: Isometry<N, D, R>, right: Point<N, D>, Output = Point<N, D>; self: Isometry<N, R, D>, right: Point<N, D>, Output = Point<N, D>;
[val val] => self.translation * self.rotation.transform_point(&right); [val val] => self.translation * self.rotation.transform_point(&right);
[ref val] => &self.translation * self.rotation.transform_point(&right); [ref val] => &self.translation * self.rotation.transform_point(&right);
[val ref] => self.translation * self.rotation.transform_point(right); [val ref] => self.translation * self.rotation.transform_point(right);
@ -263,7 +266,7 @@ isometry_binop_impl_all!(
Mul, mul; Mul, mul;
// TODO: because of `transform_vector`, we cant use a generic storage type for the rhs vector, // TODO: because of `transform_vector`, we cant use a generic storage type for the rhs vector,
// i.e., right: Vector<N, D, S> where S: Storage<N, D>. // i.e., right: Vector<N, D, S> where S: Storage<N, D>.
self: Isometry<N, D, R>, right: VectorN<N, D>, Output = VectorN<N, D>; self: Isometry<N, R, D>, right: CVectorN<N, D>, Output = CVectorN<N, D>;
[val val] => self.rotation.transform_vector(&right); [val val] => self.rotation.transform_vector(&right);
[ref val] => self.rotation.transform_vector(&right); [ref val] => self.rotation.transform_vector(&right);
[val ref] => self.rotation.transform_vector(right); [val ref] => self.rotation.transform_vector(right);
@ -275,7 +278,7 @@ isometry_binop_impl_all!(
Mul, mul; Mul, mul;
// TODO: because of `transform_vector`, we cant use a generic storage type for the rhs vector, // TODO: because of `transform_vector`, we cant use a generic storage type for the rhs vector,
// i.e., right: Vector<N, D, S> where S: Storage<N, D>. // i.e., right: Vector<N, D, S> where S: Storage<N, D>.
self: Isometry<N, D, R>, right: Unit<VectorN<N, D>>, Output = Unit<VectorN<N, D>>; self: Isometry<N, R, D>, right: Unit<CVectorN<N, D>>, Output = Unit<CVectorN<N, D>>;
[val val] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref())); [val val] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
[ref val] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref())); [ref val] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
[val ref] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref())); [val ref] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
@ -285,7 +288,7 @@ isometry_binop_impl_all!(
// Isometry × Translation // Isometry × Translation
isometry_binop_impl_all!( isometry_binop_impl_all!(
Mul, mul; Mul, mul;
self: Isometry<N, D, R>, right: Translation<N, D>, Output = Isometry<N, D, R>; self: Isometry<N, R, D>, right: Translation<N, D>, Output = Isometry<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;
@ -299,7 +302,7 @@ isometry_binop_impl_all!(
// Translation × Isometry // Translation × Isometry
isometry_binop_impl_all!( isometry_binop_impl_all!(
Mul, mul; Mul, mul;
self: Translation<N, D>, right: Isometry<N, D, R>, Output = Isometry<N, D, R>; self: Translation<N, D>, right: Isometry<N, R, D>, Output = Isometry<N, R, D>;
[val val] => Isometry::from_parts(self * right.translation, right.rotation); [val val] => Isometry::from_parts(self * right.translation, right.rotation);
[ref val] => Isometry::from_parts(self * &right.translation, right.rotation); [ref val] => Isometry::from_parts(self * &right.translation, right.rotation);
[val ref] => Isometry::from_parts(self * &right.translation, right.rotation.clone()); [val ref] => Isometry::from_parts(self * &right.translation, right.rotation.clone());
@ -308,13 +311,11 @@ isometry_binop_impl_all!(
macro_rules! isometry_from_composition_impl( macro_rules! isometry_from_composition_impl(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(for $Dims: ident: $DimsBound: ident),*; $($Dims: ident),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField $(, $Dims: $DimsBound)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField $(, const $Dims: usize)*> $Op<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField {
DefaultAllocator: Allocator<N, $R1, $C1> +
Allocator<N, $R2, $C2> {
type Output = $Output; type Output = $Output;
#[inline] #[inline]
@ -327,7 +328,7 @@ macro_rules! isometry_from_composition_impl(
macro_rules! isometry_from_composition_impl_all( macro_rules! isometry_from_composition_impl_all(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(for $Dims: ident: $DimsBound: ident),*; $($Dims: ident),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
[val val] => $action_val_val: expr; [val val] => $action_val_val: expr;
[ref val] => $action_ref_val: expr; [ref val] => $action_ref_val: expr;
@ -336,25 +337,25 @@ macro_rules! isometry_from_composition_impl_all(
isometry_from_composition_impl!( isometry_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: $Lhs, $rhs: $Rhs, Output = $Output; $lhs: $Lhs, $rhs: $Rhs, Output = $Output;
$action_val_val; ); $action_val_val; );
isometry_from_composition_impl!( isometry_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Output; $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Output;
$action_ref_val; 'a); $action_ref_val; 'a);
isometry_from_composition_impl!( isometry_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Output; $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Output;
$action_val_ref; 'b); $action_val_ref; 'b);
isometry_from_composition_impl!( isometry_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Output; $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Output;
$action_ref_ref; 'a, 'b); $action_ref_ref; 'a, 'b);
} }
@ -363,8 +364,8 @@ macro_rules! isometry_from_composition_impl_all(
// Rotation × Translation // Rotation × Translation
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName; D;
self: Rotation<N, D>, right: Translation<N, D>, Output = Isometry<N, D, Rotation<N, D>>; self: Rotation<N, D>, right: Translation<N, D>, Output = Isometry<N, Rotation<N, D>, D>;
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self); [val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
[ref val] => Isometry::from_parts(Translation::from(self * right.vector), self.clone()); [ref val] => Isometry::from_parts(Translation::from(self * right.vector), self.clone());
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self); [val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
@ -374,9 +375,9 @@ isometry_from_composition_impl_all!(
// UnitQuaternion × Translation // UnitQuaternion × Translation
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, right: Translation<N, U3>, self: UnitQuaternion<N>, right: Translation<N, 3>,
Output = Isometry<N, U3, UnitQuaternion<N>>; Output = Isometry<N, UnitQuaternion<N>, 3>;
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self); [val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self); [ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self);
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self); [val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
@ -386,9 +387,9 @@ isometry_from_composition_impl_all!(
// Isometry × Rotation // Isometry × Rotation
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName; D;
self: Isometry<N, D, Rotation<N, D>>, rhs: Rotation<N, D>, self: Isometry<N, Rotation<N, D>, D>, rhs: Rotation<N, D>,
Output = Isometry<N, D, Rotation<N, D>>; Output = Isometry<N, Rotation<N, D>, D>;
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs); [val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone. [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone.
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone()); [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
@ -398,9 +399,9 @@ isometry_from_composition_impl_all!(
// Rotation × Isometry // Rotation × Isometry
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName; D;
self: Rotation<N, D>, right: Isometry<N, D, Rotation<N, D>>, self: Rotation<N, D>, right: Isometry<N, Rotation<N, D>, D>,
Output = Isometry<N, D, Rotation<N, D>>; Output = Isometry<N, Rotation<N, D>, 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;
@ -413,9 +414,9 @@ isometry_from_composition_impl_all!(
// Isometry ÷ Rotation // Isometry ÷ Rotation
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Div, div; Div, div;
(D, D), (D, U1) for D: DimName; D;
self: Isometry<N, D, Rotation<N, D>>, rhs: Rotation<N, D>, self: Isometry<N, Rotation<N, D>, D>, rhs: Rotation<N, D>,
Output = Isometry<N, D, Rotation<N, D>>; Output = Isometry<N, Rotation<N, D>, D>;
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs); [val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone. [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone.
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone()); [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
@ -425,9 +426,9 @@ isometry_from_composition_impl_all!(
// Rotation ÷ Isometry // Rotation ÷ Isometry
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Div, div; Div, div;
(D, D), (D, U1) for D: DimName; D;
self: Rotation<N, D>, right: Isometry<N, D, Rotation<N, D>>, self: Rotation<N, D>, right: Isometry<N, Rotation<N, D>, D>,
Output = Isometry<N, D, Rotation<N, D>>; Output = Isometry<N, Rotation<N, D>, D>;
// 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() };
@ -438,9 +439,9 @@ isometry_from_composition_impl_all!(
// Isometry × UnitQuaternion // Isometry × UnitQuaternion
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>, self: Isometry<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
Output = Isometry<N, U3, UnitQuaternion<N>>; Output = Isometry<N, UnitQuaternion<N>, 3>;
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs); [val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone. [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone.
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
@ -450,9 +451,9 @@ isometry_from_composition_impl_all!(
// UnitQuaternion × Isometry // UnitQuaternion × Isometry
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, right: Isometry<N, U3, UnitQuaternion<N>>, self: UnitQuaternion<N>, right: Isometry<N, UnitQuaternion<N>, 3>,
Output = Isometry<N, U3, UnitQuaternion<N>>; Output = Isometry<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;
@ -465,9 +466,9 @@ isometry_from_composition_impl_all!(
// Isometry ÷ UnitQuaternion // Isometry ÷ UnitQuaternion
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Div, div; Div, div;
(U4, U1), (U3, U1); ;
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>, self: Isometry<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
Output = Isometry<N, U3, UnitQuaternion<N>>; Output = Isometry<N, UnitQuaternion<N>, 3>;
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs); [val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone. [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone.
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
@ -477,9 +478,9 @@ isometry_from_composition_impl_all!(
// UnitQuaternion ÷ Isometry // UnitQuaternion ÷ Isometry
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Div, div; Div, div;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, right: Isometry<N, U3, UnitQuaternion<N>>, self: UnitQuaternion<N>, right: Isometry<N, UnitQuaternion<N>, 3>,
Output = Isometry<N, U3, UnitQuaternion<N>>; Output = Isometry<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() };
@ -490,8 +491,8 @@ isometry_from_composition_impl_all!(
// Translation × Rotation // Translation × Rotation
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName; D;
self: Translation<N, D>, right: Rotation<N, D>, Output = Isometry<N, D, Rotation<N, D>>; self: Translation<N, D>, right: Rotation<N, D>, Output = Isometry<N, Rotation<N, D>, D>;
[val val] => Isometry::from_parts(self, right); [val val] => Isometry::from_parts(self, right);
[ref val] => Isometry::from_parts(self.clone(), right); [ref val] => Isometry::from_parts(self.clone(), right);
[val ref] => Isometry::from_parts(self, right.clone()); [val ref] => Isometry::from_parts(self, right.clone());
@ -501,8 +502,8 @@ isometry_from_composition_impl_all!(
// Translation × UnitQuaternion // Translation × UnitQuaternion
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: Translation<N, U3>, right: UnitQuaternion<N>, Output = Isometry<N, U3, UnitQuaternion<N>>; self: Translation<N, 3>, right: UnitQuaternion<N>, Output = Isometry<N, UnitQuaternion<N>, 3>;
[val val] => Isometry::from_parts(self, right); [val val] => Isometry::from_parts(self, right);
[ref val] => Isometry::from_parts(self.clone(), right); [ref val] => Isometry::from_parts(self.clone(), right);
[val ref] => Isometry::from_parts(self, *right); [val ref] => Isometry::from_parts(self, *right);
@ -512,9 +513,9 @@ isometry_from_composition_impl_all!(
// Isometry × UnitComplex // Isometry × UnitComplex
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U2, U1), (U2, U1); ;
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>, self: Isometry<N, UnitComplex<N>, 2>, rhs: UnitComplex<N>,
Output = Isometry<N, U2, UnitComplex<N>>; Output = Isometry<N, UnitComplex<N>, 2>;
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs); [val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone. [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone.
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
@ -524,9 +525,9 @@ isometry_from_composition_impl_all!(
// Isometry ÷ UnitComplex // Isometry ÷ UnitComplex
isometry_from_composition_impl_all!( isometry_from_composition_impl_all!(
Div, div; Div, div;
(U2, U1), (U2, U1); ;
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>, self: Isometry<N, UnitComplex<N>, 2>, rhs: UnitComplex<N>,
Output = Isometry<N, U2, UnitComplex<N>>; Output = Isometry<N, UnitComplex<N>, 2>;
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs); [val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone. [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone.
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);

View File

@ -9,7 +9,6 @@ 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>,
{ {
type Element = Isometry<N::Element, R::Element, D>; type Element = Isometry<N::Element, R::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -7,21 +7,25 @@ macro_rules! md_impl(
// Operator, operator method, and scalar bounds. // Operator, operator method, and scalar bounds.
$Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)*; $Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)*;
// Storage dimensions, and dimension bounds. // Storage dimensions, and dimension bounds.
($R1: ty, $C1: ty),($R2: ty, $C2: ty) for $($Dims: ident: $DimsBound: ident $(<$($BoundParam: ty),*>)*),+ ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
// [Optional] Extra allocator bounds. // Const type declaration
$(where $ConstraintType: ty: $ConstraintBound: ident<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*> )*; const $($D: ident),*;
// Other generic type declarations.
for $($DimsDecl: ident),*;
// Where clause.
where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
// Argument identifiers and types + output. // Argument identifiers and types + output.
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
// Operator actual implementation. // Operator actual implementation.
$action: expr; $action: expr;
// Lifetime. // Lifetime.
$($lives: tt),*) => { $($lives: tt),*) => {
impl<$($lives ,)* N $(, $Dims: $DimsBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N $(, $DimsDecl)* $(, const $D: usize)*> $Op<$Rhs> for $Lhs
where N: Scalar + Zero + One + ClosedAdd + ClosedMul $($(+ $ScalarBounds)*)*, where N: Scalar + Zero + One + ClosedAdd + ClosedMul $($(+ $ScalarBounds)*)*,
DefaultAllocator: Allocator<N, $R1, $C1> + DefaultAllocator: Allocator<N, $R1, $C1> +
Allocator<N, $R2, $C2> + Allocator<N, $R2, $C2> +
Allocator<N, $R1, $C2>, Allocator<N, $R1, $C2>,
$( $ConstraintType: $ConstraintBound<$( $ConstraintBoundParams $( = $EqBound )*),*> ),* $( $ConstraintType: $ConstraintBound$(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),*
{ {
type Output = $Result; type Output = $Result;
@ -40,9 +44,13 @@ macro_rules! md_impl_all(
// Operator, operator method, and scalar bounds. // Operator, operator method, and scalar bounds.
$Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)*; $Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)*;
// Storage dimensions, and dimension bounds. // Storage dimensions, and dimension bounds.
($R1: ty, $C1: ty),($R2: ty, $C2: ty) for $($Dims: ident: $DimsBound: ident $(<$($BoundParam: ty),*>)*),+ ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
// [Optional] Extra allocator bounds. // Const type declaration
$(where $ConstraintType: ty: $ConstraintBound: ident<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*> )*; const $($D: ident),*;
// Other generic type declarations.
for $($DimsDecl: ident),*;
// Where clause.
where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
// Argument identifiers and types + output. // Argument identifiers and types + output.
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
// Operators actual implementations. // Operators actual implementations.
@ -53,29 +61,37 @@ macro_rules! md_impl_all(
md_impl!( md_impl!(
$Op, $op $(where N: $($ScalarBounds),*)*; $Op, $op $(where N: $($ScalarBounds),*)*;
($R1, $C1),($R2, $C2) for $($Dims: $DimsBound $(<$($BoundParam),*>)*),+ ($R1, $C1),($R2, $C2)
$(where $ConstraintType: $ConstraintBound<$($ConstraintBoundParams $( = $EqBound )*),*>)*; const $($D),*;
for $($DimsDecl),*;
where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
$lhs: $Lhs, $rhs: $Rhs, Output = $Result; $lhs: $Lhs, $rhs: $Rhs, Output = $Result;
$action_val_val; ); $action_val_val; );
md_impl!( md_impl!(
$Op, $op $(where N: $($ScalarBounds),*)*; $Op, $op $(where N: $($ScalarBounds),*)*;
($R1, $C1),($R2, $C2) for $($Dims: $DimsBound $(<$($BoundParam),*>)*),+ ($R1, $C1),($R2, $C2)
$(where $ConstraintType: $ConstraintBound<$($ConstraintBoundParams $( = $EqBound )*),*>)*; const $($D),*;
for $($DimsDecl),*;
where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result; $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result;
$action_ref_val; 'a); $action_ref_val; 'a);
md_impl!( md_impl!(
$Op, $op $(where N: $($ScalarBounds),*)*; $Op, $op $(where N: $($ScalarBounds),*)*;
($R1, $C1),($R2, $C2) for $($Dims: $DimsBound $(<$($BoundParam),*>)*),+ ($R1, $C1),($R2, $C2)
$(where $ConstraintType: $ConstraintBound<$($ConstraintBoundParams $( = $EqBound )*),*>)*; const $($D),*;
for $($DimsDecl),*;
where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result; $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result;
$action_val_ref; 'b); $action_val_ref; 'b);
md_impl!( md_impl!(
$Op, $op $(where N: $($ScalarBounds),*)*; $Op, $op $(where N: $($ScalarBounds),*)*;
($R1, $C1),($R2, $C2) for $($Dims: $DimsBound $(<$($BoundParam),*>)*),+ ($R1, $C1),($R2, $C2)
$(where $ConstraintType: $ConstraintBound<$($ConstraintBoundParams $( = $EqBound )*),*>)*; const $($D),*;
for $($DimsDecl),*;
where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result; $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result;
$action_ref_ref; 'a, 'b); $action_ref_ref; 'a, 'b);
} }
@ -85,18 +101,22 @@ macro_rules! md_impl_all(
macro_rules! md_assign_impl( macro_rules! md_assign_impl(
( (
// Operator, operator method, and scalar bounds. // Operator, operator method, and scalar bounds.
$Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)* $(for N::Element: $ElementBounds: ident)*; $Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)* $(for N::Element: $($ElementBounds: ident),*)*;
// Storage dimensions, and dimension bounds. // Storage dimensions, and dimension bounds.
($R1: ty, $C1: ty),($R2: ty, $C2: ty) for $($Dims: ident: $DimsBound: ident $(<$($BoundParam: ty),*>)*),* ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
// [Optional] Extra allocator bounds. // Const type declaration
$(where $ConstraintType: ty: $ConstraintBound: ident $(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)* )*; const $($D: ident),*;
// Other generic type declarations.
for $($DimsDecl: ident),*;
// Where clause.
where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
// Argument identifiers and types. // Argument identifiers and types.
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
// Actual implementation and lifetimes. // Actual implementation and lifetimes.
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N $(, $Dims: $DimsBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N $(, $DimsDecl)* $(, const $D: usize)*> $Op<$Rhs> for $Lhs
where N: Scalar + Zero + One + ClosedAdd + ClosedMul $($(+ $ScalarBounds)*)*, where N: Scalar + Zero + One + ClosedAdd + ClosedMul $($(+ $ScalarBounds)*)*,
$(N::Element: $ElementBounds,)* $($(N::Element: $ElementBounds,)*)*
DefaultAllocator: Allocator<N, $R1, $C1> + DefaultAllocator: Allocator<N, $R1, $C1> +
Allocator<N, $R2, $C2>, Allocator<N, $R2, $C2>,
$( $ConstraintType: $ConstraintBound $(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),* $( $ConstraintType: $ConstraintBound $(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),*
@ -116,9 +136,13 @@ macro_rules! md_assign_impl_all(
// Operator, operator method, and scalar bounds. // Operator, operator method, and scalar bounds.
$Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)* $(for N::Element: $($ElementBounds: ident),*)*; $Op: ident, $op: ident $(where N: $($ScalarBounds: ident),*)* $(for N::Element: $($ElementBounds: ident),*)*;
// Storage dimensions, and dimension bounds. // Storage dimensions, and dimension bounds.
($R1: ty, $C1: ty),($R2: ty, $C2: ty) for $($Dims: ident: $DimsBound: ident $(<$($BoundParam: ty),*>)*),* ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
// [Optional] Extra allocator bounds. // Const type declaration
$(where $ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)* )*; const $($D: ident),*;
// Other generic type declarations.
for $($DimsDecl: ident),*;
// Where clause.
where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
// Argument identifiers and types. // Argument identifiers and types.
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
// Actual implementation and lifetimes. // Actual implementation and lifetimes.
@ -126,15 +150,19 @@ macro_rules! md_assign_impl_all(
[ref] => $action_ref: expr;) => { [ref] => $action_ref: expr;) => {
md_assign_impl!( md_assign_impl!(
$Op, $op $(where N: $($ScalarBounds),*)* $(for N::Element: $($ElementBounds),*)*; $Op, $op $(where N: $($ScalarBounds),*)* $(for N::Element: $($ElementBounds),*)*;
($R1, $C1),($R2, $C2) for $($Dims: $DimsBound $(<$($BoundParam),*>)*),* ($R1, $C1),($R2, $C2)
$(where $ConstraintType: $ConstraintBound $(<$($ConstraintBoundParams $( = $EqBound )*),*>)*)*; const $($D),*;
for $($DimsDecl),*;
where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
$lhs: $Lhs, $rhs: $Rhs; $lhs: $Lhs, $rhs: $Rhs;
$action_val; ); $action_val; );
md_assign_impl!( md_assign_impl!(
$Op, $op $(where N: $($ScalarBounds),*)* $(for N::Element: $($ElementBounds),*)*; $Op, $op $(where N: $($ScalarBounds),*)* $(for N::Element: $($ElementBounds),*)*;
($R1, $C1),($R2, $C2) for $($Dims: $DimsBound $(<$($BoundParam),*>)*),* ($R1, $C1),($R2, $C2)
$(where $ConstraintType: $ConstraintBound $(<$($ConstraintBoundParams $( = $EqBound )*),*>)*)*; const $($D),*;
for $($DimsDecl),*;
where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
$lhs: $Lhs, $rhs: &'b $Rhs; $lhs: $Lhs, $rhs: &'b $Rhs;
$action_ref; 'b); $action_ref; 'b);
} }
@ -144,16 +172,23 @@ macro_rules! md_assign_impl_all(
/// Macro for the implementation of addition and subtraction. /// Macro for the implementation of addition and subtraction.
macro_rules! add_sub_impl( macro_rules! add_sub_impl(
($Op: ident, $op: ident, $bound: ident; ($Op: ident, $op: ident, $bound: ident;
($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(-> ($RRes: ty))* for $($Dims: ident: $DimsBound: ident $(<$($BoundParam: ty),*>)*),+; ($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(-> ($RRes: ty))*
// Const type declaration
const $($D: ident),*;
// Other generic type declarations.
for $($DimsDecl: ident),*;
// Where clause.
where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N $(, $Dims: $DimsBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N $(, $DimsDecl)* $(, const $D: usize)*> $Op<$Rhs> for $Lhs
where N: Scalar + $bound, where N: Scalar + $bound,
DefaultAllocator: Allocator<N, $R1, $C1> + DefaultAllocator: Allocator<N, $R1, $C1> +
Allocator<N, $R2, $C2> + Allocator<N, $R2, $C2> +
SameShapeAllocator<N, $R1, $C1, $R2, $C2>, SameShapeAllocator<N, $R1, $C1, $R2, $C2>,
ShapeConstraint: SameNumberOfRows<$R1, $R2 $(, Representative = $RRes)*> + ShapeConstraint: SameNumberOfRows<$R1, $R2 $(, Representative = $RRes)*> +
SameNumberOfColumns<$C1, $C2> { SameNumberOfColumns<$C1, $C2>,
$( $ConstraintType: $ConstraintBound$(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),* {
type Output = $Result; type Output = $Result;
#[inline] #[inline]
@ -168,14 +203,11 @@ macro_rules! add_sub_impl(
/// Macro for the implementation of assignment-addition and assignment-subtraction. /// Macro for the implementation of assignment-addition and assignment-subtraction.
macro_rules! add_sub_assign_impl( macro_rules! add_sub_assign_impl(
($Op: ident, $op: ident, $bound: ident; ($Op: ident, $op: ident, $bound: ident;
($R1: ty, $C1: ty),($R2: ty, $C2: ty) for $($Dims: ident: $DimsBound: ident),+; $(const $D: ident),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N $(, $Dims: $DimsBound)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N $(, const $D: usize),*> $Op<$Rhs> for $Lhs
where N: Scalar + $bound, where N: Scalar + $bound {
DefaultAllocator: Allocator<N, $R1, $C1> +
Allocator<N, $R2, $C2>,
ShapeConstraint: SameNumberOfRows<$R1, $R2> + SameNumberOfColumns<$C1, $C2> {
#[inline] #[inline]
fn $op(&mut $lhs, $rhs: $Rhs) { fn $op(&mut $lhs, $rhs: $Rhs) {
$action $action

View File

@ -17,7 +17,7 @@ use simba::simd::SimdPartialOrd;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::{Const, DefaultAllocator, Scalar, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, Scalar, VectorN};
/// A point in an euclidean space. /// A point in an euclidean space.
/// ///
@ -64,7 +64,7 @@ impl<N: Scalar + Copy, const D: usize> Copy for Point<N, D>
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<N: Scalar, const D: usize> bytemuck::Zeroable for Point<N, D> where unsafe impl<N: Scalar, const D: usize> bytemuck::Zeroable for Point<N, D> where
VectorN<N, Const<D>>: bytemuck::Zeroable // DefaultAllocator: Allocator<N, D>, VectorN<N, Const<D>>: bytemuck::Zeroable
{ {
} }
@ -73,17 +73,11 @@ unsafe impl<N: Scalar, const D: usize> bytemuck::Pod for Point<N, D>
where where
N: Copy, N: Copy,
VectorN<N, Const<D>>: bytemuck::Pod, VectorN<N, Const<D>>: bytemuck::Pod,
// DefaultAllocator: Allocator<N, D>,
// <DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
{ {
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: Scalar, const D: usize> Serialize for Point<N, D> impl<N: Scalar + Serialize, const D: usize> Serialize for Point<N, D> {
// where
// DefaultAllocator: Allocator<N, D>,
// <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
S: Serializer, S: Serializer,
@ -93,16 +87,12 @@ impl<N: Scalar, const D: usize> Serialize for Point<N, D>
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Point<N, D> impl<'a, N: Scalar + Deserialize<'a>, const D: usize> Deserialize<'a> for Point<N, D> {
// where
// DefaultAllocator: Allocator<N, D>,
// <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
Des: Deserializer<'a>, Des: Deserializer<'a>,
{ {
let coords = VectorN::<N, D>::deserialize(deserializer)?; let coords = CVectorN::<N, D>::deserialize(deserializer)?;
Ok(Self::from(coords)) Ok(Self::from(coords))
} }
@ -113,7 +103,6 @@ impl<N, const D: usize> Abomonation for Point<N, D>
where where
N: Scalar, N: Scalar,
VectorN<N, Const<D>>: Abomonation, VectorN<N, Const<D>>: Abomonation,
// 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)
@ -312,7 +301,6 @@ impl<N: Scalar, const D: usize> Point<N, D>
impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Point<N, D> impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Point<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -330,7 +318,6 @@ where
impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Point<N, D> impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Point<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -352,7 +339,6 @@ where
impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Point<N, D> impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Point<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]

View File

@ -10,10 +10,10 @@ use rand::{
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, Scalar, VectorN}; use crate::base::{CVectorN, DefaultAllocator, Scalar};
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,
Vector5, Vector6, Vector5, Vector6, VectorN,
}; };
use simba::scalar::{ClosedDiv, SupersetOf}; use simba::scalar::{ClosedDiv, SupersetOf};
@ -52,7 +52,7 @@ impl<N: Scalar, const D: usize> Point<N, D>
where where
N: Zero, N: Zero,
{ {
Self::from(VectorN::from_element(N::zero())) Self::from(CVectorN::from_element(N::zero()))
} }
/// Creates a new point from a slice. /// Creates a new point from a slice.
@ -71,7 +71,7 @@ impl<N: Scalar, const D: usize> Point<N, D>
/// ``` /// ```
#[inline] #[inline]
pub fn from_slice(components: &[N]) -> Self { pub fn from_slice(components: &[N]) -> Self {
Self::from(VectorN::from_row_slice(components)) Self::from(CVectorN::from_row_slice(components))
} }
/// Creates a new point from its homogeneous vector representation. /// Creates a new point from its homogeneous vector representation.
@ -131,7 +131,6 @@ impl<N: Scalar, const D: usize> Point<N, D>
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>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -148,37 +147,35 @@ impl<N: Scalar + Bounded, const D: usize> Bounded for Point<N, D>
{ {
#[inline] #[inline]
fn max_value() -> Self { fn max_value() -> Self {
Self::from(VectorN::max_value()) Self::from(CVectorN::max_value())
} }
#[inline] #[inline]
fn min_value() -> Self { fn min_value() -> Self {
Self::from(VectorN::min_value()) Self::from(CVectorN::min_value())
} }
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: Scalar, const D: usize> Distribution<Point<N, D>> for Standard impl<N: Scalar, const D: usize> Distribution<Point<N, D>> for Standard
where where
// 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)`.
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Point<N, D> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Point<N, D> {
Point::from(rng.gen::<VectorN<N, D>>()) Point::from(rng.gen::<CVectorN<N, D>>())
} }
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: Scalar + Arbitrary + Send, const D: usize> 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 as Allocator<N, Const<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 {
Self::from(VectorN::arbitrary(g)) Self::from(CVectorN::arbitrary(g))
} }
} }

View File

@ -20,7 +20,6 @@ impl<N1, N2, const D: usize> SubsetOf<Point<N2, D>> for Point<N1, D>
where where
N1: Scalar, N1: Scalar,
N2: Scalar + SupersetOf<N1>, N2: Scalar + SupersetOf<N1>,
// DefaultAllocator: Allocator<N2, D> + Allocator<N1, D>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Point<N2, D> { fn to_superset(&self) -> Point<N2, D> {
@ -58,12 +57,12 @@ where
#[inline] #[inline]
fn is_in_subset(v: &VectorN<N2, DimNameSum<Const<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].is_zero() crate::is_convertible::<_, VectorN<N1, DimNameSum<Const<D>, U1>>>(v) && !v[D].is_zero()
} }
#[inline] #[inline]
fn from_superset_unchecked(v: &VectorN<N2, DimNameSum<Const<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].inlined_clone(); let coords = v.fixed_slice::<Const<D>, U1>(0, 0) / v[D].inlined_clone();
Self { Self {
coords: crate::convert_unchecked(coords), coords: crate::convert_unchecked(coords),
} }
@ -97,7 +96,6 @@ impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Eleme
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 as Allocator<N::Element, Const<D>>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
@ -111,7 +109,6 @@ impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Eleme
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 as Allocator<N::Element, Const<D>>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
@ -130,7 +127,6 @@ impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Eleme
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 as Allocator<N::Element, Const<D>>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]
@ -153,7 +149,6 @@ impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Eleme
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 as Allocator<N::Element, Const<D>>>::Buffer: Copy, <DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
{ {
#[inline] #[inline]

View File

@ -9,7 +9,7 @@ use crate::base::allocator::{Allocator, SameShapeAllocator};
use crate::base::constraint::{ use crate::base::constraint::{
AreMultipliable, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, AreMultipliable, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
}; };
use crate::base::dimension::{Dim, DimName, U1}; use crate::base::dimension::{Dim, U1};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{Const, DefaultAllocator, Matrix, Scalar, Vector, VectorSum}; use crate::base::{Const, DefaultAllocator, Matrix, Scalar, Vector, VectorSum};
@ -79,74 +79,101 @@ impl<'a, N: Scalar + ClosedNeg, const D: usize> Neg for &'a Point<N, D>
// Point - Point // Point - Point
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D, U1), (D, U1); (Const<D>, U1), (Const<D>, U1)
self: &'a Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>; const D; for; where;
self: &'a Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, Const<D>, Const<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); (Const<D>, U1), (Const<D>, U1)
self: &'a Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>; const D; for; where;
self: &'a Point<N, D>, right: Point<N, D>, Output = VectorSum<N, Const<D>, Const<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); (Const<D>, U1), (Const<D>, U1)
self: Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>; const D; for; where;
self: Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, Const<D>, Const<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); (Const<D>, U1), (Const<D>, U1)
self: Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>; const D; for; where;
self: Point<N, D>, right: Point<N, D>, Output = VectorSum<N, Const<D>, Const<D>>;
self.coords - right.coords; ); self.coords - right.coords; );
// Point - Vector // Point - Vector
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: &'a Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>; self: &'a Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(&self.coords - right); 'a, 'b); Self::Output::from(&self.coords - right); 'a, 'b);
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: &'a Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>; self: &'a Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(&self.coords - &right); 'a); // TODO: should not be a ref to `right`. Self::Output::from(&self.coords - &right); 'a); // TODO: should not be a ref to `right`.
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>; self: Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(self.coords - right); 'b); Self::Output::from(self.coords - right); 'b);
add_sub_impl!(Sub, sub, ClosedSub; add_sub_impl!(Sub, sub, ClosedSub;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>; self: Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(self.coords - right); ); Self::Output::from(self.coords - right); );
// Point + Vector // Point + Vector
add_sub_impl!(Add, add, ClosedAdd; add_sub_impl!(Add, add, ClosedAdd;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: &'a Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>; self: &'a Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(&self.coords + right); 'a, 'b); Self::Output::from(&self.coords + right); 'a, 'b);
add_sub_impl!(Add, add, ClosedAdd; add_sub_impl!(Add, add, ClosedAdd;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: &'a Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>; self: &'a Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(&self.coords + &right); 'a); // TODO: should not be a ref to `right`. Self::Output::from(&self.coords + &right); 'a); // TODO: should not be a ref to `right`.
add_sub_impl!(Add, add, ClosedAdd; add_sub_impl!(Add, add, ClosedAdd;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>; self: Point<N, D1>, right: &'b Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(self.coords + right); 'b); Self::Output::from(self.coords + right); 'b);
add_sub_impl!(Add, add, ClosedAdd; add_sub_impl!(Add, add, ClosedAdd;
(D1, U1), (D2, U1) -> (D1) for D1: DimName, D2: Dim, SB: Storage<N, D2>; (Const<D1>, U1), (D2, U1) -> (Const<D1>)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<N, D2>;
self: Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>; self: Point<N, D1>, right: Vector<N, D2, SB>, Output = Point<N, D1>;
Self::Output::from(self.coords + right); ); Self::Output::from(self.coords + right); );
// XXX: replace by the shared macro: add_sub_assign_impl // TODO: 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, D2: Dim, SB, const D1: usize> $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>,
ShapeConstraint: SameNumberOfRows<Const<D1>, D2> { ShapeConstraint: SameNumberOfRows<Const<D1>, D2> {
#[inline] #[inline]
@ -158,8 +185,7 @@ macro_rules! op_assign_impl(
impl<N, D2: Dim, SB, const D1: usize> $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>, ShapeConstraint: SameNumberOfRows<Const<D1>, D2> {
ShapeConstraint: SameNumberOfRows<D1, D2> {
#[inline] #[inline]
fn $method_assign(&mut self, right: Vector<N, D2, SB>) { fn $method_assign(&mut self, right: Vector<N, D2, SB>) {
@ -181,9 +207,12 @@ op_assign_impl!(
*/ */
md_impl_all!( md_impl_all!(
Mul, mul; Mul, mul;
(R1, C1), (D2, U1) for R1: DimName, C1: Dim, D2: DimName, SA: Storage<N, R1, C1> (Const<R1>, Const<C1>), (Const<D2>, U1)
where ShapeConstraint: AreMultipliable<R1, C1, D2, U1>; const D2, R1, C1;
self: Matrix<N, R1, C1, SA>, right: Point<N, D2>, Output = Point<N, R1>; for SA;
where SA: Storage<N, Const<R1>, Const<C1>>,
ShapeConstraint: AreMultipliable<Const<R1>, Const<C1>, Const<D2>, U1>;
self: Matrix<N, Const<R1>, Const<C1>, SA>, right: Point<N, D2>, Output = Point<N, R1>;
[val val] => Point::from(self * right.coords); [val val] => Point::from(self * right.coords);
[ref val] => Point::from(self * right.coords); [ref val] => Point::from(self * right.coords);
[val ref] => Point::from(self * &right.coords); [val ref] => Point::from(self * &right.coords);

View File

@ -7,7 +7,6 @@ use crate::geometry::Point;
impl<N: Scalar + SimdValue, const D: usize> 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>,
{ {
type Element = Point<N::Element, D>; type Element = Point<N::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -54,10 +54,9 @@ use std::ops::{
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign, Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
}; };
use crate::base::allocator::Allocator; use crate::base::dimension::U3;
use crate::base::dimension::{U1, U3, U4};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Scalar, Unit, Vector, Vector3}; use crate::base::{Const, Scalar, Unit, Vector, Vector3};
use crate::SimdRealField; use crate::SimdRealField;
use crate::geometry::{Point3, Quaternion, Rotation, UnitQuaternion}; use crate::geometry::{Point3, Quaternion, Rotation, UnitQuaternion};
@ -80,14 +79,11 @@ impl<N: Scalar> IndexMut<usize> for Quaternion<N> {
macro_rules! quaternion_op_impl( macro_rules! quaternion_op_impl(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($LhsRDim: ident, $LhsCDim: ident), ($RhsRDim: ident, $RhsCDim: ident) $($Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*;
$(for $Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty $(=> $VDimA: ty, $VDimB: ty)*;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField $(, $Storage: $StoragesBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField $(, $Storage: $StoragesBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField {
DefaultAllocator: Allocator<N, $LhsRDim, $LhsCDim> +
Allocator<N, $RhsRDim, $RhsCDim> {
type Output = $Result; type Output = $Result;
#[inline] #[inline]
@ -101,63 +97,63 @@ macro_rules! quaternion_op_impl(
// Quaternion + Quaternion // Quaternion + Quaternion
quaternion_op_impl!( quaternion_op_impl!(
Add, add; Add, add;
(U4, U1), (U4, U1); ;
self: &'a Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>; self: &'a Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(&self.coords + &rhs.coords); Quaternion::from(&self.coords + &rhs.coords);
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Add, add; Add, add;
(U4, U1), (U4, U1); ;
self: &'a Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>; self: &'a Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(&self.coords + rhs.coords); Quaternion::from(&self.coords + rhs.coords);
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Add, add; Add, add;
(U4, U1), (U4, U1); ;
self: Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>; self: Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(self.coords + &rhs.coords); Quaternion::from(self.coords + &rhs.coords);
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Add, add; Add, add;
(U4, U1), (U4, U1); ;
self: Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>; self: Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(self.coords + rhs.coords); ); Quaternion::from(self.coords + rhs.coords); );
// Quaternion - Quaternion // Quaternion - Quaternion
quaternion_op_impl!( quaternion_op_impl!(
Sub, sub; Sub, sub;
(U4, U1), (U4, U1); ;
self: &'a Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>; self: &'a Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(&self.coords - &rhs.coords); Quaternion::from(&self.coords - &rhs.coords);
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Sub, sub; Sub, sub;
(U4, U1), (U4, U1); ;
self: &'a Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>; self: &'a Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(&self.coords - rhs.coords); Quaternion::from(&self.coords - rhs.coords);
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Sub, sub; Sub, sub;
(U4, U1), (U4, U1); ;
self: Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>; self: Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(self.coords - &rhs.coords); Quaternion::from(self.coords - &rhs.coords);
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Sub, sub; Sub, sub;
(U4, U1), (U4, U1); ;
self: Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>; self: Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>;
Quaternion::from(self.coords - rhs.coords); ); Quaternion::from(self.coords - rhs.coords); );
// Quaternion × Quaternion // Quaternion × Quaternion
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: &'a Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>; self: &'a Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>;
Quaternion::new( Quaternion::new(
self[3] * rhs[3] - self[0] * rhs[0] - self[1] * rhs[1] - self[2] * rhs[2], self[3] * rhs[3] - self[0] * rhs[0] - self[1] * rhs[1] - self[2] * rhs[2],
@ -168,218 +164,218 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: &'a Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>; self: &'a Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>;
self * &rhs; self * &rhs;
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>; self: Quaternion<N>, rhs: &'b Quaternion<N>, Output = Quaternion<N>;
&self * rhs; &self * rhs;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>; self: Quaternion<N>, rhs: Quaternion<N>, Output = Quaternion<N>;
&self * &rhs; ); &self * &rhs; );
// UnitQuaternion × UnitQuaternion // UnitQuaternion × UnitQuaternion
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: &'a UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>; self: &'a UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>;
UnitQuaternion::new_unchecked(self.quaternion() * rhs.quaternion()); UnitQuaternion::new_unchecked(self.quaternion() * rhs.quaternion());
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: &'a UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>; self: &'a UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>;
self * &rhs; self * &rhs;
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>;
&self * rhs; &self * rhs;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U4, U1); ;
self: UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>;
&self * &rhs; ); &self * &rhs; );
// UnitQuaternion ÷ UnitQuaternion // UnitQuaternion ÷ UnitQuaternion
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U4, U1); ;
self: &'a UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>; self: &'a UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>;
#[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() }; #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U4, U1); ;
self: &'a UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>; self: &'a UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>;
self / &rhs; self / &rhs;
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U4, U1); ;
self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>, Output = UnitQuaternion<N>;
&self / rhs; &self / rhs;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U4, U1); ;
self: UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: UnitQuaternion<N>, Output = UnitQuaternion<N>;
&self / &rhs; ); &self / &rhs; );
// UnitQuaternion × Rotation // UnitQuaternion × Rotation
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U3); ;
self: &'a UnitQuaternion<N>, rhs: &'b Rotation<N, U3>, self: &'a UnitQuaternion<N>, rhs: &'b Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
// TODO: can we avoid the conversion from a rotation matrix? // TODO: can we avoid the conversion from a rotation matrix?
self * UnitQuaternion::<N>::from_rotation_matrix(rhs); self * UnitQuaternion::<N>::from_rotation_matrix(rhs);
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U3); ;
self: &'a UnitQuaternion<N>, rhs: Rotation<N, U3>, self: &'a UnitQuaternion<N>, rhs: Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
self * UnitQuaternion::<N>::from_rotation_matrix(&rhs); self * UnitQuaternion::<N>::from_rotation_matrix(&rhs);
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U3); ;
self: UnitQuaternion<N>, rhs: &'b Rotation<N, U3>, self: UnitQuaternion<N>, rhs: &'b Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
self * UnitQuaternion::<N>::from_rotation_matrix(rhs); self * UnitQuaternion::<N>::from_rotation_matrix(rhs);
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U3); ;
self: UnitQuaternion<N>, rhs: Rotation<N, U3>, self: UnitQuaternion<N>, rhs: Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
self * UnitQuaternion::<N>::from_rotation_matrix(&rhs); ); self * UnitQuaternion::<N>::from_rotation_matrix(&rhs); );
// UnitQuaternion ÷ Rotation // UnitQuaternion ÷ Rotation
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U3, U3); ;
self: &'a UnitQuaternion<N>, rhs: &'b Rotation<N, U3>, self: &'a UnitQuaternion<N>, rhs: &'b Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
// TODO: can we avoid the conversion to a rotation matrix? // TODO: can we avoid the conversion to a rotation matrix?
self / UnitQuaternion::<N>::from_rotation_matrix(rhs); self / UnitQuaternion::<N>::from_rotation_matrix(rhs);
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U3, U3); ;
self: &'a UnitQuaternion<N>, rhs: Rotation<N, U3>, self: &'a UnitQuaternion<N>, rhs: Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
self / UnitQuaternion::<N>::from_rotation_matrix(&rhs); self / UnitQuaternion::<N>::from_rotation_matrix(&rhs);
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U3, U3); ;
self: UnitQuaternion<N>, rhs: &'b Rotation<N, U3>, self: UnitQuaternion<N>, rhs: &'b Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
self / UnitQuaternion::<N>::from_rotation_matrix(rhs); self / UnitQuaternion::<N>::from_rotation_matrix(rhs);
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U4, U1), (U3, U3); ;
self: UnitQuaternion<N>, rhs: Rotation<N, U3>, self: UnitQuaternion<N>, rhs: Rotation<N, 3>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
self / UnitQuaternion::<N>::from_rotation_matrix(&rhs); ); self / UnitQuaternion::<N>::from_rotation_matrix(&rhs); );
// Rotation × UnitQuaternion // Rotation × UnitQuaternion
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U3, U3), (U4, U1); ;
self: &'a Rotation<N, U3>, rhs: &'b UnitQuaternion<N>, self: &'a Rotation<N, 3>, rhs: &'b UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
// TODO: can we avoid the conversion from a rotation matrix? // TODO: can we avoid the conversion from a rotation matrix?
UnitQuaternion::<N>::from_rotation_matrix(self) * rhs; UnitQuaternion::<N>::from_rotation_matrix(self) * rhs;
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U3, U3), (U4, U1); ;
self: &'a Rotation<N, U3>, rhs: UnitQuaternion<N>, self: &'a Rotation<N, 3>, rhs: UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
UnitQuaternion::<N>::from_rotation_matrix(self) * rhs; UnitQuaternion::<N>::from_rotation_matrix(self) * rhs;
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U3, U3), (U4, U1); ;
self: Rotation<N, U3>, rhs: &'b UnitQuaternion<N>, self: Rotation<N, 3>, rhs: &'b UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
UnitQuaternion::<N>::from_rotation_matrix(&self) * rhs; UnitQuaternion::<N>::from_rotation_matrix(&self) * rhs;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U3, U3), (U4, U1); ;
self: Rotation<N, U3>, rhs: UnitQuaternion<N>, self: Rotation<N, 3>, rhs: UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
UnitQuaternion::<N>::from_rotation_matrix(&self) * rhs; ); UnitQuaternion::<N>::from_rotation_matrix(&self) * rhs; );
// Rotation ÷ UnitQuaternion // Rotation ÷ UnitQuaternion
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U3, U3), (U4, U1); ;
self: &'a Rotation<N, U3>, rhs: &'b UnitQuaternion<N>, self: &'a Rotation<N, 3>, rhs: &'b UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
// TODO: can we avoid the conversion from a rotation matrix? // TODO: can we avoid the conversion from a rotation matrix?
UnitQuaternion::<N>::from_rotation_matrix(self) / rhs; UnitQuaternion::<N>::from_rotation_matrix(self) / rhs;
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U3, U3), (U4, U1); ;
self: &'a Rotation<N, U3>, rhs: UnitQuaternion<N>, self: &'a Rotation<N, 3>, rhs: UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
UnitQuaternion::<N>::from_rotation_matrix(self) / rhs; UnitQuaternion::<N>::from_rotation_matrix(self) / rhs;
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U3, U3), (U4, U1); ;
self: Rotation<N, U3>, rhs: &'b UnitQuaternion<N>, self: Rotation<N, 3>, rhs: &'b UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
UnitQuaternion::<N>::from_rotation_matrix(&self) / rhs; UnitQuaternion::<N>::from_rotation_matrix(&self) / rhs;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Div, div; Div, div;
(U3, U3), (U4, U1); ;
self: Rotation<N, U3>, rhs: UnitQuaternion<N>, self: Rotation<N, 3>, rhs: UnitQuaternion<N>,
Output = UnitQuaternion<N> => U3, U3; Output = UnitQuaternion<N>;
UnitQuaternion::<N>::from_rotation_matrix(&self) / rhs; ); UnitQuaternion::<N>::from_rotation_matrix(&self) / rhs; );
// UnitQuaternion × Vector // UnitQuaternion × Vector
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: &'a UnitQuaternion<N>, rhs: &'b Vector<N, U3, SB>, self: &'a UnitQuaternion<N>, rhs: &'b Vector<N, Const<3>, SB>,
Output = Vector3<N> => U3, U4; Output = Vector3<N>;
{ {
let two: N = crate::convert(2.0f64); let two: N = crate::convert(2.0f64);
let t = self.as_ref().vector().cross(rhs) * two; let t = self.as_ref().vector().cross(rhs) * two;
@ -391,89 +387,89 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: &'a UnitQuaternion<N>, rhs: Vector<N, U3, SB>, self: &'a UnitQuaternion<N>, rhs: Vector<N, U3, SB>,
Output = Vector3<N> => U3, U4; Output = Vector3<N>;
self * &rhs; self * &rhs;
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: UnitQuaternion<N>, rhs: &'b Vector<N, U3, SB>, self: UnitQuaternion<N>, rhs: &'b Vector<N, U3, SB>,
Output = Vector3<N> => U3, U4; Output = Vector3<N>;
&self * rhs; &self * rhs;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: UnitQuaternion<N>, rhs: Vector<N, U3, SB>, self: UnitQuaternion<N>, rhs: Vector<N, U3, SB>,
Output = Vector3<N> => U3, U4; Output = Vector3<N>;
&self * &rhs; ); &self * &rhs; );
// UnitQuaternion × Point // UnitQuaternion × Point
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: &'a UnitQuaternion<N>, rhs: &'b Point3<N>, self: &'a UnitQuaternion<N>, rhs: &'b Point3<N>,
Output = Point3<N> => U3, U4; Output = Point3<N>;
Point3::from(self * &rhs.coords); Point3::from(self * &rhs.coords);
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: &'a UnitQuaternion<N>, rhs: Point3<N>, self: &'a UnitQuaternion<N>, rhs: Point3<N>,
Output = Point3<N> => U3, U4; Output = Point3<N>;
Point3::from(self * rhs.coords); Point3::from(self * rhs.coords);
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, rhs: &'b Point3<N>, self: UnitQuaternion<N>, rhs: &'b Point3<N>,
Output = Point3<N> => U3, U4; Output = Point3<N>;
Point3::from(self * &rhs.coords); Point3::from(self * &rhs.coords);
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, rhs: Point3<N>, self: UnitQuaternion<N>, rhs: Point3<N>,
Output = Point3<N> => U3, U4; Output = Point3<N>;
Point3::from(self * rhs.coords); ); Point3::from(self * rhs.coords); );
// UnitQuaternion × Unit<Vector> // UnitQuaternion × Unit<Vector>
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: &'a UnitQuaternion<N>, rhs: &'b Unit<Vector<N, U3, SB>>, self: &'a UnitQuaternion<N>, rhs: &'b Unit<Vector<N, U3, SB>>,
Output = Unit<Vector3<N>> => U3, U4; Output = Unit<Vector3<N>>;
Unit::new_unchecked(self * rhs.as_ref()); Unit::new_unchecked(self * rhs.as_ref());
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: &'a UnitQuaternion<N>, rhs: Unit<Vector<N, U3, SB>>, self: &'a UnitQuaternion<N>, rhs: Unit<Vector<N, U3, SB>>,
Output = Unit<Vector3<N>> => U3, U4; Output = Unit<Vector3<N>>;
Unit::new_unchecked(self * rhs.into_inner()); Unit::new_unchecked(self * rhs.into_inner());
'a); 'a);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: UnitQuaternion<N>, rhs: &'b Unit<Vector<N, U3, SB>>, self: UnitQuaternion<N>, rhs: &'b Unit<Vector<N, U3, SB>>,
Output = Unit<Vector3<N>> => U3, U4; Output = Unit<Vector3<N>>;
Unit::new_unchecked(self * rhs.as_ref()); Unit::new_unchecked(self * rhs.as_ref());
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1) for SB: Storage<N, U3> ; SB: Storage<N, Const<3>> ;
self: UnitQuaternion<N>, rhs: Unit<Vector<N, U3, SB>>, self: UnitQuaternion<N>, rhs: Unit<Vector<N, U3, SB>>,
Output = Unit<Vector3<N>> => U3, U4; Output = Unit<Vector3<N>>;
Unit::new_unchecked(self * rhs.into_inner()); ); Unit::new_unchecked(self * rhs.into_inner()); );
macro_rules! scalar_op_impl( macro_rules! scalar_op_impl(
@ -564,13 +560,10 @@ where
macro_rules! quaternion_op_impl( macro_rules! quaternion_op_impl(
($OpAssign: ident, $op_assign: ident; ($OpAssign: ident, $op_assign: ident;
($LhsRDim: ident, $LhsCDim: ident), ($RhsRDim: ident, $RhsCDim: ident);
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty $(=> $VDimA: ty, $VDimB: ty)*; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty $(=> $VDimA: ty, $VDimB: ty)*;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField> $OpAssign<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField> $OpAssign<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField {
DefaultAllocator: Allocator<N, $LhsRDim, $LhsCDim> +
Allocator<N, $RhsRDim, $RhsCDim> {
#[inline] #[inline]
fn $op_assign(&mut $lhs, $rhs: $Rhs) { fn $op_assign(&mut $lhs, $rhs: $Rhs) {
@ -583,35 +576,30 @@ macro_rules! quaternion_op_impl(
// Quaternion += Quaternion // Quaternion += Quaternion
quaternion_op_impl!( quaternion_op_impl!(
AddAssign, add_assign; AddAssign, add_assign;
(U4, U1), (U4, U1);
self: Quaternion<N>, rhs: &'b Quaternion<N>; self: Quaternion<N>, rhs: &'b Quaternion<N>;
self.coords += &rhs.coords; self.coords += &rhs.coords;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
AddAssign, add_assign; AddAssign, add_assign;
(U4, U1), (U4, U1);
self: Quaternion<N>, rhs: Quaternion<N>; self: Quaternion<N>, rhs: Quaternion<N>;
self.coords += rhs.coords; ); self.coords += rhs.coords; );
// Quaternion -= Quaternion // Quaternion -= Quaternion
quaternion_op_impl!( quaternion_op_impl!(
SubAssign, sub_assign; SubAssign, sub_assign;
(U4, U1), (U4, U1);
self: Quaternion<N>, rhs: &'b Quaternion<N>; self: Quaternion<N>, rhs: &'b Quaternion<N>;
self.coords -= &rhs.coords; self.coords -= &rhs.coords;
'b); 'b);
quaternion_op_impl!( quaternion_op_impl!(
SubAssign, sub_assign; SubAssign, sub_assign;
(U4, U1), (U4, U1);
self: Quaternion<N>, rhs: Quaternion<N>; self: Quaternion<N>, rhs: Quaternion<N>;
self.coords -= rhs.coords; ); self.coords -= rhs.coords; );
// Quaternion ×= Quaternion // Quaternion ×= Quaternion
quaternion_op_impl!( quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U4, U1);
self: Quaternion<N>, rhs: &'b Quaternion<N>; self: Quaternion<N>, rhs: &'b Quaternion<N>;
{ {
let res = &*self * rhs; let res = &*self * rhs;
@ -622,14 +610,12 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U4, U1);
self: Quaternion<N>, rhs: Quaternion<N>; self: Quaternion<N>, rhs: Quaternion<N>;
*self *= &rhs; ); *self *= &rhs; );
// UnitQuaternion ×= UnitQuaternion // UnitQuaternion ×= UnitQuaternion
quaternion_op_impl!( quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U4, U1);
self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>;
{ {
let res = &*self * rhs; let res = &*self * rhs;
@ -639,14 +625,12 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U4, U1);
self: UnitQuaternion<N>, rhs: UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: UnitQuaternion<N>;
*self *= &rhs; ); *self *= &rhs; );
// UnitQuaternion ÷= UnitQuaternion // UnitQuaternion ÷= UnitQuaternion
quaternion_op_impl!( quaternion_op_impl!(
DivAssign, div_assign; DivAssign, div_assign;
(U4, U1), (U4, U1);
self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: &'b UnitQuaternion<N>;
{ {
let res = &*self / rhs; let res = &*self / rhs;
@ -656,15 +640,13 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
DivAssign, div_assign; DivAssign, div_assign;
(U4, U1), (U4, U1);
self: UnitQuaternion<N>, rhs: UnitQuaternion<N>; self: UnitQuaternion<N>, rhs: UnitQuaternion<N>;
*self /= &rhs; ); *self /= &rhs; );
// UnitQuaternion ×= Rotation // UnitQuaternion ×= Rotation
quaternion_op_impl!( quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U3, U3); self: UnitQuaternion<N>, rhs: &'b Rotation<N, 3>;
self: UnitQuaternion<N>, rhs: &'b Rotation<N, U3> => U3, U3;
{ {
let res = &*self * rhs; let res = &*self * rhs;
self.as_mut_unchecked().coords.copy_from(&res.as_ref().coords); self.as_mut_unchecked().coords.copy_from(&res.as_ref().coords);
@ -673,15 +655,13 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U3, U3); self: UnitQuaternion<N>, rhs: Rotation<N, 3>;
self: UnitQuaternion<N>, rhs: Rotation<N, U3> => U3, U3;
*self *= &rhs; ); *self *= &rhs; );
// UnitQuaternion ÷= Rotation // UnitQuaternion ÷= Rotation
quaternion_op_impl!( quaternion_op_impl!(
DivAssign, div_assign; DivAssign, div_assign;
(U4, U1), (U3, U3); self: UnitQuaternion<N>, rhs: &'b Rotation<N, 3>;
self: UnitQuaternion<N>, rhs: &'b Rotation<N, U3> => U3, U3;
{ {
let res = &*self / rhs; let res = &*self / rhs;
self.as_mut_unchecked().coords.copy_from(&res.as_ref().coords); self.as_mut_unchecked().coords.copy_from(&res.as_ref().coords);
@ -690,6 +670,5 @@ quaternion_op_impl!(
quaternion_op_impl!( quaternion_op_impl!(
DivAssign, div_assign; DivAssign, div_assign;
(U4, U1), (U3, U3); self: UnitQuaternion<N>, rhs: Rotation<N, 3>;
self: UnitQuaternion<N>, rhs: Rotation<N, U3> => U3, U3;
*self /= &rhs; ); *self /= &rhs; );

View File

@ -64,7 +64,6 @@ pub struct Rotation<N: Scalar, const D: usize>
impl<N: Scalar + hash::Hash, const D: usize> 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 as Allocator<N, Const<D>, Const<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) {
@ -73,14 +72,12 @@ where
} }
impl<N: Scalar + Copy, const D: usize> Copy for Rotation<N, D> where impl<N: Scalar + Copy, const D: usize> Copy for Rotation<N, D> where
// DefaultAllocator: Allocator<N, D, D>,
<DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Copy <DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Copy
{ {
} }
impl<N: Scalar, const D: usize> Clone for Rotation<N, D> impl<N: Scalar, const D: usize> Clone for Rotation<N, D>
where where
// DefaultAllocator: Allocator<N, D, D>,
<DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Clone, <DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Clone,
{ {
#[inline] #[inline]
@ -93,8 +90,7 @@ where
impl<N, const D: usize> Abomonation for Rotation<N, D> impl<N, const D: usize> Abomonation for Rotation<N, D>
where where
N: Scalar, N: Scalar,
CMatrixN<N, Const<D>>: Abomonation, CMatrixN<N, D>: Abomonation,
// 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,8 +108,7 @@ where
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: Scalar, const D: usize> Serialize for Rotation<N, D> impl<N: Scalar, const D: usize> Serialize for Rotation<N, D>
where where
// DefaultAllocator: Allocator<N, D, D>, Owned<N, Const<D>, Const<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>
where where
@ -126,8 +121,7 @@ where
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: Scalar, const D: usize> 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>, Owned<N, Const<D>, Const<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
@ -286,8 +280,9 @@ impl<N: Scalar, const D: usize> Rotation<N, D>
// We could use `CMatrixN::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<Const<D>, U1>>::identity();
res.fixed_slice_mut::<D, D>(0, 0).copy_from(&self.matrix); res.fixed_slice_mut::<Const<D>, Const<D>>(0, 0)
.copy_from(&self.matrix);
res res
} }
@ -405,7 +400,6 @@ impl<N: Scalar, const D: usize> Rotation<N, D>
impl<N: SimdRealField, const D: usize> 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>,
{ {
/// Rotate the given point. /// Rotate the given point.
/// ///
@ -521,7 +515,6 @@ impl<N: Scalar + PartialEq, const D: usize> PartialEq for Rotation<N, D>
impl<N, const D: usize> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -540,7 +533,6 @@ where
impl<N, const D: usize> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -563,7 +555,6 @@ where
impl<N, const D: usize> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -585,7 +576,6 @@ where
impl<N, const D: usize> 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>,
{ {
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

@ -2,7 +2,7 @@ use num::{One, Zero};
use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf}; use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
use crate::base::{MatrixN, Scalar}; use crate::base::{CMatrixN, Scalar};
use crate::geometry::Rotation; use crate::geometry::Rotation;
@ -10,7 +10,6 @@ use crate::geometry::Rotation;
impl<N, const D: usize> 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>,
{ {
/// Creates a new square identity rotation of the given `dimension`. /// Creates a new square identity rotation of the given `dimension`.
/// ///
@ -25,7 +24,7 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn identity() -> Rotation<N, D> { pub fn identity() -> Rotation<N, D> {
Self::from_matrix_unchecked(MatrixN::<N, D>::identity()) Self::from_matrix_unchecked(CMatrixN::<N, D>::identity())
} }
} }
@ -45,7 +44,6 @@ impl<N: Scalar, const D: usize> Rotation<N, D>
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>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -54,7 +52,6 @@ impl<N: Scalar, const D: usize> Rotation<N, D>
impl<N, const D: usize> 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>,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {

View File

@ -5,7 +5,7 @@ use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
use crate::base::{Const, DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar}; use crate::base::{CMatrixN, 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,
@ -31,7 +31,6 @@ 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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Rotation<N2, D> { fn to_superset(&self) -> Rotation<N2, D> {
@ -40,7 +39,7 @@ where
#[inline] #[inline]
fn is_in_subset(rot: &Rotation<N2, D>) -> bool { fn is_in_subset(rot: &Rotation<N2, D>) -> bool {
crate::is_convertible::<_, MatrixN<N1, D>>(rot.matrix()) crate::is_convertible::<_, CMatrixN<N1, D>>(rot.matrix())
} }
#[inline] #[inline]
@ -125,7 +124,6 @@ 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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, R, D> { fn to_superset(&self) -> Isometry<N2, R, D> {
@ -148,7 +146,6 @@ 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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, R, D> { fn to_superset(&self) -> Similarity<N2, R, D> {
@ -213,8 +210,8 @@ where
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<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::<Const<D>, Const<D>>(0, 0);
let bottom = m.fixed_slice::<U1, D>(D, 0); let bottom = m.fixed_slice::<U1, Const<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)) &&
@ -226,7 +223,7 @@ where
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<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::<Const<D>, Const<D>>(0, 0);
Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned())) Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned()))
} }
} }
@ -264,7 +261,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element,
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>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 2]) -> Self { fn from(arr: [Rotation<N::Element, D>; 2]) -> Self {
@ -280,7 +276,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element,
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>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 4]) -> Self { fn from(arr: [Rotation<N::Element, D>; 4]) -> Self {
@ -298,7 +293,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element,
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>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 8]) -> Self { fn from(arr: [Rotation<N::Element, D>; 8]) -> Self {
@ -320,7 +314,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element,
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>,
{ {
#[inline] #[inline]
fn from(arr: [Rotation<N::Element, D>; 16]) -> Self { fn from(arr: [Rotation<N::Element, D>; 16]) -> Self {

View File

@ -24,16 +24,15 @@ use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::constraint::{AreMultipliable, ShapeConstraint}; use crate::base::constraint::{AreMultipliable, ShapeConstraint};
use crate::base::dimension::{Dim, DimName, U1}; use crate::base::dimension::{Dim, U1};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, Scalar, Unit, Vector, VectorN}; use crate::base::{
CMatrixMN, CVectorN, Const, DefaultAllocator, Matrix, MatrixMN, Scalar, Unit, Vector,
};
use crate::geometry::{Point, Rotation}; use crate::geometry::{Point, Rotation};
impl<N: Scalar, D: DimName> Index<(usize, usize)> for Rotation<N, D> impl<N: Scalar, const D: usize> Index<(usize, usize)> for Rotation<N, D> {
where
DefaultAllocator: Allocator<N, D, D>,
{
type Output = N; type Output = N;
#[inline] #[inline]
@ -45,7 +44,10 @@ where
// Rotation × Rotation // Rotation × Rotation
md_impl_all!( md_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, D) for D: DimName; (Const<D>, Const<D>), (Const<D>, Const<D>)
const D;
for;
where;
self: Rotation<N, D>, right: Rotation<N, D>, Output = Rotation<N, D>; self: Rotation<N, D>, right: Rotation<N, D>, Output = Rotation<N, D>;
[val val] => Rotation::from_matrix_unchecked(self.into_inner() * right.into_inner()); [val val] => Rotation::from_matrix_unchecked(self.into_inner() * right.into_inner());
[ref val] => Rotation::from_matrix_unchecked(self.matrix() * right.into_inner()); [ref val] => Rotation::from_matrix_unchecked(self.matrix() * right.into_inner());
@ -57,7 +59,10 @@ md_impl_all!(
// TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? // TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method?
md_impl_all!( md_impl_all!(
Div, div; Div, div;
(D, D), (D, D) for D: DimName; (Const<D>, Const<D>), (Const<D>, Const<D>)
const D;
for;
where;
self: Rotation<N, D>, right: Rotation<N, D>, Output = Rotation<N, D>; self: Rotation<N, D>, right: Rotation<N, D>, Output = Rotation<N, D>;
[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() };
@ -68,10 +73,13 @@ md_impl_all!(
// Rotation × Matrix // Rotation × Matrix
md_impl_all!( md_impl_all!(
Mul, mul; Mul, mul;
(D1, D1), (R2, C2) for D1: DimName, R2: Dim, C2: Dim, SB: Storage<N, R2, C2> (Const<D1>, Const<D1>), (R2, C2)
where DefaultAllocator: Allocator<N, D1, C2> const D1;
where ShapeConstraint: AreMultipliable<D1, D1, R2, C2>; for R2, C2, SB;
self: Rotation<N, D1>, right: Matrix<N, R2, C2, SB>, Output = MatrixMN<N, D1, C2>; where R2: Dim, C2: Dim, SB: Storage<N, R2, C2>,
DefaultAllocator: Allocator<N, Const<D1>, C2>,
ShapeConstraint: AreMultipliable<Const<D1>, Const<D1>, R2, C2>;
self: Rotation<N, D1>, right: Matrix<N, R2, C2, SB>, Output = MatrixMN<N, Const<D1>, C2>;
[val val] => self.into_inner() * right; [val val] => self.into_inner() * right;
[ref val] => self.matrix() * right; [ref val] => self.matrix() * right;
[val ref] => self.into_inner() * right; [val ref] => self.into_inner() * right;
@ -81,10 +89,13 @@ md_impl_all!(
// Matrix × Rotation // Matrix × Rotation
md_impl_all!( md_impl_all!(
Mul, mul; Mul, mul;
(R1, C1), (D2, D2) for R1: Dim, C1: Dim, D2: DimName, SA: Storage<N, R1, C1> (R1, C1), (Const<D2>, Const<D2>)
where DefaultAllocator: Allocator<N, R1, D2> const D2;
where ShapeConstraint: AreMultipliable<R1, C1, D2, D2>; for R1, C1, SA;
self: Matrix<N, R1, C1, SA>, right: Rotation<N, D2>, Output = MatrixMN<N, R1, D2>; where R1: Dim, C1: Dim, SA: Storage<N, R1, C1>,
DefaultAllocator: Allocator<N, R1, Const<D2>>,
ShapeConstraint: AreMultipliable<R1, C1, Const<D2>, Const<D2>>;
self: Matrix<N, R1, C1, SA>, right: Rotation<N, D2>, Output = MatrixMN<N, R1, Const<D2>>;
[val val] => self * right.into_inner(); [val val] => self * right.into_inner();
[ref val] => self * right.into_inner(); [ref val] => self * right.into_inner();
[val ref] => self * right.matrix(); [val ref] => self * right.matrix();
@ -94,10 +105,13 @@ md_impl_all!(
// Matrix ÷ Rotation // Matrix ÷ Rotation
md_impl_all!( md_impl_all!(
Div, div; Div, div;
(R1, C1), (D2, D2) for R1: Dim, C1: Dim, D2: DimName, SA: Storage<N, R1, C1> (R1, C1), (Const<D2>, Const<D2>)
where DefaultAllocator: Allocator<N, R1, D2> const D2;
where ShapeConstraint: AreMultipliable<R1, C1, D2, D2>; for R1, C1, SA;
self: Matrix<N, R1, C1, SA>, right: Rotation<N, D2>, Output = MatrixMN<N, R1, D2>; where R1: Dim, C1: Dim, SA: Storage<N, R1, C1>,
DefaultAllocator: Allocator<N, R1, Const<D2>>,
ShapeConstraint: AreMultipliable<R1, C1, Const<D2>, Const<D2>>;
self: Matrix<N, R1, C1, SA>, right: Rotation<N, D2>, Output = MatrixMN<N, R1, Const<D2>>;
[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() };
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
@ -109,9 +123,10 @@ md_impl_all!(
// behavior? // behavior?
md_impl_all!( md_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName (Const<D>, Const<D>), (Const<D>, U1)
where DefaultAllocator: Allocator<N, D> const D;
where ShapeConstraint: AreMultipliable<D, D, D, U1>; for;
where ShapeConstraint: AreMultipliable<Const<D>, Const<D>, Const<D>, U1>;
self: Rotation<N, D>, right: Point<N, D>, Output = Point<N, D>; self: Rotation<N, D>, right: Point<N, D>, Output = Point<N, D>;
[val val] => self.into_inner() * right; [val val] => self.into_inner() * right;
[ref val] => self.matrix() * right; [ref val] => self.matrix() * right;
@ -122,10 +137,12 @@ md_impl_all!(
// Rotation × Unit<Vector> // Rotation × Unit<Vector>
md_impl_all!( md_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName, S: Storage<N, D> (Const<D>, Const<D>), (Const<D>, U1)
where DefaultAllocator: Allocator<N, D> const D;
where ShapeConstraint: AreMultipliable<D, D, D, U1>; for S;
self: Rotation<N, D>, right: Unit<Vector<N, D, S>>, Output = Unit<VectorN<N, D>>; where S: Storage<N, Const<D>>,
ShapeConstraint: AreMultipliable<Const<D>, Const<D>, Const<D>, U1>;
self: Rotation<N, D>, right: Unit<Vector<N, Const<D>, S>>, Output = Unit<CVectorN<N, D>>;
[val val] => Unit::new_unchecked(self.into_inner() * right.into_inner()); [val val] => Unit::new_unchecked(self.into_inner() * right.into_inner());
[ref val] => Unit::new_unchecked(self.matrix() * right.into_inner()); [ref val] => Unit::new_unchecked(self.matrix() * right.into_inner());
[val ref] => Unit::new_unchecked(self.into_inner() * right.as_ref()); [val ref] => Unit::new_unchecked(self.into_inner() * right.as_ref());
@ -137,7 +154,8 @@ md_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
(D, D), (D, D) for D: DimName; (Const<D>, Const<D>), (Const<D>, Const<D>)
const D; for; where;
self: Rotation<N, D>, right: Rotation<N, D>; self: Rotation<N, D>, right: Rotation<N, D>;
[val] => self.matrix_mut_unchecked().mul_assign(right.into_inner()); [val] => self.matrix_mut_unchecked().mul_assign(right.into_inner());
[ref] => self.matrix_mut_unchecked().mul_assign(right.matrix()); [ref] => self.matrix_mut_unchecked().mul_assign(right.matrix());
@ -145,7 +163,8 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
DivAssign, div_assign; DivAssign, div_assign;
(D, D), (D, D) for D: DimName; (Const<D>, Const<D>), (Const<D>, Const<D>)
const D; for; where;
self: Rotation<N, D>, right: Rotation<N, D>; self: Rotation<N, D>, right: Rotation<N, D>;
[val] => self.matrix_mut_unchecked().mul_assign(right.inverse().into_inner()); [val] => self.matrix_mut_unchecked().mul_assign(right.inverse().into_inner());
[ref] => self.matrix_mut_unchecked().mul_assign(right.inverse().matrix()); [ref] => self.matrix_mut_unchecked().mul_assign(right.inverse().matrix());
@ -159,16 +178,18 @@ md_assign_impl_all!(
md_assign_impl_all!( md_assign_impl_all!(
MulAssign, mul_assign; MulAssign, mul_assign;
(R1, C1), (C1, C1) for R1: DimName, C1: DimName; (Const<R1>, Const<C1>), (Const<C1>, Const<C1>)
self: MatrixMN<N, R1, C1>, right: Rotation<N, C1>; const R1, C1; for; where;
self: CMatrixMN<N, R1, C1>, right: Rotation<N, C1>;
[val] => self.mul_assign(right.into_inner()); [val] => self.mul_assign(right.into_inner());
[ref] => self.mul_assign(right.matrix()); [ref] => self.mul_assign(right.matrix());
); );
md_assign_impl_all!( md_assign_impl_all!(
DivAssign, div_assign; DivAssign, div_assign;
(R1, C1), (C1, C1) for R1: DimName, C1: DimName; (Const<R1>, Const<C1>), (Const<C1>, Const<C1>)
self: MatrixMN<N, R1, C1>, right: Rotation<N, C1>; const R1, C1; for; where;
self: CMatrixMN<N, R1, C1>, right: Rotation<N, C1>;
[val] => self.mul_assign(right.inverse().into_inner()); [val] => self.mul_assign(right.inverse().into_inner());
[ref] => self.mul_assign(right.inverse().matrix()); [ref] => self.mul_assign(right.inverse().matrix());
); );

View File

@ -8,7 +8,6 @@ impl<N, const D: usize> SimdValue for Rotation<N, D>
where where
N: Scalar + SimdValue, N: Scalar + SimdValue,
N::Element: Scalar, N::Element: Scalar,
// 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

@ -29,15 +29,15 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "N: Serialize, serde(bound(serialize = "N: Serialize,
R: Serialize, R: Serialize,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, Const<D>>,
Owned<N, D>: Serialize")) Owned<N, Const<D>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "N: Deserialize<'de>, serde(bound(deserialize = "N: Deserialize<'de>,
R: Deserialize<'de>, R: Deserialize<'de>,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, Const<D>>,
Owned<N, D>: Deserialize<'de>")) Owned<N, Const<D>>: Deserialize<'de>"))
)] )]
pub struct Similarity<N: Scalar, R, const D: usize> pub struct Similarity<N: Scalar, R, const D: usize>
// where // where
@ -52,7 +52,6 @@ pub struct Similarity<N: Scalar, R, const D: usize>
impl<N: Scalar, R, const D: usize> Abomonation for Similarity<N, R, D> impl<N: Scalar, R, const D: usize> Abomonation for Similarity<N, R, D>
where where
Isometry<N, R, D>: Abomonation, Isometry<N, R, D>: Abomonation,
// 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)
@ -69,7 +68,6 @@ where
impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Similarity<N, R, D> impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Similarity<N, R, D>
where where
// DefaultAllocator: Allocator<N, D>,
Owned<N, Const<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) {
@ -81,7 +79,6 @@ where
impl<N: Scalar + Copy + Zero, R: AbstractRotation<N, D> + Copy, const D: usize> Copy impl<N: Scalar + Copy + Zero, R: AbstractRotation<N, D> + Copy, const D: usize> Copy
for Similarity<N, R, D> for Similarity<N, R, D>
where where
// DefaultAllocator: Allocator<N, D>,
Owned<N, Const<D>>: Copy, Owned<N, Const<D>>: Copy,
{ {
} }
@ -100,7 +97,6 @@ impl<N: Scalar + Zero, R: AbstractRotation<N, D> + Clone, const D: usize> Clone
impl<N: Scalar + Zero, R, const D: usize> Similarity<N, R, D> 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>,
{ {
/// Creates a new similarity from its rotational and translational parts. /// Creates a new similarity from its rotational and translational parts.
#[inline] #[inline]
@ -143,7 +139,6 @@ 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>,
{ {
/// Creates a new similarity that applies only a scaling factor. /// Creates a new similarity that applies only a scaling factor.
#[inline] #[inline]
@ -345,7 +340,7 @@ impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
{ {
let mut res = self.isometry.to_homogeneous(); let mut res = self.isometry.to_homogeneous();
for e in res.fixed_slice_mut::<D, D>(0, 0).iter_mut() { for e in res.fixed_slice_mut::<Const<D>, Const<D>>(0, 0).iter_mut() {
*e *= self.scaling *e *= self.scaling
} }
@ -354,14 +349,13 @@ impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
} }
impl<N: SimdRealField, R, const D: usize> Eq for Similarity<N, R, D> where impl<N: SimdRealField, R, const D: usize> Eq for Similarity<N, R, D> where
R: AbstractRotation<N, D> + Eq // DefaultAllocator: Allocator<N, D>, R: AbstractRotation<N, D> + Eq
{ {
} }
impl<N: SimdRealField, R, const D: usize> PartialEq for Similarity<N, R, D> 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>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -372,7 +366,6 @@ where
impl<N: RealField, R, const D: usize> AbsDiffEq for Similarity<N, R, D> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -392,7 +385,6 @@ where
impl<N: RealField, R, const D: usize> RelativeEq for Similarity<N, R, D> 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>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -441,7 +433,6 @@ 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>,
{ {
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

@ -16,7 +16,7 @@ use simba::simd::SimdRealField;
use crate::base::{Vector2, Vector3}; use crate::base::{Vector2, Vector3};
use crate::{ use crate::{
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity, AbstractRotation, Const, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity,
Translation, UnitComplex, UnitQuaternion, Translation, UnitComplex, UnitQuaternion,
}; };
@ -24,7 +24,6 @@ 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>,
{ {
/// Creates a new identity similarity. /// Creates a new identity similarity.
/// ///
@ -51,7 +50,6 @@ 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>,
{ {
/// Creates a new identity similarity. /// Creates a new identity similarity.
#[inline] #[inline]
@ -64,7 +62,6 @@ where
impl<N: crate::RealField, R, const D: usize> Distribution<Similarity<N, R, D>> 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>,
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.
@ -83,7 +80,6 @@ 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>,
{ {
/// 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`.
@ -113,8 +109,7 @@ 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>, Owned<N, Const<D>>: Send,
Owned<N, D>: Send,
{ {
#[inline] #[inline]
fn arbitrary(rng: &mut Gen) -> Self { fn arbitrary(rng: &mut Gen) -> Self {
@ -394,7 +389,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>, 3>::look_at_lh(eye, target, up), scaling)
} }
} }
} }

View File

@ -26,7 +26,6 @@ where
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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, R2, D> { fn to_superset(&self) -> Similarity<N2, R2, D> {
@ -106,7 +105,7 @@ where
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<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::<Const<D>, Const<D>>(0, 0).clone_owned();
if rot if rot
.fixed_columns_mut::<U1>(0) .fixed_columns_mut::<U1>(0)
.try_normalize_mut(N2::zero()) .try_normalize_mut(N2::zero())
@ -128,7 +127,7 @@ 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, 0); let bottom = m.fixed_slice::<U1, Const<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.
@ -143,22 +142,22 @@ where
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<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::<Const<D>, U1>(0, 0).normalize_mut();
let nb = mm.fixed_slice_mut::<D, U1>(0, 1).normalize_mut(); let nb = mm.fixed_slice_mut::<Const<D>, U1>(0, 1).normalize_mut();
let nc = mm.fixed_slice_mut::<D, U1>(0, 2).normalize_mut(); let nc = mm.fixed_slice_mut::<Const<D>, U1>(0, 2).normalize_mut();
let mut scale = (na + nb + nc) / crate::convert(3.0); // We take the mean, for robustness. let mut scale = (na + nb + nc) / crate::convert(3.0); // We take the mean, for robustness.
// TODO: could we avoid the explicit computation of the determinant? // TODO: could we avoid the explicit computation of the determinant?
// (its sign is needed to see if the scaling factor is negative). // (its sign is needed to see if the scaling factor is negative).
if mm.fixed_slice::<D, D>(0, 0).determinant() < N2::zero() { if mm.fixed_slice::<Const<D>, Const<D>>(0, 0).determinant() < N2::zero() {
mm.fixed_slice_mut::<D, U1>(0, 0).neg_mut(); mm.fixed_slice_mut::<Const<D>, U1>(0, 0).neg_mut();
mm.fixed_slice_mut::<D, U1>(0, 1).neg_mut(); mm.fixed_slice_mut::<Const<D>, U1>(0, 1).neg_mut();
mm.fixed_slice_mut::<D, U1>(0, 2).neg_mut(); mm.fixed_slice_mut::<Const<D>, U1>(0, 2).neg_mut();
scale = -scale; scale = -scale;
} }
let t = m.fixed_slice::<D, U1>(0, D).into_owned(); let t = m.fixed_slice::<Const<D>, U1>(0, D).into_owned();
let t = Translation { let t = Translation {
vector: crate::convert_unchecked(t), vector: crate::convert_unchecked(t),
}; };
@ -192,7 +191,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, R::Element, D>; 2]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 2]) -> Self {
@ -211,7 +209,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, R::Element, D>; 4]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 4]) -> Self {
@ -240,7 +237,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, R::Element, D>; 8]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 8]) -> Self {
@ -277,7 +273,6 @@ where
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>,
{ {
#[inline] #[inline]
fn from(arr: [Similarity<N::Element, R::Element, D>; 16]) -> Self { fn from(arr: [Similarity<N::Element, R::Element, D>; 16]) -> Self {

View File

@ -5,8 +5,8 @@ use simba::scalar::{ClosedAdd, ClosedMul};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U1, U2, U3, U4}; use crate::base::dimension::{U1, U2, U3};
use crate::base::{DefaultAllocator, Scalar, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, Scalar};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Point, Rotation, Similarity, Translation, UnitComplex, AbstractRotation, Isometry, Point, Rotation, Similarity, Translation, UnitComplex,
@ -70,10 +70,9 @@ macro_rules! similarity_binop_impl(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField, D: DimName, R> $Op<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField, R, const D: usize> $Op<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D> {
DefaultAllocator: Allocator<N, D> {
type Output = $Output; type Output = $Output;
#[inline] #[inline]
@ -118,20 +117,18 @@ macro_rules! similarity_binop_assign_impl_all(
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
[val] => $action_val: expr; [val] => $action_val: expr;
[ref] => $action_ref: expr;) => { [ref] => $action_ref: expr;) => {
impl<N: SimdRealField, D: DimName, R> $OpAssign<$Rhs> for $Lhs impl<N: SimdRealField, R, const D: usize> $OpAssign<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D>{
DefaultAllocator: Allocator<N, D> {
#[inline] #[inline]
fn $op_assign(&mut $lhs, $rhs: $Rhs) { fn $op_assign(&mut $lhs, $rhs: $Rhs) {
$action_val $action_val
} }
} }
impl<'b, N: SimdRealField, D: DimName, R> $OpAssign<&'b $Rhs> for $Lhs impl<'b, N: SimdRealField, R, const D: usize> $OpAssign<&'b $Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField,
R: AbstractRotation<N, D>, R: AbstractRotation<N, D> {
DefaultAllocator: Allocator<N, D> {
#[inline] #[inline]
fn $op_assign(&mut $lhs, $rhs: &'b $Rhs) { fn $op_assign(&mut $lhs, $rhs: &'b $Rhs) {
$action_ref $action_ref
@ -220,16 +217,18 @@ similarity_binop_assign_impl_all!(
// Similarity ÷= R // Similarity ÷= R
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;
(D, U1), (D, D) for D: DimName; (Const<D>, U1), (Const<D>, Const<D>)
self: Similarity<N, D, Rotation<N, D>>, rhs: Rotation<N, D>; const D; for; where;
self: Similarity<N, Rotation<N, D>, D>, rhs: Rotation<N, D>;
[val] => self.isometry.rotation *= rhs; [val] => self.isometry.rotation *= rhs;
[ref] => self.isometry.rotation *= rhs.clone(); [ref] => self.isometry.rotation *= rhs.clone();
); );
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;
(D, U1), (D, D) for D: DimName; (Const<D>, U1), (Const<D>, Const<D>)
self: Similarity<N, D, Rotation<N, D>>, rhs: Rotation<N, D>; const D; for; where;
self: Similarity<N, Rotation<N, D>, D>, rhs: Rotation<N, D>;
// 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() };
@ -237,7 +236,8 @@ 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)
const; for; where;
self: Similarity<N, UnitQuaternion<N>, 3>, 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;
@ -245,7 +245,8 @@ 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)
const; for; where;
self: Similarity<N, UnitQuaternion<N>, 3>, 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() };
@ -254,16 +255,18 @@ 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;
(U2, U2), (U2, U2) for; (U2, U2), (U2, U2)
self: Similarity<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>; const; for; where;
self: Similarity<N, UnitComplex<N>, 2>, rhs: UnitComplex<N>;
[val] => self.isometry.rotation *= rhs; [val] => self.isometry.rotation *= rhs;
[ref] => self.isometry.rotation *= *rhs; [ref] => self.isometry.rotation *= *rhs;
); );
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;
(U2, U2), (U2, U2) for; (U2, U2), (U2, U2)
self: Similarity<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>; const; for; where;
self: Similarity<N, UnitComplex<N>, 2>, rhs: UnitComplex<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() };
@ -347,7 +350,7 @@ similarity_binop_impl_all!(
// Similarity × Vector // Similarity × Vector
similarity_binop_impl_all!( similarity_binop_impl_all!(
Mul, mul; Mul, mul;
self: Similarity<N, R, D>, right: VectorN<N, D>, Output = VectorN<N, D>; self: Similarity<N, R, D>, right: CVectorN<N, D>, Output = CVectorN<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();
@ -389,13 +392,11 @@ similarity_binop_impl_all!(
macro_rules! similarity_from_composition_impl( macro_rules! similarity_from_composition_impl(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(for $Dims: ident: $DimsBound: ident),*; $($Dims: ident),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField $(, $Dims: $DimsBound)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField $(, const $Dims: usize)*> $Op<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField {
DefaultAllocator: Allocator<N, $R1, $C1> +
Allocator<N, $R2, $C2> {
type Output = $Output; type Output = $Output;
#[inline] #[inline]
@ -408,7 +409,7 @@ macro_rules! similarity_from_composition_impl(
macro_rules! similarity_from_composition_impl_all( macro_rules! similarity_from_composition_impl_all(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(for $Dims: ident: $DimsBound: ident),*; $($Dims: ident),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
[val val] => $action_val_val: expr; [val val] => $action_val_val: expr;
[ref val] => $action_ref_val: expr; [ref val] => $action_ref_val: expr;
@ -417,25 +418,25 @@ macro_rules! similarity_from_composition_impl_all(
similarity_from_composition_impl!( similarity_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: $Lhs, $rhs: $Rhs, Output = $Output; $lhs: $Lhs, $rhs: $Rhs, Output = $Output;
$action_val_val; ); $action_val_val; );
similarity_from_composition_impl!( similarity_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Output; $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Output;
$action_ref_val; 'a); $action_ref_val; 'a);
similarity_from_composition_impl!( similarity_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Output; $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Output;
$action_val_ref; 'b); $action_val_ref; 'b);
similarity_from_composition_impl!( similarity_from_composition_impl!(
$Op, $op; $Op, $op;
($R1, $C1),($R2, $C2) $(for $Dims: $DimsBound),*; $($Dims),*;
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Output; $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Output;
$action_ref_ref; 'a, 'b); $action_ref_ref; 'a, 'b);
} }
@ -444,9 +445,9 @@ macro_rules! similarity_from_composition_impl_all(
// Similarity × Rotation // Similarity × Rotation
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName; D;
self: Similarity<N, D, Rotation<N, D>>, rhs: Rotation<N, D>, self: Similarity<N, Rotation<N, D>, D>, rhs: Rotation<N, D>,
Output = Similarity<N, D, Rotation<N, D>>; Output = Similarity<N, Rotation<N, D>, D>;
[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)
@ -462,9 +463,9 @@ similarity_from_composition_impl_all!(
// Rotation × Similarity // Rotation × Similarity
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(D, D), (D, U1) for D: DimName; D;
self: Rotation<N, D>, right: Similarity<N, D, Rotation<N, D>>, self: Rotation<N, D>, right: Similarity<N, Rotation<N, D>, D>,
Output = Similarity<N, D, Rotation<N, D>>; Output = Similarity<N, Rotation<N, D>, 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;
@ -474,9 +475,9 @@ similarity_from_composition_impl_all!(
// Similarity ÷ Rotation // Similarity ÷ Rotation
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(D, D), (D, U1) for D: DimName; D;
self: Similarity<N, D, Rotation<N, D>>, rhs: Rotation<N, D>, self: Similarity<N, Rotation<N, D>, D>, rhs: Rotation<N, D>,
Output = Similarity<N, D, Rotation<N, D>>; Output = Similarity<N, Rotation<N, D>, D>;
[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)
@ -492,9 +493,9 @@ similarity_from_composition_impl_all!(
// Rotation ÷ Similarity // Rotation ÷ Similarity
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(D, D), (D, U1) for D: DimName; D;
self: Rotation<N, D>, right: Similarity<N, D, Rotation<N, D>>, self: Rotation<N, D>, right: Similarity<N, Rotation<N, D>, D>,
Output = Similarity<N, D, Rotation<N, D>>; Output = Similarity<N, Rotation<N, D>, D>;
// 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() };
@ -505,7 +506,7 @@ similarity_from_composition_impl_all!(
// Similarity × UnitQuaternion // Similarity × UnitQuaternion
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>, self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
Output = Similarity<N, UnitQuaternion<N>, 3>; Output = Similarity<N, UnitQuaternion<N>, 3>;
[val val] => { [val val] => {
@ -523,7 +524,7 @@ similarity_from_composition_impl_all!(
// UnitQuaternion × Similarity // UnitQuaternion × Similarity
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>, self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>,
Output = Similarity<N, UnitQuaternion<N>, 3>; Output = Similarity<N, UnitQuaternion<N>, 3>;
[val val] => &self * &right; [val val] => &self * &right;
@ -535,7 +536,7 @@ similarity_from_composition_impl_all!(
// Similarity ÷ UnitQuaternion // Similarity ÷ UnitQuaternion
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(U4, U1), (U3, U1); ;
self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>, self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
Output = Similarity<N, UnitQuaternion<N>, 3>; Output = Similarity<N, UnitQuaternion<N>, 3>;
[val val] => { [val val] => {
@ -553,7 +554,7 @@ similarity_from_composition_impl_all!(
// UnitQuaternion ÷ Similarity // UnitQuaternion ÷ Similarity
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(U4, U1), (U3, U1); ;
self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>, self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>,
Output = Similarity<N, UnitQuaternion<N>, 3>; Output = Similarity<N, UnitQuaternion<N>, 3>;
// TODO: don't call inverse explicitly? // TODO: don't call inverse explicitly?
@ -566,9 +567,9 @@ similarity_from_composition_impl_all!(
// Similarity × UnitComplex // Similarity × UnitComplex
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Mul, mul; Mul, mul;
(U2, U1), (U2, U1); ;
self: Similarity<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>, self: Similarity<N, UnitComplex<N>, 2>, rhs: UnitComplex<N>,
Output = Similarity<N, U2, UnitComplex<N>>; Output = Similarity<N, UnitComplex<N>, 2>;
[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)
@ -584,9 +585,9 @@ similarity_from_composition_impl_all!(
// Similarity ÷ UnitComplex // Similarity ÷ UnitComplex
similarity_from_composition_impl_all!( similarity_from_composition_impl_all!(
Div, div; Div, div;
(U2, U1), (U2, U1); ;
self: Similarity<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>, self: Similarity<N, UnitComplex<N>, 2>, rhs: UnitComplex<N>,
Output = Similarity<N, U2, UnitComplex<N>>; Output = Similarity<N, UnitComplex<N>, 2>;
[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)

View File

@ -7,7 +7,6 @@ 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>,
{ {
type Element = Similarity<N::Element, R::Element, D>; type Element = Similarity<N::Element, R::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -21,7 +21,6 @@ macro_rules! impl_swizzle {
impl<N: Scalar, const D: usize> Point<N, D> impl<N: Scalar, const D: usize> Point<N, D>
where where
Const<D>: ToTypenum, Const<D>: ToTypenum,
// DefaultAllocator: Allocator<N, D>,
{ {
impl_swizzle!( impl_swizzle!(
where U0: xx() -> Point2[0, 0], where U0: xx() -> Point2[0, 0],

View File

@ -11,7 +11,7 @@ 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::storage::Owned; use crate::base::storage::Owned;
use crate::base::{CMatrixN, CVectorN, Const, DefaultAllocator, MatrixN}; use crate::base::{CVectorN, Const, DefaultAllocator, DimName, 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, const D: usize>(mat: &CMatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<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, const D: usize>(_: &CMatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, D: DimName>(_: &MatrixN<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, const D: usize>(mat: &CMatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<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, const D: usize>(mat: &CMatrixN<N, D>) -> bool fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool
where where
N::Epsilon: Copy, N::Epsilon: Copy,
// DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<N, D, D>,
{ {
let last = D - 1; let last = D::dim() - 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())

View File

@ -4,8 +4,8 @@ use std::ops::{Div, DivAssign, Index, IndexMut, Mul, MulAssign};
use simba::scalar::{ClosedAdd, ClosedMul, RealField, SubsetOf}; use simba::scalar::{ClosedAdd, ClosedMul, RealField, SubsetOf};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1, U3, U4}; use crate::base::dimension::{DimNameAdd, DimNameSum, U1, U4};
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar};
use crate::geometry::{ use crate::geometry::{
Isometry, Point, Rotation, Similarity, SubTCategoryOf, SuperTCategoryOf, TAffine, TCategory, Isometry, Point, Rotation, Similarity, SubTCategoryOf, SuperTCategoryOf, TAffine, TCategory,
@ -107,16 +107,19 @@ where
// Transform × Vector // Transform × Vector
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
self: Transform<N, C, D>, rhs: VectorN<N, D>, Output = VectorN<N, D>; const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategory;
self: Transform<N, C, D>, rhs: CVectorN<N, D>, Output = CVectorN<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;
[ref ref] => { [ref ref] => {
let transform = self.matrix().fixed_slice::<D, D>(0, 0); let transform = self.matrix().fixed_slice::<Const<D>, Const<D>>(0, 0);
if C::has_normalizer() { if C::has_normalizer() {
let normalizer = self.matrix().fixed_slice::<U1, D>(D::dim(), 0); let normalizer = self.matrix().fixed_slice::<U1, Const<D>>(D, 0);
let n = normalizer.tr_dot(&rhs); let n = normalizer.tr_dot(&rhs);
if !n.is_zero() { if !n.is_zero() {
@ -131,20 +134,22 @@ md_impl_all!(
// Transform × Point // Transform × Point
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
where DefaultAllocator: Allocator<N, D, D>; const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategory;
self: Transform<N, C, D>, 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;
[ref ref] => { [ref ref] => {
let transform = self.matrix().fixed_slice::<D, D>(0, 0); let transform = self.matrix().fixed_slice::<Const<D>, Const<D>>(0, 0);
let translation = self.matrix().fixed_slice::<D, U1>(0, D::dim()); let translation = self.matrix().fixed_slice::<Const<D>, U1>(0, D);
if C::has_normalizer() { if C::has_normalizer() {
let normalizer = self.matrix().fixed_slice::<U1, D>(D::dim(), 0); let normalizer = self.matrix().fixed_slice::<U1, Const<D>>(D, 0);
#[allow(clippy::suspicious_arithmetic_impl)] #[allow(clippy::suspicious_arithmetic_impl)]
let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked((D::dim(), D::dim())) }; let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked((D, D)) };
if !n.is_zero() { if !n.is_zero() {
return (transform * rhs + translation) / n; return (transform * rhs + translation) / n;
@ -158,8 +163,11 @@ md_impl_all!(
// Transform × Transform // Transform × Transform
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, CA: TCategoryMul<CB>, CB: TCategory; (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
self: Transform<N, D, CA>, rhs: Transform<N, D, CB>, Output = Transform<N, D, CA::Representative>; const D;
for CA, CB;
where Const<D>: DimNameAdd<U1>, CA: TCategoryMul<CB>, CB: TCategory;
self: Transform<N, CA, D>, rhs: Transform<N, CB, D>, Output = Transform<N, CA::Representative, D>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.matrix());
@ -169,7 +177,10 @@ md_impl_all!(
// Transform × Rotation // Transform × Rotation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, Const<D>)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, C, D>, rhs: Rotation<N, D>, Output = Transform<N, C::Representative, D>; 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());
@ -180,7 +191,10 @@ md_impl_all!(
// Rotation × Transform // Rotation × Transform
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>; (Const<D>, Const<D>), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Rotation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; 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());
@ -191,7 +205,10 @@ md_impl_all!(
// Transform × UnitQuaternion // Transform × UnitQuaternion
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)
const;
for C;
where C: TCategoryMul<TAffine>;
self: Transform<N, C, 3>, rhs: UnitQuaternion<N>, Output = Transform<N, C::Representative, 3>; 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());
@ -202,7 +219,10 @@ md_impl_all!(
// UnitQuaternion × Transform // UnitQuaternion × Transform
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)
const;
for C;
where C: TCategoryMul<TAffine>;
self: UnitQuaternion<N>, rhs: Transform<N, C, 3>, Output = Transform<N, C::Representative, 3>; 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());
@ -213,8 +233,10 @@ md_impl_all!(
// Transform × Isometry // Transform × Isometry
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; const D;
for C, R;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
self: Transform<N, C, D>, rhs: Isometry<N, R, D>, Output = Transform<N, C::Representative, D>; 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());
@ -225,8 +247,10 @@ md_impl_all!(
// Isometry × Transform // Isometry × Transform
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (Const<D>, U1), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; const D;
for C, R;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
self: Isometry<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; 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());
@ -237,8 +261,10 @@ md_impl_all!(
// Transform × Similarity // Transform × Similarity
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; const D;
for C, R;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
self: Transform<N, C, D>, rhs: Similarity<N, R, D>, Output = Transform<N, C::Representative, D>; 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());
@ -249,8 +275,10 @@ md_impl_all!(
// Similarity × Transform // Similarity × Transform
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (Const<D>, U1), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; const D;
for C, R;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
self: Similarity<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; 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());
@ -269,7 +297,10 @@ md_impl_all!(
// Transform × Translation // Transform × Translation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, C, D>, rhs: Translation<N, D>, Output = Transform<N, C::Representative, D>; 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());
@ -280,8 +311,10 @@ md_impl_all!(
// Translation × Transform // Translation × Transform
md_impl_all!( md_impl_all!(
Mul, mul where N: RealField; Mul, mul where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (Const<D>, U1), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Translation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; 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());
@ -292,8 +325,11 @@ md_impl_all!(
// Transform ÷ Transform // Transform ÷ Transform
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, CA: TCategoryMul<CB>, CB: SubTCategoryOf<TProjective>; (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
self: Transform<N, D, CA>, rhs: Transform<N, D, CB>, Output = Transform<N, D, CA::Representative>; const D;
for CA, CB;
where Const<D>: DimNameAdd<U1>, CA: TCategoryMul<CB>, CB: SubTCategoryOf<TProjective>;
self: Transform<N, CA, D>, rhs: Transform<N, CB, D>, Output = Transform<N, CA::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.clone().inverse() }; [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.clone().inverse() };
@ -303,7 +339,10 @@ md_impl_all!(
// Transform ÷ Rotation // Transform ÷ Rotation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, Const<D>)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, C, D>, rhs: Rotation<N, D>, Output = Transform<N, C::Representative, D>; 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() };
@ -314,7 +353,10 @@ md_impl_all!(
// Rotation ÷ Transform // Rotation ÷ Transform
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>; (Const<D>, Const<D>), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Rotation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; 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 };
@ -325,7 +367,10 @@ md_impl_all!(
// Transform ÷ UnitQuaternion // Transform ÷ UnitQuaternion
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)
const;
for C;
where C: TCategoryMul<TAffine>;
self: Transform<N, C, 3>, rhs: UnitQuaternion<N>, Output = Transform<N, C::Representative, 3>; 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() };
@ -336,7 +381,10 @@ md_impl_all!(
// UnitQuaternion ÷ Transform // UnitQuaternion ÷ Transform
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)
const;
for C;
where C: TCategoryMul<TAffine>;
self: UnitQuaternion<N>, rhs: Transform<N, C, 3>, Output = Transform<N, C::Representative, 3>; 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 };
@ -347,9 +395,9 @@ md_impl_all!(
// // Transform ÷ Isometry // // Transform ÷ Isometry
// md_impl_all!( // md_impl_all!(
// Div, div where N: RealField; // Div, div where N: RealField;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >; // where SB::Alloc: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1> >;
// self: Transform<N, C, D>, rhs: Isometry<N, R, D>, Output = Transform<N, C::Representative, D>; // 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());
@ -360,9 +408,9 @@ md_impl_all!(
// // Isometry ÷ Transform // // Isometry ÷ Transform
// md_impl_all!( // md_impl_all!(
// Div, div where N: RealField; // Div, div where N: RealField;
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) // (Const<D>, U1), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >; // where SA::Alloc: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1> >;
// self: Isometry<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; // 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());
@ -373,10 +421,10 @@ md_impl_all!(
// // Transform ÷ Similarity // // Transform ÷ Similarity
// md_impl_all!( // md_impl_all!(
// Div, div where N: RealField; // Div, div where N: RealField;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<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<Const<D>, U1>, DimNameSum<Const<D>, U1> >;
// self: Transform<N, C, D>, rhs: Similarity<N, R, D>, Output = Transform<N, C::Representative, D>; // 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());
@ -387,10 +435,10 @@ md_impl_all!(
// // Similarity ÷ Transform // // Similarity ÷ Transform
// md_impl_all!( // md_impl_all!(
// Div, div where N: RealField; // Div, div where N: RealField;
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) // (Const<D>, U1), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> > // for Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<Const<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<Const<D>, U1>, DimNameSum<Const<D>, U1> >;
// self: Similarity<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; // 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());
@ -401,7 +449,10 @@ md_impl_all!(
// Transform ÷ Translation // Transform ÷ Translation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Transform<N, C, D>, rhs: Translation<N, D>, Output = Transform<N, C::Representative, D>; 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() };
@ -412,8 +463,10 @@ md_impl_all!(
// Translation ÷ Transform // Translation ÷ Transform
md_impl_all!( md_impl_all!(
Div, div where N: RealField; Div, div where N: RealField;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>) (Const<D>, U1), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>; const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
self: Translation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>; 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 };
@ -424,8 +477,11 @@ md_impl_all!(
// Transform ×= Transform // Transform ×= Transform
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>), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, CA: TCategory, CB: SubTCategoryOf<CA>; (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
self: Transform<N, D, CA>, rhs: Transform<N, D, CB>; const D;
for CA, CB;
where Const<D>: DimNameAdd<U1>, CA: TCategory, CB: SubTCategoryOf<CA>;
self: Transform<N, CA, D>, rhs: Transform<N, CB, D>;
[val] => *self.matrix_mut_unchecked() *= rhs.into_inner(); [val] => *self.matrix_mut_unchecked() *= rhs.into_inner();
[ref] => *self.matrix_mut_unchecked() *= rhs.matrix(); [ref] => *self.matrix_mut_unchecked() *= rhs.matrix();
); );
@ -433,8 +489,10 @@ md_assign_impl_all!(
// Transform ×= Similarity // Transform ×= Similarity
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) (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; const D;
for C, R;
where Const<D>: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
self: Transform<N, C, D>, rhs: Similarity<N, R, D>; 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();
@ -443,8 +501,10 @@ md_assign_impl_all!(
// Transform ×= Isometry // Transform ×= Isometry
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) (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; const D;
for C, R;
where Const<D>: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
self: Transform<N, C, D>, rhs: Isometry<N, R, D>; 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();
@ -461,7 +521,10 @@ md_assign_impl_all!(
// Transform ×= Translation // Transform ×= Translation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategory;
self: Transform<N, C, D>, 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();
@ -470,7 +533,10 @@ md_assign_impl_all!(
// Transform ×= Rotation // Transform ×= Rotation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, Const<D>)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategory;
self: Transform<N, C, D>, 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();
@ -479,7 +545,10 @@ md_assign_impl_all!(
// Transform ×= UnitQuaternion // Transform ×= UnitQuaternion
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)
const;
for C;
where C: TCategory;
self: Transform<N, C, 3>, 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();
@ -488,9 +557,11 @@ md_assign_impl_all!(
// Transform ÷= Transform // Transform ÷= Transform
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>), (DimNameSum<D, U1>, DimNameSum<D, U1>) (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>)
for D: DimNameAdd<U1>, CA: SuperTCategoryOf<CB>, CB: SubTCategoryOf<TProjective>; const D;
self: Transform<N, D, CA>, rhs: Transform<N, D, CB>; for CA, CB;
where Const<D>: DimNameAdd<U1>, CA: SuperTCategoryOf<CB>, CB: SubTCategoryOf<TProjective>;
self: Transform<N, CA, D>, rhs: Transform<N, CB, 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.clone().inverse() }; [ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.clone().inverse() };
); );
@ -498,8 +569,8 @@ md_assign_impl_all!(
// // Transform ÷= Similarity // // Transform ÷= Similarity
// md_assign_impl_all!( // md_assign_impl_all!(
// DivAssign, div_assign; // DivAssign, div_assign;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; // for Const<D>: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
// self: Transform<N, C, D>, rhs: Similarity<N, R, D>; // 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();
@ -509,8 +580,8 @@ md_assign_impl_all!(
// // Transform ÷= Isometry // // Transform ÷= Isometry
// md_assign_impl_all!( // md_assign_impl_all!(
// DivAssign, div_assign; // DivAssign, div_assign;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) // (DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >; // for Const<D>: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>> >;
// self: Transform<N, C, D>, rhs: Isometry<N, R, D>; // 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();
@ -519,7 +590,10 @@ md_assign_impl_all!(
// Transform ÷= Translation // Transform ÷= Translation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, U1)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategory;
self: Transform<N, C, D>, 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() };
@ -528,7 +602,10 @@ md_assign_impl_all!(
// Transform ÷= Rotation // Transform ÷= Rotation
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<Const<D>, U1>, DimNameSum<Const<D>, U1>), (Const<D>, Const<D>)
const D;
for C;
where Const<D>: DimNameAdd<U1>, C: TCategory;
self: Transform<N, C, D>, 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() };
@ -537,7 +614,10 @@ md_assign_impl_all!(
// Transform ÷= UnitQuaternion // Transform ÷= UnitQuaternion
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)
const;
for C;
where C: TCategory;
self: Transform<N, C, 3>, 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

@ -34,7 +34,6 @@ pub struct Translation<N: Scalar, const D: usize>
impl<N: Scalar + hash::Hash, const D: usize> 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>,
Owned<N, Const<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) {
@ -42,15 +41,10 @@ where
} }
} }
impl<N: Scalar + Copy, const D: usize> Copy for Translation<N, D> where impl<N: Scalar + Copy, const D: usize> Copy for Translation<N, D> where Owned<N, Const<D>>: Copy {}
// DefaultAllocator: Allocator<N, D>,
Owned<N, Const<D>>: Copy
{
}
impl<N: Scalar, const D: usize> Clone for Translation<N, D> impl<N: Scalar, const D: usize> Clone for Translation<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
Owned<N, Const<D>>: Clone, Owned<N, Const<D>>: Clone,
{ {
#[inline] #[inline]
@ -60,12 +54,10 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N, D> Abomonation for Translation<N, D> impl<N, const D: usize> Abomonation for Translation<N, D>
where where
N: Scalar, N: Scalar,
D: DimName,
CVectorN<N, D>: Abomonation, CVectorN<N, D>: Abomonation,
// 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)
@ -83,8 +75,7 @@ where
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: Scalar, const D: usize> Serialize for Translation<N, D> impl<N: Scalar, const D: usize> Serialize for Translation<N, D>
where where
// DefaultAllocator: Allocator<N, D>, Owned<N, Const<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>
where where
@ -97,8 +88,7 @@ where
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: Scalar, const D: usize> 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>, Owned<N, Const<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
@ -169,8 +159,9 @@ impl<N: Scalar, const D: usize> Translation<N, D>
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<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<Const<D>, U1>>::identity();
res.fixed_slice_mut::<D, U1>(0, D).copy_from(&self.vector); res.fixed_slice_mut::<Const<D>, U1>(0, D)
.copy_from(&self.vector);
res res
} }
@ -257,7 +248,6 @@ impl<N: Scalar + PartialEq, const D: usize> PartialEq for Translation<N, D>
impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<N, D> impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
type Epsilon = N::Epsilon; type Epsilon = N::Epsilon;
@ -275,7 +265,6 @@ where
impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<N, D> impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]
@ -297,7 +286,6 @@ where
impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<N, D> impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<N, D>
where where
// DefaultAllocator: Allocator<N, D>,
N::Epsilon: Copy, N::Epsilon: Copy,
{ {
#[inline] #[inline]

View File

@ -12,7 +12,7 @@ use rand::{
use simba::scalar::{ClosedAdd, SupersetOf}; use simba::scalar::{ClosedAdd, SupersetOf};
use crate::base::{CVectorN, Scalar}; use crate::base::{CVectorN, Const, Scalar};
use crate::geometry::Translation; use crate::geometry::Translation;
@ -54,7 +54,6 @@ impl<N: Scalar, const D: usize> Translation<N, D>
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>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -73,7 +72,6 @@ impl<N: Scalar + Zero + ClosedAdd, const D: usize> One for Translation<N, D>
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: Scalar, const D: usize> Distribution<Translation<N, D>> for Standard impl<N: Scalar, const D: usize> Distribution<Translation<N, D>> for Standard
where where
// 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.
@ -86,8 +84,7 @@ where
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Translation<N, D> impl<N: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Translation<N, D>
where where
// DefaultAllocator: Allocator<N, D>, Owned<N, Const<D>>: Send,
Owned<N, D>: Send,
{ {
#[inline] #[inline]
fn arbitrary(rng: &mut Gen) -> Self { fn arbitrary(rng: &mut Gen) -> Self {

View File

@ -5,7 +5,7 @@ use simba::simd::PrimitiveSimdValue;
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::{Const, DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::base::{CVectorN, 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,
@ -28,7 +28,6 @@ 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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Translation<N2, D> { fn to_superset(&self) -> Translation<N2, D> {
@ -37,7 +36,7 @@ where
#[inline] #[inline]
fn is_in_subset(rot: &Translation<N2, D>) -> bool { fn is_in_subset(rot: &Translation<N2, D>) -> bool {
crate::is_convertible::<_, VectorN<N1, D>>(&rot.vector) crate::is_convertible::<_, CVectorN<N1, D>>(&rot.vector)
} }
#[inline] #[inline]
@ -53,7 +52,6 @@ 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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Isometry<N2, R, D> { fn to_superset(&self) -> Isometry<N2, R, D> {
@ -84,7 +82,7 @@ where
#[inline] #[inline]
fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool { fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool {
crate::is_convertible::<_, Translation<N1, _>>(&dq.translation()) crate::is_convertible::<_, Translation<N1, 3>>(&dq.translation())
&& dq.rotation() == UnitQuaternion::identity() && dq.rotation() == UnitQuaternion::identity()
} }
@ -100,7 +98,6 @@ 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>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Similarity<N2, R, D> { fn to_superset(&self) -> Similarity<N2, R, D> {
@ -160,7 +157,7 @@ where
#[inline] #[inline]
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool { fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
let id = m.fixed_slice::<DimNameSum<Const<D>, U1>, D>(0, 0); let id = m.fixed_slice::<DimNameSum<Const<D>, U1>, Const<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)) &&
@ -172,7 +169,7 @@ where
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self { fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
let t = m.fixed_slice::<D, U1>(0, D); let t = m.fixed_slice::<Const<D>, U1>(0, D);
Self { Self {
vector: crate::convert_unchecked(t.into_owned()), vector: crate::convert_unchecked(t.into_owned()),
} }
@ -207,7 +204,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Elemen
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>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 2]) -> Self { fn from(arr: [Translation<N::Element, D>; 2]) -> Self {
@ -223,7 +219,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Elemen
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>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 4]) -> Self { fn from(arr: [Translation<N::Element, D>; 4]) -> Self {
@ -241,7 +236,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Elemen
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>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 8]) -> Self { fn from(arr: [Translation<N::Element, D>; 8]) -> Self {
@ -263,7 +257,6 @@ impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Elemen
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>,
{ {
#[inline] #[inline]
fn from(arr: [Translation<N::Element, D>; 16]) -> Self { fn from(arr: [Translation<N::Element, D>; 16]) -> Self {

View File

@ -4,57 +4,65 @@ use simba::scalar::{ClosedAdd, ClosedSub};
use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::allocator::{Allocator, SameShapeAllocator};
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::base::dimension::{DimName, U1}; use crate::base::dimension::U1;
use crate::base::{DefaultAllocator, Scalar}; use crate::base::{Const, DefaultAllocator, Scalar};
use crate::geometry::{Point, Translation}; use crate::geometry::{Point, Translation};
// Translation × Translation // Translation × Translation
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + &right.vector) };
'a, 'b); 'a, 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + right.vector) };
'a); 'a);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + &right.vector) };
'b); 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + right.vector) }; ); #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + right.vector) }; );
// Translation ÷ Translation // Translation ÷ Translation
// TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? // TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method?
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - &right.vector) };
'a, 'b); 'a, 'b);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - right.vector) };
'a); 'a);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - &right.vector) };
'b); 'b);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - right.vector) }; ); #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - right.vector) }; );
@ -62,47 +70,51 @@ add_sub_impl!(Div, div, ClosedSub;
// TODO: we don't handle properly non-zero origins here. Do we want this to be the intended // TODO: we don't handle properly non-zero origins here. Do we want this to be the intended
// behavior? // behavior?
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: &'a Translation<N, D>, right: &'b Point<N, D>, Output = Point<N, D>; self: &'a Translation<N, D>, right: &'b Point<N, D>, Output = Point<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; #[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector };
'a, 'b); 'a, 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: &'a Translation<N, D>, right: Point<N, D>, Output = Point<N, D>; self: &'a Translation<N, D>, right: Point<N, D>, Output = Point<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; #[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector };
'a); 'a);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: Translation<N, D>, right: &'b Point<N, D>, Output = Point<N, D>; self: Translation<N, D>, right: &'b Point<N, D>, Output = Point<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; #[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector };
'b); 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (Const<D>, U1), (Const<D>, U1) -> (Const<D>)
const D; for; where;
self: Translation<N, D>, right: Point<N, D>, Output = Point<N, D>; self: Translation<N, D>, right: Point<N, D>, Output = Point<N, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; ); #[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; );
// Translation *= Translation // Translation *= Translation
add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd;
(D, U1), (D, U1) for D: DimName; const D;
self: Translation<N, D>, right: &'b Translation<N, D>; self: Translation<N, D>, right: &'b Translation<N, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector += &right.vector }; #[allow(clippy::suspicious_op_assign_impl)] { self.vector += &right.vector };
'b); 'b);
add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd;
(D, U1), (D, U1) for D: DimName; const D;
self: Translation<N, D>, right: Translation<N, D>; self: Translation<N, D>, right: Translation<N, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector += right.vector }; ); #[allow(clippy::suspicious_op_assign_impl)] { self.vector += right.vector }; );
add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; add_sub_assign_impl!(DivAssign, div_assign, ClosedSub;
(D, U1), (D, U1) for D: DimName; const D;
self: Translation<N, D>, right: &'b Translation<N, D>; self: Translation<N, D>, right: &'b Translation<N, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector -= &right.vector }; #[allow(clippy::suspicious_op_assign_impl)] { self.vector -= &right.vector };
'b); 'b);
add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; add_sub_assign_impl!(DivAssign, div_assign, ClosedSub;
(D, U1), (D, U1) for D: DimName; const D;
self: Translation<N, D>, right: Translation<N, D>; self: Translation<N, D>, right: Translation<N, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector -= right.vector }; ); #[allow(clippy::suspicious_op_assign_impl)] { self.vector -= right.vector }; );

View File

@ -8,7 +8,6 @@ use crate::geometry::Translation;
impl<N: Scalar + SimdValue, const D: usize> 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>,
{ {
type Element = Translation<N::Element, D>; type Element = Translation<N::Element, D>;
type SimdBool = N::SimdBool; type SimdBool = N::SimdBool;

View File

@ -1,9 +1,7 @@
use std::ops::{Div, DivAssign, Mul, MulAssign}; use std::ops::{Div, DivAssign, Mul, MulAssign};
use crate::base::allocator::Allocator;
use crate::base::dimension::{U1, U2};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Unit, Vector, Vector2}; use crate::base::{Const, Unit, Vector, Vector2};
use crate::geometry::{Isometry, Point2, Rotation, Similarity, Translation, UnitComplex}; use crate::geometry::{Isometry, Point2, Rotation, Similarity, Translation, UnitComplex};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
@ -142,12 +140,11 @@ where
macro_rules! complex_op_impl( macro_rules! complex_op_impl(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($RDim: ident, $CDim: ident) $(for $Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*; $($Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
$action: expr; $($lives: tt),*) => { $action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N: SimdRealField $(, $Storage: $StoragesBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs impl<$($lives ,)* N: SimdRealField $(, $Storage: $StoragesBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs
where N::Element: SimdRealField, where N::Element: SimdRealField {
DefaultAllocator: Allocator<N, $RDim, $CDim> {
type Output = $Result; type Output = $Result;
#[inline] #[inline]
@ -160,7 +157,7 @@ macro_rules! complex_op_impl(
macro_rules! complex_op_impl_all( macro_rules! complex_op_impl_all(
($Op: ident, $op: ident; ($Op: ident, $op: ident;
($RDim: ident, $CDim: ident) $(for $Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*; $($Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*;
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty; $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
[val val] => $action_val_val: expr; [val val] => $action_val_val: expr;
[ref val] => $action_ref_val: expr; [ref val] => $action_ref_val: expr;
@ -168,22 +165,22 @@ macro_rules! complex_op_impl_all(
[ref ref] => $action_ref_ref: expr;) => { [ref ref] => $action_ref_ref: expr;) => {
complex_op_impl!($Op, $op; complex_op_impl!($Op, $op;
($RDim, $CDim) $(for $Storage: $StoragesBound $(<$($BoundParam),*>)*),*; $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
$lhs: $Lhs, $rhs: $Rhs, Output = $Result; $lhs: $Lhs, $rhs: $Rhs, Output = $Result;
$action_val_val; ); $action_val_val; );
complex_op_impl!($Op, $op; complex_op_impl!($Op, $op;
($RDim, $CDim) $(for $Storage: $StoragesBound $(<$($BoundParam),*>)*),*; $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result; $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result;
$action_ref_val; 'a); $action_ref_val; 'a);
complex_op_impl!($Op, $op; complex_op_impl!($Op, $op;
($RDim, $CDim) $(for $Storage: $StoragesBound $(<$($BoundParam),*>)*),*; $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result; $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result;
$action_val_ref; 'b); $action_val_ref; 'b);
complex_op_impl!($Op, $op; complex_op_impl!($Op, $op;
($RDim, $CDim) $(for $Storage: $StoragesBound $(<$($BoundParam),*>)*),*; $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result; $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result;
$action_ref_ref; 'a, 'b); $action_ref_ref; 'a, 'b);
@ -194,8 +191,8 @@ macro_rules! complex_op_impl_all(
// UnitComplex × Rotation // UnitComplex × Rotation
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U2); ;
self: UnitComplex<N>, rhs: Rotation<N, U2>, Output = UnitComplex<N>; self: UnitComplex<N>, rhs: Rotation<N, 2>, Output = UnitComplex<N>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -205,8 +202,8 @@ complex_op_impl_all!(
// UnitComplex ÷ Rotation // UnitComplex ÷ Rotation
complex_op_impl_all!( complex_op_impl_all!(
Div, div; Div, div;
(U2, U2); ;
self: UnitComplex<N>, rhs: Rotation<N, U2>, Output = UnitComplex<N>; self: UnitComplex<N>, rhs: Rotation<N, 2>, Output = UnitComplex<N>;
[val val] => &self / &rhs; [val val] => &self / &rhs;
[ref val] => self / &rhs; [ref val] => self / &rhs;
[val ref] => &self / rhs; [val ref] => &self / rhs;
@ -216,8 +213,8 @@ complex_op_impl_all!(
// Rotation × UnitComplex // Rotation × UnitComplex
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U2); ;
self: Rotation<N, U2>, rhs: UnitComplex<N>, Output = UnitComplex<N>; self: Rotation<N, 2>, rhs: UnitComplex<N>, Output = UnitComplex<N>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -227,8 +224,8 @@ complex_op_impl_all!(
// Rotation ÷ UnitComplex // Rotation ÷ UnitComplex
complex_op_impl_all!( complex_op_impl_all!(
Div, div; Div, div;
(U2, U2); ;
self: Rotation<N, U2>, rhs: UnitComplex<N>, Output = UnitComplex<N>; self: Rotation<N, 2>, rhs: UnitComplex<N>, Output = UnitComplex<N>;
[val val] => &self / &rhs; [val val] => &self / &rhs;
[ref val] => self / &rhs; [ref val] => self / &rhs;
[val ref] => &self / rhs; [val ref] => &self / rhs;
@ -238,7 +235,7 @@ complex_op_impl_all!(
// UnitComplex × Point // UnitComplex × Point
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1); ;
self: UnitComplex<N>, rhs: Point2<N>, Output = Point2<N>; self: UnitComplex<N>, rhs: Point2<N>, Output = Point2<N>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
@ -249,8 +246,8 @@ complex_op_impl_all!(
// UnitComplex × Vector // UnitComplex × Vector
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1) for S: Storage<N, U2>; S: Storage<N, Const<2>>;
self: UnitComplex<N>, rhs: Vector<N, U2, S>, Output = Vector2<N>; self: UnitComplex<N>, rhs: Vector<N, Const<2>, S>, Output = Vector2<N>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -264,8 +261,8 @@ complex_op_impl_all!(
// UnitComplex × Unit<Vector> // UnitComplex × Unit<Vector>
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1) for S: Storage<N, U2>; S: Storage<N, Const<2>>;
self: UnitComplex<N>, rhs: Unit<Vector<N, U2, S>>, Output = Unit<Vector2<N>>; self: UnitComplex<N>, rhs: Unit<Vector<N, Const<2>, S>>, Output = Unit<Vector2<N>>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -275,9 +272,9 @@ complex_op_impl_all!(
// UnitComplex × Isometry<UnitComplex> // UnitComplex × Isometry<UnitComplex>
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1); ;
self: UnitComplex<N>, rhs: Isometry<N, U2, UnitComplex<N>>, self: UnitComplex<N>, rhs: Isometry<N, UnitComplex<N>, 2>,
Output = Isometry<N, U2, UnitComplex<N>>; Output = Isometry<N, UnitComplex<N>, 2>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -290,9 +287,9 @@ complex_op_impl_all!(
// UnitComplex × Similarity<UnitComplex> // UnitComplex × Similarity<UnitComplex>
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1); ;
self: UnitComplex<N>, rhs: Similarity<N, U2, UnitComplex<N>>, self: UnitComplex<N>, rhs: Similarity<N, UnitComplex<N>, 2>,
Output = Similarity<N, U2, UnitComplex<N>>; Output = Similarity<N, UnitComplex<N>, 2>;
[val val] => &self * &rhs; [val val] => &self * &rhs;
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
@ -302,9 +299,9 @@ complex_op_impl_all!(
// UnitComplex × Translation // UnitComplex × Translation
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1); ;
self: UnitComplex<N>, rhs: Translation<N, U2>, self: UnitComplex<N>, rhs: Translation<N, 2>,
Output = Isometry<N, U2, UnitComplex<N>>; Output = Isometry<N, UnitComplex<N>, 2>;
[val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self); [val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self);
[ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), *self); [ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), *self);
[val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self); [val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self);
@ -314,9 +311,9 @@ complex_op_impl_all!(
// Translation × UnitComplex // Translation × UnitComplex
complex_op_impl_all!( complex_op_impl_all!(
Mul, mul; Mul, mul;
(U2, U1); ;
self: Translation<N, U2>, right: UnitComplex<N>, self: Translation<N, 2>, right: UnitComplex<N>,
Output = Isometry<N, U2, UnitComplex<N>>; Output = Isometry<N, UnitComplex<N>, 2>;
[val val] => Isometry::from_parts(self, right); [val val] => Isometry::from_parts(self, right);
[ref val] => Isometry::from_parts(self.clone(), right); [ref val] => Isometry::from_parts(self.clone(), right);
[val ref] => Isometry::from_parts(self, *right); [val ref] => Isometry::from_parts(self, *right);
@ -366,56 +363,51 @@ where
} }
// UnitComplex ×= Rotation // UnitComplex ×= Rotation
impl<N: SimdRealField> MulAssign<Rotation<N, U2>> for UnitComplex<N> impl<N: SimdRealField> MulAssign<Rotation<N, 2>> for UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: Rotation<N, U2>) { fn mul_assign(&mut self, rhs: Rotation<N, 2>) {
*self = &*self * rhs *self = &*self * rhs
} }
} }
impl<'b, N: SimdRealField> MulAssign<&'b Rotation<N, U2>> for UnitComplex<N> impl<'b, N: SimdRealField> MulAssign<&'b Rotation<N, 2>> for UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: &'b Rotation<N, U2>) { fn mul_assign(&mut self, rhs: &'b Rotation<N, 2>) {
*self = &*self * rhs *self = &*self * rhs
} }
} }
// UnitComplex ÷= Rotation // UnitComplex ÷= Rotation
impl<N: SimdRealField> DivAssign<Rotation<N, U2>> for UnitComplex<N> impl<N: SimdRealField> DivAssign<Rotation<N, 2>> for UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: Rotation<N, U2>) { fn div_assign(&mut self, rhs: Rotation<N, 2>) {
*self = &*self / rhs *self = &*self / rhs
} }
} }
impl<'b, N: SimdRealField> DivAssign<&'b Rotation<N, U2>> for UnitComplex<N> impl<'b, N: SimdRealField> DivAssign<&'b Rotation<N, 2>> for UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: &'b Rotation<N, U2>) { fn div_assign(&mut self, rhs: &'b Rotation<N, 2>) {
*self = &*self / rhs *self = &*self / rhs
} }
} }
// Rotation ×= UnitComplex // Rotation ×= UnitComplex
impl<N: SimdRealField> MulAssign<UnitComplex<N>> for Rotation<N, U2> impl<N: SimdRealField> MulAssign<UnitComplex<N>> for Rotation<N, 2>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: UnitComplex<N>) { fn mul_assign(&mut self, rhs: UnitComplex<N>) {
@ -423,10 +415,9 @@ where
} }
} }
impl<'b, N: SimdRealField> MulAssign<&'b UnitComplex<N>> for Rotation<N, U2> impl<'b, N: SimdRealField> MulAssign<&'b UnitComplex<N>> for Rotation<N, 2>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: &'b UnitComplex<N>) { fn mul_assign(&mut self, rhs: &'b UnitComplex<N>) {
@ -435,10 +426,9 @@ where
} }
// Rotation ÷= UnitComplex // Rotation ÷= UnitComplex
impl<N: SimdRealField> DivAssign<UnitComplex<N>> for Rotation<N, U2> impl<N: SimdRealField> DivAssign<UnitComplex<N>> for Rotation<N, 2>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: UnitComplex<N>) { fn div_assign(&mut self, rhs: UnitComplex<N>) {
@ -446,10 +436,9 @@ where
} }
} }
impl<'b, N: SimdRealField> DivAssign<&'b UnitComplex<N>> for Rotation<N, U2> impl<'b, N: SimdRealField> DivAssign<&'b UnitComplex<N>> for Rotation<N, 2>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
DefaultAllocator: Allocator<N, U2, U2>,
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: &'b UnitComplex<N>) { fn div_assign(&mut self, rhs: &'b UnitComplex<N>) {

View File

@ -53,20 +53,20 @@
//! with [matrix](fn.matrix.html) as follows: //! with [matrix](fn.matrix.html) as follows:
//! //!
//! ```rust //! ```rust
//! use nalgebra::{Dynamic, MatrixMN, U3}; //! use nalgebra::{Dynamic, MatrixMN, Const};
//! use nalgebra::proptest::matrix; //! use nalgebra::proptest::matrix;
//! use proptest::prelude::*; //! use proptest::prelude::*;
//! //!
//! type MyMatrix = MatrixMN<i32, U3, Dynamic>; //! type MyMatrix = MatrixMN<i32, Const::<3>, Dynamic>;
//! //!
//! /// Returns a strategy for pairs of matrices with `U3` rows and the same number of //! /// Returns a strategy for pairs of matrices with `U3` rows and the same number of
//! /// columns. //! /// columns.
//! fn matrix_pairs() -> impl Strategy<Value=(MyMatrix, MyMatrix)> { //! fn matrix_pairs() -> impl Strategy<Value=(MyMatrix, MyMatrix)> {
//! matrix(-5 ..= 5, U3, 0 ..= 10) //! matrix(-5 ..= 5, Const::<3>, 0 ..= 10)
//! // We first generate the initial matrix `a`, and then depending on the concrete //! // We first generate the initial matrix `a`, and then depending on the concrete
//! // instances of `a`, we pick a second matrix with the same number of columns //! // instances of `a`, we pick a second matrix with the same number of columns
//! .prop_flat_map(|a| { //! .prop_flat_map(|a| {
//! let b = matrix(-5 .. 5, U3, a.ncols()); //! let b = matrix(-5 .. 5, Const::<3>, a.ncols());
//! // This returns a new tuple strategy where we keep `a` fixed while //! // This returns a new tuple strategy where we keep `a` fixed while
//! // the second item is a strategy that generates instances with the same //! // the second item is a strategy that generates instances with the same
//! // dimensions as `a` //! // dimensions as `a`
@ -141,7 +141,7 @@
//! PROPTEST_MAX_SHRINK_ITERS=100000 cargo test my_failing_test //! PROPTEST_MAX_SHRINK_ITERS=100000 cargo test my_failing_test
//! ``` //! ```
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::{DefaultAllocator, Dim, DimName, Dynamic, MatrixMN, Scalar, U1}; use crate::{Const, DefaultAllocator, Dim, DimName, Dynamic, MatrixMN, Scalar, U1};
use proptest::arbitrary::Arbitrary; use proptest::arbitrary::Arbitrary;
use proptest::collection::vec; use proptest::collection::vec;
use proptest::strategy::{BoxedStrategy, Just, NewTree, Strategy, ValueTree}; use proptest::strategy::{BoxedStrategy, Just, NewTree, Strategy, ValueTree};
@ -225,16 +225,16 @@ fn dynamic_dim_range() -> DimRange<Dynamic> {
/// ## Examples /// ## Examples
/// ``` /// ```
/// use nalgebra::proptest::matrix; /// use nalgebra::proptest::matrix;
/// use nalgebra::{MatrixMN, U3, Dynamic}; /// use nalgebra::{MatrixMN, Const, Dynamic};
/// use proptest::prelude::*; /// use proptest::prelude::*;
/// ///
/// proptest! { /// proptest! {
/// # /* /// # /*
/// #[test] /// #[test]
/// # */ /// # */
/// fn my_test(a in matrix(0 .. 5i32, U3, 0 ..= 5)) { /// fn my_test(a in matrix(0 .. 5i32, Const::<3>, 0 ..= 5)) {
/// // Let's make sure we've got the correct type first /// // Let's make sure we've got the correct type first
/// let a: MatrixMN<_, U3, Dynamic> = a; /// let a: MatrixMN<_, Const::<3>, Dynamic> = a;
/// prop_assert!(a.nrows() == 3); /// prop_assert!(a.nrows() == 3);
/// prop_assert!(a.ncols() <= 5); /// prop_assert!(a.ncols() <= 5);
/// prop_assert!(a.iter().all(|x_ij| *x_ij >= 0 && *x_ij < 5)); /// prop_assert!(a.iter().all(|x_ij| *x_ij >= 0 && *x_ij < 5));
@ -329,7 +329,7 @@ where
D: Dim, D: Dim,
DefaultAllocator: Allocator<ScalarStrategy::Value, D>, DefaultAllocator: Allocator<ScalarStrategy::Value, D>,
{ {
matrix_(value_strategy, length.into(), U1.into()) matrix_(value_strategy, length.into(), Const::<1>.into())
} }
impl<NParameters, R, C> Default for MatrixParameters<NParameters, R, C> impl<NParameters, R, C> Default for MatrixParameters<NParameters, R, C>

View File

@ -8,9 +8,7 @@ use alga::linear::{
Transformation, Transformation,
}; };
use crate::base::allocator::Allocator; use crate::base::CVectorN;
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, VectorN};
use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
@ -19,11 +17,10 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
* Algebraic structures. * Algebraic structures.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName, R> Identity<Multiplicative> impl<N: RealField + simba::scalar::RealField, R, const D: usize> Identity<Multiplicative>
for Isometry<N, D, R> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -31,11 +28,10 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> TwoSidedInverse<Multiplicative> impl<N: RealField + simba::scalar::RealField, R, const D: usize> TwoSidedInverse<Multiplicative>
for Isometry<N, D, R> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
#[must_use = "Did you mean to use two_sided_inverse_mut()?"] #[must_use = "Did you mean to use two_sided_inverse_mut()?"]
@ -49,11 +45,10 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> AbstractMagma<Multiplicative> impl<N: RealField + simba::scalar::RealField, R, const D: usize> AbstractMagma<Multiplicative>
for Isometry<N, D, R> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn operate(&self, rhs: &Self) -> Self { fn operate(&self, rhs: &Self) -> Self {
@ -63,9 +58,8 @@ where
macro_rules! impl_multiplicative_structures( macro_rules! impl_multiplicative_structures(
($($marker: ident<$operator: ident>),* $(,)*) => {$( ($($marker: ident<$operator: ident>),* $(,)*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName, R> $marker<$operator> for Isometry<N, D, R> impl<N: RealField + simba::scalar::RealField, R, const D: usize> $marker<$operator> for Isometry<N, R, D>
where R: Rotation<Point<N, D>> + AbstractRotation<N, D>, where R: Rotation<Point<N, D>> + AbstractRotation<N, D> { }
DefaultAllocator: Allocator<N, D> { }
)*} )*}
); );
@ -82,11 +76,10 @@ impl_multiplicative_structures!(
* Transformation groups. * Transformation groups.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName, R> Transformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize> Transformation<Point<N, D>>
for Isometry<N, D, R> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -94,16 +87,15 @@ 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> {
self.transform_vector(v) self.transform_vector(v)
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> ProjectiveTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize>
for Isometry<N, D, R> ProjectiveTransformation<Point<N, D>> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -111,16 +103,15 @@ where
} }
#[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> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> AffineTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize> AffineTransformation<Point<N, D>>
for Isometry<N, D, R> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
type Rotation = R; type Rotation = R;
type NonUniformScaling = Id; type NonUniformScaling = Id;
@ -175,11 +166,10 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> Similarity<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize> Similarity<Point<N, D>>
for Isometry<N, D, R> for Isometry<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
type Scaling = Id; type Scaling = Id;
@ -201,9 +191,8 @@ where
macro_rules! marker_impl( macro_rules! marker_impl(
($($Trait: ident),*) => {$( ($($Trait: ident),*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName, R> $Trait<Point<N, D>> for Isometry<N, D, R> impl<N: RealField + simba::scalar::RealField, R, const D: usize> $Trait<Point<N, D>> for Isometry<N, R, D>
where R: Rotation<Point<N, D>> + AbstractRotation<N, D>, where R: Rotation<Point<N, D>> + AbstractRotation<N, D> { }
DefaultAllocator: Allocator<N, D> { }
)*} )*}
); );

View File

@ -1,25 +1,19 @@
use alga::general::{Field, JoinSemilattice, Lattice, MeetSemilattice, RealField}; use alga::general::{Field, JoinSemilattice, Lattice, MeetSemilattice, RealField};
use alga::linear::{AffineSpace, EuclideanSpace}; use alga::linear::{AffineSpace, EuclideanSpace};
use crate::base::allocator::Allocator; use crate::base::{CVectorN, Scalar};
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, Scalar, VectorN};
use crate::geometry::Point; use crate::geometry::Point;
impl<N: Scalar + Field, D: DimName> AffineSpace for Point<N, D> impl<N: Scalar + Field, const D: usize> AffineSpace for Point<N, D>
where where
N: Scalar + Field, N: Scalar + Field,
DefaultAllocator: Allocator<N, D>,
{ {
type Translation = VectorN<N, D>; type Translation = CVectorN<N, D>;
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> EuclideanSpace for Point<N, D> impl<N: RealField + simba::scalar::RealField, const D: usize> EuclideanSpace for Point<N, D> {
where type Coordinates = CVectorN<N, D>;
DefaultAllocator: Allocator<N, D>,
{
type Coordinates = VectorN<N, D>;
type RealField = N; type RealField = N;
#[inline] #[inline]
@ -48,10 +42,9 @@ where
* Ordering * Ordering
* *
*/ */
impl<N, D: DimName> MeetSemilattice for Point<N, D> impl<N, const D: usize> MeetSemilattice for Point<N, D>
where where
N: Scalar + MeetSemilattice, N: Scalar + MeetSemilattice,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn meet(&self, other: &Self) -> Self { fn meet(&self, other: &Self) -> Self {
@ -59,10 +52,9 @@ where
} }
} }
impl<N, D: DimName> JoinSemilattice for Point<N, D> impl<N, const D: usize> JoinSemilattice for Point<N, D>
where where
N: Scalar + JoinSemilattice, N: Scalar + JoinSemilattice,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn join(&self, other: &Self) -> Self { fn join(&self, other: &Self) -> Self {
@ -70,10 +62,9 @@ where
} }
} }
impl<N, D: DimName> Lattice for Point<N, D> impl<N, const D: usize> Lattice for Point<N, D>
where where
N: Scalar + Lattice, N: Scalar + Lattice,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn meet_join(&self, other: &Self) -> (Self, Self) { fn meet_join(&self, other: &Self) -> (Self, Self) {

View File

@ -7,10 +7,7 @@ use alga::linear::{
ProjectiveTransformation, Similarity, Transformation, ProjectiveTransformation, Similarity, Transformation,
}; };
use crate::base::allocator::Allocator; use crate::base::CVectorN;
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, VectorN};
use crate::geometry::{Point, Rotation}; use crate::geometry::{Point, Rotation};
/* /*
@ -18,10 +15,8 @@ use crate::geometry::{Point, Rotation};
* Algebraic structures. * Algebraic structures.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName> Identity<Multiplicative> impl<N: RealField + simba::scalar::RealField, const D: usize> Identity<Multiplicative>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -29,10 +24,8 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> TwoSidedInverse<Multiplicative> impl<N: RealField + simba::scalar::RealField, const D: usize> TwoSidedInverse<Multiplicative>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
#[must_use = "Did you mean to use two_sided_inverse_mut()?"] #[must_use = "Did you mean to use two_sided_inverse_mut()?"]
@ -46,10 +39,8 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> AbstractMagma<Multiplicative> impl<N: RealField + simba::scalar::RealField, const D: usize> AbstractMagma<Multiplicative>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
fn operate(&self, rhs: &Self) -> Self { fn operate(&self, rhs: &Self) -> Self {
@ -59,8 +50,8 @@ where
macro_rules! impl_multiplicative_structures( macro_rules! impl_multiplicative_structures(
($($marker: ident<$operator: ident>),* $(,)*) => {$( ($($marker: ident<$operator: ident>),* $(,)*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName> $marker<$operator> for Rotation<N, D> impl<N: RealField + simba::scalar::RealField, const D: usize> $marker<$operator> for Rotation<N, D>
where DefaultAllocator: Allocator<N, D, D> { } { }
)*} )*}
); );
@ -77,10 +68,8 @@ impl_multiplicative_structures!(
* Transformation groups. * Transformation groups.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName> Transformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> Transformation<Point<N, D>>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
#[inline] #[inline]
fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -88,15 +77,13 @@ 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> {
self.transform_vector(v) self.transform_vector(v)
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> ProjectiveTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> ProjectiveTransformation<Point<N, D>>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
#[inline] #[inline]
fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -104,15 +91,13 @@ where
} }
#[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> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> AffineTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> AffineTransformation<Point<N, D>>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
type Rotation = Self; type Rotation = Self;
type NonUniformScaling = Id; type NonUniformScaling = Id;
@ -154,9 +139,8 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> Similarity<Point<N, D>> for Rotation<N, D> impl<N: RealField + simba::scalar::RealField, const D: usize> Similarity<Point<N, D>>
where for Rotation<N, D>
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
type Scaling = Id; type Scaling = Id;
@ -178,19 +162,16 @@ where
macro_rules! marker_impl( macro_rules! marker_impl(
($($Trait: ident),*) => {$( ($($Trait: ident),*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName> $Trait<Point<N, D>> for Rotation<N, D> impl<N: RealField + simba::scalar::RealField, const D: usize> $Trait<Point<N, D>> for Rotation<N, D>
where DefaultAllocator: Allocator<N, D, D> + { }
Allocator<N, D> { }
)*} )*}
); );
marker_impl!(Isometry, DirectIsometry, OrthogonalTransformation); marker_impl!(Isometry, DirectIsometry, OrthogonalTransformation);
/// Subgroups of the n-dimensional rotation group `SO(n)`. /// Subgroups of the n-dimensional rotation group `SO(n)`.
impl<N: RealField + simba::scalar::RealField, D: DimName> linear::Rotation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> linear::Rotation<Point<N, D>>
for Rotation<N, D> for Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
#[inline] #[inline]
fn powf(&self, _: N) -> Option<Self> { fn powf(&self, _: N) -> Option<Self> {
@ -200,14 +181,14 @@ where
} }
#[inline] #[inline]
fn rotation_between(_: &VectorN<N, D>, _: &VectorN<N, D>) -> Option<Self> { fn rotation_between(_: &CVectorN<N, D>, _: &CVectorN<N, D>) -> Option<Self> {
// XXX: Add the general case. // XXX: Add the general case.
// XXX: Use specialization for 2D and 3D. // XXX: Use specialization for 2D and 3D.
unimplemented!() unimplemented!()
} }
#[inline] #[inline]
fn scaled_rotation_between(_: &VectorN<N, D>, _: &VectorN<N, D>, _: N) -> Option<Self> { fn scaled_rotation_between(_: &CVectorN<N, D>, _: &CVectorN<N, D>, _: N) -> Option<Self> {
// XXX: Add the general case. // XXX: Add the general case.
// XXX: Use specialization for 2D and 3D. // XXX: Use specialization for 2D and 3D.
unimplemented!() unimplemented!()

View File

@ -5,10 +5,7 @@ use alga::general::{
use alga::linear::Similarity as AlgaSimilarity; use alga::linear::Similarity as AlgaSimilarity;
use alga::linear::{AffineTransformation, ProjectiveTransformation, Rotation, Transformation}; use alga::linear::{AffineTransformation, ProjectiveTransformation, Rotation, Transformation};
use crate::base::allocator::Allocator; use crate::base::CVectorN;
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, VectorN};
use crate::geometry::{AbstractRotation, Point, Similarity, Translation}; use crate::geometry::{AbstractRotation, Point, Similarity, Translation};
/* /*
@ -16,11 +13,10 @@ use crate::geometry::{AbstractRotation, Point, Similarity, Translation};
* Algebraic structures. * Algebraic structures.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName, R> Identity<Multiplicative> impl<N: RealField + simba::scalar::RealField, R, const D: usize> Identity<Multiplicative>
for Similarity<N, D, R> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -28,11 +24,10 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> TwoSidedInverse<Multiplicative> impl<N: RealField + simba::scalar::RealField, R, const D: usize> TwoSidedInverse<Multiplicative>
for Similarity<N, D, R> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
#[must_use = "Did you mean to use two_sided_inverse_mut()?"] #[must_use = "Did you mean to use two_sided_inverse_mut()?"]
@ -46,11 +41,10 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> AbstractMagma<Multiplicative> impl<N: RealField + simba::scalar::RealField, R, const D: usize> AbstractMagma<Multiplicative>
for Similarity<N, D, R> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn operate(&self, rhs: &Self) -> Self { fn operate(&self, rhs: &Self) -> Self {
@ -60,9 +54,9 @@ where
macro_rules! impl_multiplicative_structures( macro_rules! impl_multiplicative_structures(
($($marker: ident<$operator: ident>),* $(,)*) => {$( ($($marker: ident<$operator: ident>),* $(,)*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName, R> $marker<$operator> for Similarity<N, D, R> impl<N: RealField + simba::scalar::RealField, R, const D: usize> $marker<$operator> for Similarity<N, R, D>
where R: Rotation<Point<N, D>> + AbstractRotation<N, D>, where R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D> { } { }
)*} )*}
); );
@ -79,11 +73,10 @@ impl_multiplicative_structures!(
* Transformation groups. * Transformation groups.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName, R> Transformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize> Transformation<Point<N, D>>
for Similarity<N, D, R> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -91,16 +84,15 @@ 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> {
self.transform_vector(v) self.transform_vector(v)
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> ProjectiveTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize>
for Similarity<N, D, R> ProjectiveTransformation<Point<N, D>> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -108,16 +100,15 @@ where
} }
#[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> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> AffineTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize> AffineTransformation<Point<N, D>>
for Similarity<N, D, R> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
type NonUniformScaling = N; type NonUniformScaling = N;
type Rotation = R; type Rotation = R;
@ -171,11 +162,10 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName, R> AlgaSimilarity<Point<N, D>> impl<N: RealField + simba::scalar::RealField, R, const D: usize> AlgaSimilarity<Point<N, D>>
for Similarity<N, D, R> for Similarity<N, R, D>
where where
R: Rotation<Point<N, D>> + AbstractRotation<N, D>, R: Rotation<Point<N, D>> + AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{ {
type Scaling = N; type Scaling = N;

View File

@ -6,7 +6,7 @@ use alga::linear::{ProjectiveTransformation, Transformation};
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, VectorN}; use crate::base::{CVectorN, Const, DefaultAllocator};
use crate::geometry::{Point, SubTCategoryOf, TCategory, TProjective, Transform}; use crate::geometry::{Point, SubTCategoryOf, TCategory, TProjective, Transform};
@ -15,11 +15,12 @@ use crate::geometry::{Point, SubTCategoryOf, TCategory, TProjective, Transform};
* Algebraic structures. * Algebraic structures.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimNameAdd<U1>, C> Identity<Multiplicative> impl<N: RealField + simba::scalar::RealField, C, const D: usize> Identity<Multiplicative>
for Transform<N, D, C> for Transform<N, C, D>
where where
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 identity() -> Self { fn identity() -> Self {
@ -27,11 +28,12 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimNameAdd<U1>, C> TwoSidedInverse<Multiplicative> impl<N: RealField + simba::scalar::RealField, C, const D: usize> TwoSidedInverse<Multiplicative>
for Transform<N, D, C> for 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>>,
{ {
#[inline] #[inline]
#[must_use = "Did you mean to use two_sided_inverse_mut()?"] #[must_use = "Did you mean to use two_sided_inverse_mut()?"]
@ -45,11 +47,12 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimNameAdd<U1>, C> AbstractMagma<Multiplicative> impl<N: RealField + simba::scalar::RealField, C, const D: usize> AbstractMagma<Multiplicative>
for Transform<N, D, C> for Transform<N, C, D>
where where
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 operate(&self, rhs: &Self) -> Self { fn operate(&self, rhs: &Self) -> Self {
@ -59,17 +62,21 @@ where
macro_rules! impl_multiplicative_structures( macro_rules! impl_multiplicative_structures(
($($marker: ident<$operator: ident>),* $(,)*) => {$( ($($marker: ident<$operator: ident>),* $(,)*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimNameAdd<U1>, C> $marker<$operator> for Transform<N, D, C> impl<N: RealField + simba::scalar::RealField, C, const D: usize> $marker<$operator> for Transform<N, C, D>
where C: TCategory, where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> { } Const<D>: DimNameAdd<U1>,
C: TCategory,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> { }
)*} )*}
); );
macro_rules! impl_inversible_multiplicative_structures( macro_rules! impl_inversible_multiplicative_structures(
($($marker: ident<$operator: ident>),* $(,)*) => {$( ($($marker: ident<$operator: ident>),* $(,)*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimNameAdd<U1>, C> $marker<$operator> for Transform<N, D, C> impl<N: RealField + simba::scalar::RealField, C, const D: usize> $marker<$operator> for Transform<N, C, D>
where C: SubTCategoryOf<TProjective>, where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> { } Const<D>: DimNameAdd<U1>,
C: SubTCategoryOf<TProjective>,
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> { }
)*} )*}
); );
@ -89,14 +96,13 @@ impl_inversible_multiplicative_structures!(
* Transformation groups. * Transformation groups.
* *
*/ */
impl<N, D: DimNameAdd<U1>, C> Transformation<Point<N, D>> for Transform<N, D, C> impl<N, C, const D: usize> Transformation<Point<N, D>> for Transform<N, C, D>
where where
Const<D>: DimNameAdd<U1>,
N: RealField + simba::scalar::RealField, N: RealField + simba::scalar::RealField,
C: TCategory, C: TCategory,
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>,
{ {
#[inline] #[inline]
fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -104,19 +110,18 @@ 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> {
self.transform_vector(v) self.transform_vector(v)
} }
} }
impl<N, D: DimNameAdd<U1>, C> ProjectiveTransformation<Point<N, D>> for Transform<N, D, C> impl<N, C, const D: usize> ProjectiveTransformation<Point<N, D>> for Transform<N, C, D>
where where
Const<D>: DimNameAdd<U1>,
N: RealField + simba::scalar::RealField, N: RealField + simba::scalar::RealField,
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>,
{ {
#[inline] #[inline]
fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -124,17 +129,17 @@ where
} }
#[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> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
} }
// TODO: we need to implement an SVD for this. // TODO: we need to implement an SVD for this.
// //
// impl<N, D: DimNameAdd<U1>, C> AffineTransformation<Point<N, D>> for Transform<N, D, C> // impl<N, C, const D: usize> AffineTransformation<Point<N, D>> for Transform<N, C, D>
// where N: RealField, // where N: RealField,
// C: SubTCategoryOf<TAffine>, // C: SubTCategoryOf<TAffine>,
// DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> + // DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> +
// Allocator<N, D, D> + // Allocator<N, D, D> +
// Allocator<N, D> { // Allocator<N, D> {
// type PreRotation = Rotation<N, D>; // type PreRotation = Rotation<N, D>;

View File

@ -8,10 +8,7 @@ use alga::linear::{
Transformation, Transformation,
}; };
use crate::base::allocator::Allocator; use crate::base::CVectorN;
use crate::base::dimension::DimName;
use crate::base::{DefaultAllocator, VectorN};
use crate::geometry::{Point, Translation}; use crate::geometry::{Point, Translation};
/* /*
@ -19,10 +16,8 @@ use crate::geometry::{Point, Translation};
* Algebraic structures. * Algebraic structures.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName> Identity<Multiplicative> impl<N: RealField + simba::scalar::RealField, const D: usize> Identity<Multiplicative>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -30,10 +25,8 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> TwoSidedInverse<Multiplicative> impl<N: RealField + simba::scalar::RealField, const D: usize> TwoSidedInverse<Multiplicative>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
#[must_use = "Did you mean to use two_sided_inverse_mut()?"] #[must_use = "Did you mean to use two_sided_inverse_mut()?"]
@ -47,10 +40,8 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> AbstractMagma<Multiplicative> impl<N: RealField + simba::scalar::RealField, const D: usize> AbstractMagma<Multiplicative>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn operate(&self, rhs: &Self) -> Self { fn operate(&self, rhs: &Self) -> Self {
@ -60,8 +51,8 @@ where
macro_rules! impl_multiplicative_structures( macro_rules! impl_multiplicative_structures(
($($marker: ident<$operator: ident>),* $(,)*) => {$( ($($marker: ident<$operator: ident>),* $(,)*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName> $marker<$operator> for Translation<N, D> impl<N: RealField + simba::scalar::RealField, const D: usize> $marker<$operator> for Translation<N, D>
where DefaultAllocator: Allocator<N, D> { } { }
)*} )*}
); );
@ -78,10 +69,8 @@ impl_multiplicative_structures!(
* Transformation groups. * Transformation groups.
* *
*/ */
impl<N: RealField + simba::scalar::RealField, D: DimName> Transformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> Transformation<Point<N, D>>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -89,15 +78,13 @@ 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> {
v.clone() v.clone()
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> ProjectiveTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> ProjectiveTransformation<Point<N, D>>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> { fn inverse_transform_point(&self, pt: &Point<N, D>) -> Point<N, D> {
@ -105,15 +92,13 @@ where
} }
#[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> {
v.clone() v.clone()
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> AffineTransformation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> AffineTransformation<Point<N, D>>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
type Rotation = Id; type Rotation = Id;
type NonUniformScaling = Id; type NonUniformScaling = Id;
@ -155,10 +140,8 @@ where
} }
} }
impl<N: RealField + simba::scalar::RealField, D: DimName> Similarity<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> Similarity<Point<N, D>>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
type Scaling = Id; type Scaling = Id;
@ -180,26 +163,24 @@ where
macro_rules! marker_impl( macro_rules! marker_impl(
($($Trait: ident),*) => {$( ($($Trait: ident),*) => {$(
impl<N: RealField + simba::scalar::RealField, D: DimName> $Trait<Point<N, D>> for Translation<N, D> impl<N: RealField + simba::scalar::RealField, const D: usize> $Trait<Point<N, D>> for Translation<N, D>
where DefaultAllocator: Allocator<N, D> { } { }
)*} )*}
); );
marker_impl!(Isometry, DirectIsometry); marker_impl!(Isometry, DirectIsometry);
/// Subgroups of the n-dimensional translation group `T(n)`. /// Subgroups of the n-dimensional translation group `T(n)`.
impl<N: RealField + simba::scalar::RealField, D: DimName> AlgaTranslation<Point<N, D>> impl<N: RealField + simba::scalar::RealField, const D: usize> AlgaTranslation<Point<N, D>>
for Translation<N, D> for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn to_vector(&self) -> VectorN<N, D> { fn to_vector(&self) -> CVectorN<N, D> {
self.vector.clone() self.vector.clone()
} }
#[inline] #[inline]
fn from_vector(v: VectorN<N, D>) -> Option<Self> { fn from_vector(v: CVectorN<N, D>) -> Option<Self> {
Some(Self::from(v)) Some(Self::from(v))
} }

View File

@ -287,12 +287,12 @@ fn matrix_slice_from_matrix_ref() {
($mref:expr) => { ($mref:expr) => {
MatrixSlice::<_, U3, U4, U1, U3>::from($mref) MatrixSlice::<_, U3, U4, U1, U3>::from($mref)
}; };
}; }
macro_rules! fixed_slice_mut { macro_rules! fixed_slice_mut {
($mref:expr) => { ($mref:expr) => {
MatrixSliceMut::<_, U3, U4, U1, U3>::from($mref) MatrixSliceMut::<_, U3, U4, U1, U3>::from($mref)
}; };
}; }
// TODO: The `into_owned()` is a result of `PartialEq` not being implemented for different // TODO: The `into_owned()` is a result of `PartialEq` not being implemented for different
// Self and RHS. See issue #674. Once this is implemented, we can remove `into_owned` // Self and RHS. See issue #674. Once this is implemented, we can remove `into_owned`

View File

@ -838,17 +838,16 @@ fn swizzle() {
mod transposition_tests { mod transposition_tests {
use super::*; use super::*;
use crate::proptest::{dmatrix, matrix, vector4, PROPTEST_F64}; use crate::proptest::{dmatrix, matrix, vector4, PROPTEST_F64};
use na::{U2, U3, U4, U6};
use proptest::{prop_assert, prop_assert_eq, proptest}; use proptest::{prop_assert, prop_assert_eq, proptest};
proptest! { proptest! {
#[test] #[test]
fn transpose_transpose_is_self(m in matrix(PROPTEST_F64, U2, U3)) { fn transpose_transpose_is_self(m in matrix(PROPTEST_F64, Const::<2>, Const::<3>)) {
prop_assert_eq!(m.transpose().transpose(), m) prop_assert_eq!(m.transpose().transpose(), m)
} }
#[test] #[test]
fn transpose_mut_transpose_mut_is_self(m in matrix(PROPTEST_F64, U3, U3)) { fn transpose_mut_transpose_mut_is_self(m in matrix(PROPTEST_F64, Const::<3>, Const::<3>)) {
let mut mm = m; let mut mm = m;
mm.transpose_mut(); mm.transpose_mut();
mm.transpose_mut(); mm.transpose_mut();
@ -875,7 +874,7 @@ mod transposition_tests {
} }
#[test] #[test]
fn tr_mul_is_transpose_then_mul(m in matrix(PROPTEST_F64, U4, U6), v in vector4()) { fn tr_mul_is_transpose_then_mul(m in matrix(PROPTEST_F64, Const::<4>, Const::<6>), v in vector4()) {
prop_assert!(relative_eq!(m.transpose() * v, m.tr_mul(&v), epsilon = 1.0e-7)) prop_assert!(relative_eq!(m.transpose() * v, m.tr_mul(&v), epsilon = 1.0e-7))
} }
} }

View File

@ -4,7 +4,7 @@ macro_rules! gen_tests(
($module: ident, $scalar: ty) => { ($module: ident, $scalar: ty) => {
mod $module { mod $module {
use na::debug::RandomSDP; use na::debug::RandomSDP;
use na::dimension::{U4, Const, Dynamic}; use na::dimension::{Const, Dynamic};
use na::{DMatrix, DVector, Matrix4x3, Vector4}; use na::{DMatrix, DVector, Matrix4x3, Vector4};
use rand::random; use rand::random;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;

View File

@ -8,7 +8,7 @@ use nalgebra::proptest::{DimRange, MatrixStrategy};
use nalgebra::{ use nalgebra::{
DMatrix, DVector, DefaultAllocator, Dim, DualQuaternion, Isometry2, Isometry3, Matrix3, DMatrix, DVector, DefaultAllocator, Dim, DualQuaternion, Isometry2, Isometry3, Matrix3,
MatrixMN, Point2, Point3, Quaternion, Rotation2, Rotation3, Scalar, Similarity3, Translation2, MatrixMN, Point2, Point3, Quaternion, Rotation2, Rotation3, Scalar, Similarity3, Translation2,
Translation3, UnitComplex, UnitDualQuaternion, UnitQuaternion, Vector3, U2, U3, U4, U7, U8, Translation3, UnitComplex, UnitDualQuaternion, UnitQuaternion, Vector3, U3, U4,
}; };
use num_complex::Complex; use num_complex::Complex;
use proptest::prelude::*; use proptest::prelude::*;
@ -62,7 +62,7 @@ pub fn isometry3() -> impl Strategy<Value = Isometry3<f64>> {
// } // }
pub fn similarity3() -> impl Strategy<Value = Similarity3<f64>> { pub fn similarity3() -> impl Strategy<Value = Similarity3<f64>> {
vector(PROPTEST_F64, U7) vector(PROPTEST_F64, Const::<7>)
.prop_map(|v| Similarity3::new(v.xyz(), Vector3::new(v[3], v[4], v[5]), v[6])) .prop_map(|v| Similarity3::new(v.xyz(), Vector3::new(v[3], v[4], v[5]), v[6]))
} }
@ -71,7 +71,7 @@ pub fn unit_dual_quaternion() -> impl Strategy<Value = UnitDualQuaternion<f64>>
} }
pub fn dual_quaternion() -> impl Strategy<Value = DualQuaternion<f64>> { pub fn dual_quaternion() -> impl Strategy<Value = DualQuaternion<f64>> {
vector(PROPTEST_F64, U8).prop_map(|v| { vector(PROPTEST_F64, Const::<8>).prop_map(|v| {
DualQuaternion::from_real_and_dual( DualQuaternion::from_real_and_dual(
Quaternion::new(v[0], v[1], v[2], v[3]), Quaternion::new(v[0], v[1], v[2], v[3]),
Quaternion::new(v[4], v[5], v[6], v[7]), Quaternion::new(v[4], v[5], v[6], v[7]),
@ -88,7 +88,7 @@ pub fn unit_quaternion() -> impl Strategy<Value = UnitQuaternion<f64>> {
} }
pub fn complex_f64() -> impl Strategy<Value = Complex<f64>> + Clone { pub fn complex_f64() -> impl Strategy<Value = Complex<f64>> + Clone {
vector(PROPTEST_F64, U2).prop_map(|v| Complex::new(v.x, v.y)) vector(PROPTEST_F64, Const::<2>).prop_map(|v| Complex::new(v.x, v.y))
} }
pub fn dmatrix() -> impl Strategy<Value = DMatrix<f64>> { pub fn dmatrix() -> impl Strategy<Value = DMatrix<f64>> {
@ -120,42 +120,41 @@ where
// } // }
macro_rules! define_strategies( macro_rules! define_strategies(
($($strategy_: ident $strategy: ident<$nrows: ident, $ncols: ident>),*) => {$( ($($strategy_: ident $strategy: ident<$nrows: literal, $ncols: literal>),*) => {$(
pub fn $strategy() -> impl Strategy<Value = MatrixMN<f64, $nrows, $ncols>> { pub fn $strategy() -> impl Strategy<Value = MatrixMN<f64, Const<$nrows>, Const<$ncols>>> {
matrix(PROPTEST_F64, $nrows, $ncols) matrix(PROPTEST_F64, Const::<$nrows>, Const::<$ncols>)
} }
pub fn $strategy_<ScalarStrategy>(scalar_strategy: ScalarStrategy) -> impl Strategy<Value = MatrixMN<ScalarStrategy::Value, $nrows, $ncols>> pub fn $strategy_<ScalarStrategy>(scalar_strategy: ScalarStrategy) -> impl Strategy<Value = MatrixMN<ScalarStrategy::Value, Const<$nrows>, Const<$ncols>>>
where where
ScalarStrategy: Strategy + Clone + 'static, ScalarStrategy: Strategy + Clone + 'static,
ScalarStrategy::Value: Scalar, ScalarStrategy::Value: Scalar, {
DefaultAllocator: Allocator<ScalarStrategy::Value, $nrows, $ncols> { matrix(scalar_strategy, Const::<$nrows>, Const::<$ncols>)
matrix(scalar_strategy, $nrows, $ncols)
} }
)*} )*}
); );
define_strategies!( define_strategies!(
matrix1_ matrix1<U1, U1>, matrix1_ matrix1<1, 1>,
matrix2_ matrix2<U2, U2>, matrix2_ matrix2<2, 2>,
matrix3_ matrix3<U3, U3>, matrix3_ matrix3<3, 3>,
matrix4_ matrix4<U4, U4>, matrix4_ matrix4<4, 4>,
matrix5_ matrix5<U5, U5>, matrix5_ matrix5<5, 5>,
matrix6_ matrix6<U6, U6>, matrix6_ matrix6<6, 6>,
matrix5x2_ matrix5x2<U5, U2>, matrix5x2_ matrix5x2<5, 2>,
matrix2x5_ matrix2x5<U2, U5>, matrix2x5_ matrix2x5<2, 5>,
matrix5x3_ matrix5x3<U5, U3>, matrix5x3_ matrix5x3<5, 3>,
matrix3x5_ matrix3x5<U3, U5>, matrix3x5_ matrix3x5<3, 5>,
matrix5x4_ matrix5x4<U5, U4>, matrix5x4_ matrix5x4<5, 4>,
matrix4x5_ matrix4x5<U4, U5>, matrix4x5_ matrix4x5<4, 5>,
vector1_ vector1<U1, U1>, vector1_ vector1<1, 1>,
vector2_ vector2<U2, U1>, vector2_ vector2<2, 1>,
vector3_ vector3<U3, U1>, vector3_ vector3<3, 1>,
vector4_ vector4<U4, U1>, vector4_ vector4<4, 1>,
vector5_ vector5<U5, U1>, vector5_ vector5<5, 1>,
vector6_ vector6<U6, U1> vector6_ vector6<6, 1>
); );
/// Generate a proptest that tests that all matrices generated with the /// Generate a proptest that tests that all matrices generated with the
@ -180,16 +179,16 @@ macro_rules! generate_matrix_sanity_test {
} }
// Test all fixed-size matrices with row/col dimensions up to 3 // Test all fixed-size matrices with row/col dimensions up to 3
generate_matrix_sanity_test!(test_matrix_u0_u0, U0, U0); generate_matrix_sanity_test!(test_matrix_u0_u0, Const::<0>, Const::<0>);
generate_matrix_sanity_test!(test_matrix_u1_u0, U1, U0); generate_matrix_sanity_test!(test_matrix_u1_u0, Const::<1>, Const::<0>);
generate_matrix_sanity_test!(test_matrix_u0_u1, U0, U1); generate_matrix_sanity_test!(test_matrix_u0_u1, Const::<0>, Const::<1>);
generate_matrix_sanity_test!(test_matrix_u1_u1, U1, U1); generate_matrix_sanity_test!(test_matrix_u1_u1, Const::<1>, Const::<1>);
generate_matrix_sanity_test!(test_matrix_u2_u1, U2, U1); generate_matrix_sanity_test!(test_matrix_u2_u1, Const::<2>, Const::<1>);
generate_matrix_sanity_test!(test_matrix_u1_u2, U1, U2); generate_matrix_sanity_test!(test_matrix_u1_u2, Const::<1>, Const::<2>);
generate_matrix_sanity_test!(test_matrix_u2_u2, U2, U2); generate_matrix_sanity_test!(test_matrix_u2_u2, Const::<2>, Const::<2>);
generate_matrix_sanity_test!(test_matrix_u3_u2, U3, U2); generate_matrix_sanity_test!(test_matrix_u3_u2, Const::<3>, Const::<2>);
generate_matrix_sanity_test!(test_matrix_u2_u3, U2, U3); generate_matrix_sanity_test!(test_matrix_u2_u3, Const::<2>, Const::<3>);
generate_matrix_sanity_test!(test_matrix_u3_u3, U3, U3); generate_matrix_sanity_test!(test_matrix_u3_u3, Const::<3>, Const::<3>);
// Similarly test all heap-allocated but fixed dim ranges // Similarly test all heap-allocated but fixed dim ranges
generate_matrix_sanity_test!(test_matrix_0_0, 0, 0); generate_matrix_sanity_test!(test_matrix_0_0, 0, 0);
@ -204,18 +203,18 @@ generate_matrix_sanity_test!(test_matrix_2_3, 2, 3);
generate_matrix_sanity_test!(test_matrix_3_3, 3, 3); generate_matrix_sanity_test!(test_matrix_3_3, 3, 3);
// Test arbitrary inputs // Test arbitrary inputs
generate_matrix_sanity_test!(test_matrix_input_1, U5, 1..=5); generate_matrix_sanity_test!(test_matrix_input_1, Const::<5>, 1..=5);
generate_matrix_sanity_test!(test_matrix_input_2, 3..=4, 1..=5); generate_matrix_sanity_test!(test_matrix_input_2, 3..=4, 1..=5);
generate_matrix_sanity_test!(test_matrix_input_3, 1..=2, U3); generate_matrix_sanity_test!(test_matrix_input_3, 1..=2, Const::<3>);
generate_matrix_sanity_test!(test_matrix_input_4, 3, U4); generate_matrix_sanity_test!(test_matrix_input_4, 3, Const::<4>);
#[test] #[test]
fn test_matrix_output_types() { fn test_matrix_output_types() {
// Test that the dimension types are correct for the given inputs // Test that the dimension types are correct for the given inputs
let _: MatrixStrategy<_, U3, U4> = matrix(-5..5, U3, U4); let _: MatrixStrategy<_, U3, U4> = matrix(-5..5, Const::<3>, Const::<4>);
let _: MatrixStrategy<_, U3, U3> = matrix(-5..5, U3, U3); let _: MatrixStrategy<_, U3, U3> = matrix(-5..5, Const::<3>, Const::<3>);
let _: MatrixStrategy<_, U3, Dynamic> = matrix(-5..5, U3, 1..=5); let _: MatrixStrategy<_, U3, Dynamic> = matrix(-5..5, Const::<3>, 1..=5);
let _: MatrixStrategy<_, Dynamic, U3> = matrix(-5..5, 1..=5, U3); let _: MatrixStrategy<_, Dynamic, U3> = matrix(-5..5, 1..=5, Const::<3>);
let _: MatrixStrategy<_, Dynamic, Dynamic> = matrix(-5..5, 1..=5, 1..=5); let _: MatrixStrategy<_, Dynamic, Dynamic> = matrix(-5..5, 1..=5, 1..=5);
} }