First pass to migrate the geometry module to const-generics.
This commit is contained in:
parent
35ec135d2c
commit
8abbb35b40
|
@ -4,8 +4,7 @@ use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use crate::base::vec_storage::VecStorage;
|
use crate::base::vec_storage::VecStorage;
|
||||||
use crate::base::Matrix;
|
use crate::base::{Const, Matrix, Unit};
|
||||||
use crate::base::Unit;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -24,11 +23,14 @@ pub type MatrixNM<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
|
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
|
||||||
|
pub type CMatrixMN<N, const R: usize, const C: usize> =
|
||||||
|
Matrix<N, Const<R>, Const<C>, Owned<N, Const<R>, Const<C>>>;
|
||||||
|
|
||||||
/// A statically sized column-major square matrix with `D` rows and columns.
|
/// A statically sized column-major square matrix with `D` rows and columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixN<N, D> = Matrix<N, D, D, Owned<N, D, D>>;
|
pub type MatrixN<N, D> = Matrix<N, D, D, Owned<N, D, D>>;
|
||||||
|
pub type CMatrixN<N, const D: usize> = Matrix<N, Const<D>, Const<D>, Owned<N, Const<D>, Const<D>>>;
|
||||||
|
|
||||||
/// A dynamically sized column-major matrix.
|
/// A dynamically sized column-major matrix.
|
||||||
///
|
///
|
||||||
|
@ -266,6 +268,7 @@ pub type DVector<N> = Matrix<N, Dynamic, U1, VecStorage<N, Dynamic, U1>>;
|
||||||
|
|
||||||
/// A statically sized D-dimensional column vector.
|
/// A statically sized D-dimensional column vector.
|
||||||
pub type VectorN<N, D> = Matrix<N, D, U1, Owned<N, D, U1>>;
|
pub type VectorN<N, D> = Matrix<N, D, U1, Owned<N, D, U1>>;
|
||||||
|
pub type CVectorN<N, const D: usize> = Matrix<N, Const<D>, U1, Owned<N, Const<D>, U1>>;
|
||||||
|
|
||||||
/// A stack-allocated, 1-dimensional column vector.
|
/// A stack-allocated, 1-dimensional column vector.
|
||||||
pub type Vector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>;
|
pub type Vector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>;
|
||||||
|
|
|
@ -416,8 +416,8 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_point(
|
pub fn transform_point(
|
||||||
&self,
|
&self,
|
||||||
pt: &Point<N, DimNameDiff<D, U1>>,
|
pt: &Point<N, { DimNameDiff::<D, U1>::USIZE }>,
|
||||||
) -> Point<N, DimNameDiff<D, U1>> {
|
) -> Point<N, { DimNameDiff::<D, U1>::USIZE }> {
|
||||||
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
|
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
|
||||||
let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1);
|
let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1);
|
||||||
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);
|
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);
|
||||||
|
|
|
@ -201,6 +201,8 @@ pub struct Const<const R: usize>;
|
||||||
|
|
||||||
/// Trait implemented exclusively by type-level integers.
|
/// Trait implemented exclusively by type-level integers.
|
||||||
pub trait DimName: Dim {
|
pub trait DimName: Dim {
|
||||||
|
const USIZE: usize;
|
||||||
|
|
||||||
/// The name of this dimension, i.e., the singleton `Self`.
|
/// The name of this dimension, i.e., the singleton `Self`.
|
||||||
fn name() -> Self;
|
fn name() -> Self;
|
||||||
|
|
||||||
|
@ -233,6 +235,8 @@ impl<const T: usize> Dim for Const<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const T: usize> DimName for Const<T> {
|
impl<const T: usize> DimName for Const<T> {
|
||||||
|
const USIZE: usize = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn name() -> Self {
|
fn name() -> Self {
|
||||||
Self
|
Self
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::allocator::Allocator;
|
|
||||||
use crate::geometry::{Rotation, UnitComplex, UnitQuaternion};
|
use crate::geometry::{Rotation, UnitComplex, UnitQuaternion};
|
||||||
use crate::{DefaultAllocator, DimName, Point, Scalar, SimdRealField, Unit, VectorN, U2, U3};
|
use crate::{CVectorN, Const, Point, Scalar, SimdRealField, Unit, VectorN};
|
||||||
|
|
||||||
use simba::scalar::ClosedMul;
|
use simba::scalar::ClosedMul;
|
||||||
|
|
||||||
/// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`.
|
/// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`.
|
||||||
pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone {
|
pub trait AbstractRotation<N: Scalar, const D: usize>: PartialEq + ClosedMul + Clone {
|
||||||
/// The rotation identity.
|
/// The rotation identity.
|
||||||
fn identity() -> Self;
|
fn identity() -> Self;
|
||||||
/// The rotation inverse.
|
/// The rotation inverse.
|
||||||
|
@ -13,34 +12,34 @@ pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone
|
||||||
/// Change `self` to its inverse.
|
/// Change `self` to its inverse.
|
||||||
fn inverse_mut(&mut self);
|
fn inverse_mut(&mut self);
|
||||||
/// Apply the rotation to the given vector.
|
/// Apply the rotation to the given vector.
|
||||||
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>;
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>;
|
// DefaultAllocator: Allocator<N, D>;
|
||||||
/// Apply the rotation to the given point.
|
/// Apply the rotation to the given point.
|
||||||
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>;
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>;
|
// DefaultAllocator: Allocator<N, D>;
|
||||||
/// Apply the inverse rotation to the given vector.
|
/// Apply the inverse rotation to the given vector.
|
||||||
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn inverse_transform_vector(&self, v: &VectorN<N, Const<D>>) -> VectorN<N, Const<D>>;
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>;
|
// DefaultAllocator: Allocator<N, D>;
|
||||||
/// Apply the inverse rotation to the given unit vector.
|
/// Apply the inverse rotation to the given unit vector.
|
||||||
fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>>
|
fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
||||||
}
|
}
|
||||||
/// Apply the inverse rotation to the given point.
|
/// Apply the inverse rotation to the given point.
|
||||||
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>;
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>;
|
// DefaultAllocator: Allocator<N, D>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName> AbstractRotation<N, D> for Rotation<N, D>
|
impl<N: SimdRealField, const D: usize> AbstractRotation<N, D> for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Self {
|
fn identity() -> Self {
|
||||||
|
@ -58,47 +57,47 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
self * p
|
self * p
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
self.inverse_transform_vector(v)
|
self.inverse_transform_vector(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>>
|
fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
self.inverse_transform_unit_vector(v)
|
self.inverse_transform_unit_vector(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
self.inverse_transform_point(p)
|
self.inverse_transform_point(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> AbstractRotation<N, U3> for UnitQuaternion<N>
|
impl<N: SimdRealField> AbstractRotation<N, 3> for UnitQuaternion<N>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
|
@ -118,27 +117,27 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vector(&self, v: &VectorN<N, U3>) -> VectorN<N, U3> {
|
fn transform_vector(&self, v: &CVectorN<N, 3>) -> CVectorN<N, 3> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_point(&self, p: &Point<N, U3>) -> Point<N, U3> {
|
fn transform_point(&self, p: &Point<N, 3>) -> Point<N, 3> {
|
||||||
self * p
|
self * p
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_vector(&self, v: &VectorN<N, U3>) -> VectorN<N, U3> {
|
fn inverse_transform_vector(&self, v: &CVectorN<N, 3>) -> CVectorN<N, 3> {
|
||||||
self.inverse_transform_vector(v)
|
self.inverse_transform_vector(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_point(&self, p: &Point<N, U3>) -> Point<N, U3> {
|
fn inverse_transform_point(&self, p: &Point<N, 3>) -> Point<N, 3> {
|
||||||
self.inverse_transform_point(p)
|
self.inverse_transform_point(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> AbstractRotation<N, U2> for UnitComplex<N>
|
impl<N: SimdRealField> AbstractRotation<N, 2> for UnitComplex<N>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
|
@ -158,22 +157,22 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vector(&self, v: &VectorN<N, U2>) -> VectorN<N, U2> {
|
fn transform_vector(&self, v: &CVectorN<N, 2>) -> CVectorN<N, 2> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_point(&self, p: &Point<N, U2>) -> Point<N, U2> {
|
fn transform_point(&self, p: &Point<N, 2>) -> Point<N, 2> {
|
||||||
self * p
|
self * p
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_vector(&self, v: &VectorN<N, U2>) -> VectorN<N, U2> {
|
fn inverse_transform_vector(&self, v: &CVectorN<N, 2>) -> CVectorN<N, 2> {
|
||||||
self.inverse_transform_vector(v)
|
self.inverse_transform_vector(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_point(&self, p: &Point<N, U2>) -> Point<N, U2> {
|
fn inverse_transform_point(&self, p: &Point<N, 2>) -> Point<N, 2> {
|
||||||
self.inverse_transform_point(p)
|
self.inverse_transform_point(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::SimdRealField;
|
use simba::simd::SimdRealField;
|
||||||
|
|
||||||
use crate::base::dimension::U3;
|
|
||||||
use crate::base::{Matrix4, Vector4};
|
use crate::base::{Matrix4, Vector4};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
DualQuaternion, Isometry3, Similarity3, SuperTCategoryOf, TAffine, Transform, Translation3,
|
DualQuaternion, Isometry3, Similarity3, SuperTCategoryOf, TAffine, Transform, Translation3,
|
||||||
|
@ -14,9 +13,9 @@ use crate::geometry::{
|
||||||
*
|
*
|
||||||
* DualQuaternion -> DualQuaternion
|
* DualQuaternion -> DualQuaternion
|
||||||
* UnitDualQuaternion -> UnitDualQuaternion
|
* UnitDualQuaternion -> UnitDualQuaternion
|
||||||
* UnitDualQuaternion -> Isometry<U3>
|
* UnitDualQuaternion -> Isometry<3>
|
||||||
* UnitDualQuaternion -> Similarity<U3>
|
* UnitDualQuaternion -> Similarity<3>
|
||||||
* UnitDualQuaternion -> Transform<U3>
|
* UnitDualQuaternion -> Transform<3>
|
||||||
* UnitDualQuaternion -> Matrix<U4> (homogeneous)
|
* UnitDualQuaternion -> Matrix<U4> (homogeneous)
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
|
@ -115,24 +114,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, C> SubsetOf<Transform<N2, U3, C>> for UnitDualQuaternion<N1>
|
impl<N1, N2, C> SubsetOf<Transform<N2, C, 3>> for UnitDualQuaternion<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, U3, C> {
|
fn to_superset(&self) -> Transform<N2, C, 3> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, U3, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, 3>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, U3, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, 3>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ use simba::scalar::{RealField, SubsetOf};
|
||||||
use simba::simd::SimdRealField;
|
use simba::simd::SimdRealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, Unit, VectorN};
|
use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar, Unit};
|
||||||
use crate::geometry::{AbstractRotation, Point, Translation};
|
use crate::geometry::{AbstractRotation, Point, Translation};
|
||||||
|
|
||||||
/// A direct isometry, i.e., a rotation followed by a translation (aka. a rigid-body motion).
|
/// A direct isometry, i.e., a rotation followed by a translation (aka. a rigid-body motion).
|
||||||
|
@ -68,9 +68,9 @@ use crate::geometry::{AbstractRotation, Point, Translation};
|
||||||
DefaultAllocator: Allocator<N, D>,
|
DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Deserialize<'de>"))
|
Owned<N, D>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
pub struct Isometry<N: Scalar, D: DimName, R>
|
pub struct Isometry<N: Scalar, R, const D: usize>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// The pure rotational part of this isometry.
|
/// The pure rotational part of this isometry.
|
||||||
pub rotation: R,
|
pub rotation: R,
|
||||||
|
@ -79,13 +79,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
impl<N, D, R> Abomonation for Isometry<N, D, R>
|
impl<N, R, const D: usize> Abomonation for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N: SimdRealField,
|
N: SimdRealField,
|
||||||
D: DimName,
|
|
||||||
R: Abomonation,
|
R: Abomonation,
|
||||||
Translation<N, D>: Abomonation,
|
Translation<N, D>: Abomonation,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
self.rotation.entomb(writer)?;
|
self.rotation.entomb(writer)?;
|
||||||
|
@ -103,11 +102,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash
|
impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Isometry<N, R, D>
|
||||||
for Isometry<N, D, R>
|
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: hash::Hash,
|
Owned<N, Const<D>>: hash::Hash,
|
||||||
{
|
{
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
self.translation.hash(state);
|
self.translation.hash(state);
|
||||||
|
@ -115,16 +113,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: DimName + Copy, R: Copy> Copy for Isometry<N, D, R>
|
impl<N: Scalar + Copy, R: Copy, const D: usize> Copy for Isometry<N, R, D> where
|
||||||
where
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
Owned<N, Const<D>>: Copy
|
||||||
Owned<N, D>: Copy,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName, R: Clone> Clone for Isometry<N, D, R>
|
impl<N: Scalar, R: Clone, const D: usize> Clone for Isometry<N, R, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -135,9 +132,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// # From the translation and rotation parts
|
/// # From the translation and rotation parts
|
||||||
impl<N: Scalar, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
|
impl<N: Scalar, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new isometry from its rotational and translational parts.
|
/// Creates a new isometry from its rotational and translational parts.
|
||||||
///
|
///
|
||||||
|
@ -163,10 +160,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Inversion and in-place composition
|
/// # Inversion and in-place composition
|
||||||
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
|
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Inverts `self`.
|
/// Inverts `self`.
|
||||||
///
|
///
|
||||||
|
@ -223,7 +220,7 @@ where
|
||||||
/// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2));
|
/// assert_eq!(iso1.inverse() * iso2, iso1.inv_mul(&iso2));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inv_mul(&self, rhs: &Isometry<N, D, R>) -> Self {
|
pub fn inv_mul(&self, rhs: &Isometry<N, R, D>) -> Self {
|
||||||
let inv_rot1 = self.rotation.inverse();
|
let inv_rot1 = self.rotation.inverse();
|
||||||
let tr_12 = rhs.translation.vector.clone() - self.translation.vector.clone();
|
let tr_12 = rhs.translation.vector.clone() - self.translation.vector.clone();
|
||||||
Isometry::from_parts(
|
Isometry::from_parts(
|
||||||
|
@ -318,10 +315,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Transformation of a vector or a point
|
/// # Transformation of a vector or a point
|
||||||
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
|
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Transform the given point by this isometry.
|
/// Transform the given point by this isometry.
|
||||||
///
|
///
|
||||||
|
@ -364,7 +361,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +407,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_point, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self.rotation.inverse_transform_vector(v)
|
self.rotation.inverse_transform_vector(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +430,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>> {
|
||||||
self.rotation.inverse_transform_unit_vector(v)
|
self.rotation.inverse_transform_unit_vector(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,9 +440,9 @@ where
|
||||||
// This is OK since all constructors of the isometry enforce the Rotation bound already (and
|
// This is OK since all constructors of the isometry enforce the Rotation bound already (and
|
||||||
// explicit struct construction is prevented by the dummy ZST field).
|
// explicit struct construction is prevented by the dummy ZST field).
|
||||||
/// # Conversion to a matrix
|
/// # Conversion to a matrix
|
||||||
impl<N: SimdRealField, D: DimName, R> Isometry<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Isometry<N, R, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Converts this isometry into its equivalent homogeneous transformation matrix.
|
/// Converts this isometry into its equivalent homogeneous transformation matrix.
|
||||||
///
|
///
|
||||||
|
@ -465,14 +462,14 @@ where
|
||||||
/// assert_relative_eq!(iso.to_homogeneous(), expected, epsilon = 1.0e-6);
|
/// assert_relative_eq!(iso.to_homogeneous(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>>
|
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>,
|
R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
let mut res: MatrixN<N, _> = crate::convert_ref(&self.rotation);
|
let mut res: MatrixN<N, _> = crate::convert_ref(&self.rotation);
|
||||||
res.fixed_slice_mut::<D, U1>(0, D::dim())
|
res.fixed_slice_mut::<Const<D>, U1>(0, D)
|
||||||
.copy_from(&self.translation.vector);
|
.copy_from(&self.translation.vector);
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -496,27 +493,25 @@ where
|
||||||
/// assert_relative_eq!(iso.to_matrix(), expected, epsilon = 1.0e-6);
|
/// assert_relative_eq!(iso.to_matrix(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_matrix(&self) -> MatrixN<N, DimNameSum<D, U1>>
|
pub fn to_matrix(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>,
|
R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
self.to_homogeneous()
|
self.to_homogeneous()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> Eq for Isometry<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Eq for Isometry<N, R, D> where
|
||||||
where
|
R: AbstractRotation<N, D> + Eq // DefaultAllocator: Allocator<N, D>,
|
||||||
R: AbstractRotation<N, D> + Eq,
|
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> PartialEq for Isometry<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> PartialEq for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + PartialEq,
|
R: AbstractRotation<N, D> + PartialEq,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, right: &Self) -> bool {
|
fn eq(&self, right: &Self) -> bool {
|
||||||
|
@ -524,10 +519,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, R> AbsDiffEq for Isometry<N, D, R>
|
impl<N: RealField, R, const D: usize> AbsDiffEq for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>,
|
R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
type Epsilon = N::Epsilon;
|
type Epsilon = N::Epsilon;
|
||||||
|
@ -544,10 +539,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, R> RelativeEq for Isometry<N, D, R>
|
impl<N: RealField, R, const D: usize> RelativeEq for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>,
|
R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -570,10 +565,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, R> UlpsEq for Isometry<N, D, R>
|
impl<N: RealField, R, const D: usize> UlpsEq for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>,
|
R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -594,10 +589,10 @@ where
|
||||||
* Display
|
* Display
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: RealField + fmt::Display, D: DimName, R> fmt::Display for Isometry<N, D, R>
|
impl<N: RealField + fmt::Display, R, const D: usize> fmt::Display for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
R: fmt::Display,
|
R: fmt::Display,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let precision = f.precision().unwrap_or(3);
|
let precision = f.precision().unwrap_or(3);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::base::dimension::{U2, U3};
|
|
||||||
|
|
||||||
use crate::geometry::{Isometry, Rotation2, Rotation3, UnitComplex, UnitQuaternion};
|
use crate::geometry::{Isometry, Rotation2, Rotation3, UnitComplex, UnitQuaternion};
|
||||||
|
|
||||||
/// A 2-dimensional direct isometry using a unit complex number for its rotational part.
|
/// A 2-dimensional direct isometry using a unit complex number for its rotational part.
|
||||||
|
@ -8,28 +6,28 @@ use crate::geometry::{Isometry, Rotation2, Rotation3, UnitComplex, UnitQuaternio
|
||||||
///
|
///
|
||||||
/// Also known as a 2D rigid-body motion, or as an element of SE(2).
|
/// Also known as a 2D rigid-body motion, or as an element of SE(2).
|
||||||
|
|
||||||
pub type Isometry2<N> = Isometry<N, U2, UnitComplex<N>>;
|
pub type Isometry2<N> = Isometry<N, UnitComplex<N>, 2>;
|
||||||
|
|
||||||
/// A 3-dimensional direct isometry using a unit quaternion for its rotational part.
|
/// A 3-dimensional direct isometry using a unit quaternion for its rotational part.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
|
||||||
///
|
///
|
||||||
/// Also known as a rigid-body motion, or as an element of SE(3).
|
/// Also known as a rigid-body motion, or as an element of SE(3).
|
||||||
pub type Isometry3<N> = Isometry<N, U3, UnitQuaternion<N>>;
|
pub type Isometry3<N> = Isometry<N, UnitQuaternion<N>, 3>;
|
||||||
|
|
||||||
/// A 2-dimensional direct isometry using a rotation matrix for its rotational part.
|
/// A 2-dimensional direct isometry using a rotation matrix for its rotational part.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
|
||||||
///
|
///
|
||||||
/// Also known as a rigid-body motion, or as an element of SE(2).
|
/// Also known as a rigid-body motion, or as an element of SE(2).
|
||||||
pub type IsometryMatrix2<N> = Isometry<N, U2, Rotation2<N>>;
|
pub type IsometryMatrix2<N> = Isometry<N, Rotation2<N>, 2>;
|
||||||
|
|
||||||
/// A 3-dimensional direct isometry using a rotation matrix for its rotational part.
|
/// A 3-dimensional direct isometry using a rotation matrix for its rotational part.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Isometry`](crate::Isometry) type too.**
|
||||||
///
|
///
|
||||||
/// Also known as a rigid-body motion, or as an element of SE(3).
|
/// Also known as a rigid-body motion, or as an element of SE(3).
|
||||||
pub type IsometryMatrix3<N> = Isometry<N, U3, Rotation3<N>>;
|
pub type IsometryMatrix3<N> = Isometry<N, Rotation3<N>, 3>;
|
||||||
|
|
||||||
// This tests that the types correctly implement `Copy`, without having to run tests
|
// This tests that the types correctly implement `Copy`, without having to run tests
|
||||||
// (when targeting no-std for example).
|
// (when targeting no-std for example).
|
||||||
|
|
|
@ -13,9 +13,8 @@ use rand::{
|
||||||
use simba::scalar::SupersetOf;
|
use simba::scalar::SupersetOf;
|
||||||
use simba::simd::SimdRealField;
|
use simba::simd::SimdRealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::dimension::U2;
|
||||||
use crate::base::dimension::{DimName, U2};
|
use crate::base::{Vector2, Vector3};
|
||||||
use crate::base::{DefaultAllocator, Vector2, Vector3};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point,
|
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point,
|
||||||
|
@ -23,10 +22,10 @@ use crate::{
|
||||||
UnitQuaternion,
|
UnitQuaternion,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
|
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity isometry.
|
/// Creates a new identity isometry.
|
||||||
///
|
///
|
||||||
|
@ -71,10 +70,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> One for Isometry<N, D, R>
|
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> One for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity isometry.
|
/// Creates a new identity isometry.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -84,26 +83,26 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
impl<N: crate::RealField, D: DimName, R> Distribution<Isometry<N, D, R>> for Standard
|
impl<N: crate::RealField, R, const D: usize> Distribution<Isometry<N, R, D>> for Standard
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
Standard: Distribution<N> + Distribution<R>,
|
Standard: Distribution<N> + Distribution<R>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, D, R> {
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, R, D> {
|
||||||
Isometry::from_parts(rng.gen(), rng.gen())
|
Isometry::from_parts(rng.gen(), rng.gen())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl<N, D: DimName, R> Arbitrary for Isometry<N, D, R>
|
impl<N, R, const D: usize> Arbitrary for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N: SimdRealField + Arbitrary + Send,
|
N: SimdRealField + Arbitrary + Send,
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: AbstractRotation<N, D> + Arbitrary + Send,
|
R: AbstractRotation<N, D> + Arbitrary + Send,
|
||||||
Owned<N, D>: Send,
|
Owned<N, D>: Send,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn arbitrary(rng: &mut Gen) -> Self {
|
fn arbitrary(rng: &mut Gen) -> Self {
|
||||||
|
|
|
@ -2,8 +2,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
|
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar};
|
use crate::base::{Const, DefaultAllocator, MatrixN, Scalar};
|
||||||
|
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
AbstractRotation, Isometry, Isometry3, Similarity, SuperTCategoryOf, TAffine, Transform,
|
AbstractRotation, Isometry, Isometry3, Similarity, SuperTCategoryOf, TAffine, Transform,
|
||||||
|
@ -21,27 +21,27 @@ use crate::geometry::{
|
||||||
* Isometry -> Matrix (homogeneous)
|
* Isometry -> Matrix (homogeneous)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R1, R2> SubsetOf<Isometry<N2, D, R2>> for Isometry<N1, D, R1>
|
impl<N1, N2, R1, R2, const D: usize> SubsetOf<Isometry<N2, R2, D>> for Isometry<N1, R1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R1: AbstractRotation<N1, D> + SubsetOf<R2>,
|
R1: AbstractRotation<N1, D> + SubsetOf<R2>,
|
||||||
R2: AbstractRotation<N2, D>,
|
R2: AbstractRotation<N2, D>,
|
||||||
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Isometry<N2, D, R2> {
|
fn to_superset(&self) -> Isometry<N2, R2, D> {
|
||||||
Isometry::from_parts(self.translation.to_superset(), self.rotation.to_superset())
|
Isometry::from_parts(self.translation.to_superset(), self.rotation.to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(iso: &Isometry<N2, D, R2>) -> bool {
|
fn is_in_subset(iso: &Isometry<N2, R2, D>) -> bool {
|
||||||
crate::is_convertible::<_, Translation<N1, D>>(&iso.translation)
|
crate::is_convertible::<_, Translation<N1, D>>(&iso.translation)
|
||||||
&& crate::is_convertible::<_, R1>(&iso.rotation)
|
&& crate::is_convertible::<_, R1>(&iso.rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(iso: &Isometry<N2, D, R2>) -> Self {
|
fn from_superset_unchecked(iso: &Isometry<N2, R2, D>) -> Self {
|
||||||
Isometry::from_parts(
|
Isometry::from_parts(
|
||||||
iso.translation.to_subset_unchecked(),
|
iso.translation.to_subset_unchecked(),
|
||||||
iso.rotation.to_subset_unchecked(),
|
iso.rotation.to_subset_unchecked(),
|
||||||
|
@ -73,102 +73,101 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R1, R2> SubsetOf<Similarity<N2, D, R2>> for Isometry<N1, D, R1>
|
impl<N1, N2, R1, R2, const D: usize> SubsetOf<Similarity<N2, R2, D>> for Isometry<N1, R1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R1: AbstractRotation<N1, D> + SubsetOf<R2>,
|
R1: AbstractRotation<N1, D> + SubsetOf<R2>,
|
||||||
R2: AbstractRotation<N2, D>,
|
R2: AbstractRotation<N2, D>,
|
||||||
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Similarity<N2, D, R2> {
|
fn to_superset(&self) -> Similarity<N2, R2, D> {
|
||||||
Similarity::from_isometry(self.to_superset(), N2::one())
|
Similarity::from_isometry(self.to_superset(), N2::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(sim: &Similarity<N2, D, R2>) -> bool {
|
fn is_in_subset(sim: &Similarity<N2, R2, D>) -> bool {
|
||||||
crate::is_convertible::<_, Isometry<N1, D, R1>>(&sim.isometry) && sim.scaling() == N2::one()
|
crate::is_convertible::<_, Isometry<N1, R1, D>>(&sim.isometry) && sim.scaling() == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(sim: &Similarity<N2, D, R2>) -> Self {
|
fn from_superset_unchecked(sim: &Similarity<N2, R2, D>) -> Self {
|
||||||
crate::convert_ref_unchecked(&sim.isometry)
|
crate::convert_ref_unchecked(&sim.isometry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D, R, C> SubsetOf<Transform<N2, D, C>> for Isometry<N1, D, R>
|
impl<N1, N2, R, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Isometry<N1, R, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
R: AbstractRotation<N1, D>
|
R: AbstractRotation<N1, D>
|
||||||
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>>
|
+ SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
|
||||||
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>,
|
+ SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
|
||||||
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal()
|
Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, D, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N1, D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<(usize, usize), D>
|
||||||
+ Allocator<(usize, usize), D>
|
// + Allocator<N2, D, D>
|
||||||
+ Allocator<N2, D, D>
|
// + Allocator<N2, D>
|
||||||
+ Allocator<N2, D>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, D, C> {
|
fn to_superset(&self) -> Transform<N2, C, D> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, D, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D, R> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Isometry<N1, D, R>
|
impl<N1, N2, R, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>
|
||||||
|
for Isometry<N1, R, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N1, D>
|
R: AbstractRotation<N1, D>
|
||||||
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>>
|
+ SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
|
||||||
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>,
|
+ SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
|
||||||
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal()
|
Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, D, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<(usize, usize), D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N2, D, D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N2, D>
|
||||||
+ Allocator<(usize, usize), D>
|
// + Allocator<N1, D>
|
||||||
+ Allocator<N2, D, D>
|
// + Allocator<N1, D, D>
|
||||||
+ Allocator<N2, D>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> {
|
fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
|
||||||
self.to_homogeneous().to_superset()
|
self.to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool {
|
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
|
||||||
let rot = m.fixed_slice::<D, D>(0, 0);
|
let rot = m.fixed_slice::<D, D>(0, 0);
|
||||||
let bottom = m.fixed_slice::<U1, D>(D::dim(), 0);
|
let bottom = m.fixed_slice::<U1, D>(D, 0);
|
||||||
|
|
||||||
// Scalar types agree.
|
// Scalar types agree.
|
||||||
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
||||||
// The block part is a rotation.
|
// The block part is a rotation.
|
||||||
rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) &&
|
rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) &&
|
||||||
// The bottom row is (0, 0, ..., 1)
|
// The bottom row is (0, 0, ..., 1)
|
||||||
bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one()
|
bottom.iter().all(|e| e.is_zero()) && m[(D, D)] == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
let t = m.fixed_slice::<D, U1>(0, D::dim()).into_owned();
|
let t = m.fixed_slice::<D, U1>(0, D).into_owned();
|
||||||
let t = Translation {
|
let t = Translation {
|
||||||
vector: crate::convert_unchecked(t),
|
vector: crate::convert_unchecked(t),
|
||||||
};
|
};
|
||||||
|
@ -177,10 +176,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> From<Translation<N, D>>
|
impl<N: SimdRealField, R: AbstractRotation<N, D>, const D: usize> From<Translation<N, D>>
|
||||||
for Isometry<N, D, R>
|
for Isometry<N, R, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(tra: Translation<N, D>) -> Self {
|
fn from(tra: Translation<N, D>) -> Self {
|
||||||
|
@ -188,30 +187,31 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> From<Isometry<N, D, R>> for MatrixN<N, DimNameSum<D, U1>>
|
impl<N: SimdRealField, R, const D: usize> From<Isometry<N, R, D>>
|
||||||
|
for MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>,
|
R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> + Allocator<N, D>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(iso: Isometry<N, D, R>) -> Self {
|
fn from(iso: Isometry<N, R, D>) -> Self {
|
||||||
iso.to_homogeneous()
|
iso.to_homogeneous()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 2]>
|
impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
|
||||||
for Isometry<N, D, R>
|
From<[Isometry<N::Element, R::Element, D>; 2]> for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 2]>,
|
N: From<[<N as SimdValue>::Element; 2]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
R::Element: Scalar + Copy,
|
R::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Isometry<N::Element, D, R::Element>; 2]) -> Self {
|
fn from(arr: [Isometry<N::Element, R::Element, D>; 2]) -> Self {
|
||||||
let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]);
|
let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]);
|
||||||
let rot = R::from([arr[0].rotation, arr[0].rotation]);
|
let rot = R::from([arr[0].rotation, arr[0].rotation]);
|
||||||
|
|
||||||
|
@ -219,18 +219,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 4]>
|
impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
|
||||||
for Isometry<N, D, R>
|
From<[Isometry<N::Element, R::Element, D>; 4]> for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 4]>,
|
N: From<[<N as SimdValue>::Element; 4]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
R::Element: Scalar + Copy,
|
R::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Isometry<N::Element, D, R::Element>; 4]) -> Self {
|
fn from(arr: [Isometry<N::Element, R::Element, D>; 4]) -> Self {
|
||||||
let tra = Translation::from([
|
let tra = Translation::from([
|
||||||
arr[0].translation.clone(),
|
arr[0].translation.clone(),
|
||||||
arr[1].translation.clone(),
|
arr[1].translation.clone(),
|
||||||
|
@ -248,18 +248,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 8]>
|
impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
|
||||||
for Isometry<N, D, R>
|
From<[Isometry<N::Element, R::Element, D>; 8]> for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 8]>,
|
N: From<[<N as SimdValue>::Element; 8]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
R::Element: Scalar + Copy,
|
R::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Isometry<N::Element, D, R::Element>; 8]) -> Self {
|
fn from(arr: [Isometry<N::Element, R::Element, D>; 8]) -> Self {
|
||||||
let tra = Translation::from([
|
let tra = Translation::from([
|
||||||
arr[0].translation.clone(),
|
arr[0].translation.clone(),
|
||||||
arr[1].translation.clone(),
|
arr[1].translation.clone(),
|
||||||
|
@ -285,18 +285,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 16]>
|
impl<N: Scalar + PrimitiveSimdValue, R, const D: usize>
|
||||||
for Isometry<N, D, R>
|
From<[Isometry<N::Element, R::Element, D>; 16]> for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 16]>,
|
N: From<[<N as SimdValue>::Element; 16]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
R::Element: Scalar + Copy,
|
R::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Isometry<N::Element, D, R::Element>; 16]) -> Self {
|
fn from(arr: [Isometry<N::Element, R::Element, D>; 16]) -> Self {
|
||||||
let tra = Translation::from([
|
let tra = Translation::from([
|
||||||
arr[0].translation.clone(),
|
arr[0].translation.clone(),
|
||||||
arr[1].translation.clone(),
|
arr[1].translation.clone(),
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
use simba::simd::SimdValue;
|
use simba::simd::SimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
|
||||||
use crate::base::dimension::DimName;
|
|
||||||
use crate::base::DefaultAllocator;
|
|
||||||
use crate::SimdRealField;
|
use crate::SimdRealField;
|
||||||
|
|
||||||
use crate::geometry::{AbstractRotation, Isometry, Translation};
|
use crate::geometry::{AbstractRotation, Isometry, Translation};
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> SimdValue for Isometry<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> SimdValue for Isometry<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>,
|
R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
type Element = Isometry<N::Element, D, R::Element>;
|
type Element = Isometry<N::Element, R::Element, D>;
|
||||||
type SimdBool = N::SimdBool;
|
type SimdBool = N::SimdBool;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -40,54 +40,49 @@ use crate::base::{Const, DefaultAllocator, Scalar, VectorN};
|
||||||
/// of said transformations for details.
|
/// of said transformations for details.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Point<N: Scalar, D: DimName>
|
pub struct Point<N: Scalar, const D: usize> {
|
||||||
where
|
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
{
|
|
||||||
/// The coordinates of this point, i.e., the shift from the origin.
|
/// The coordinates of this point, i.e., the shift from the origin.
|
||||||
pub coords: VectorN<N, D>,
|
pub coords: VectorN<N, Const<D>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash> hash::Hash for Point<N, D>
|
impl<N: Scalar + hash::Hash, const D: usize> hash::Hash for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
<DefaultAllocator as Allocator<N, D>>::Buffer: hash::Hash,
|
// <DefaultAllocator as Allocator<N, D>>::Buffer: hash::Hash,
|
||||||
{
|
{
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
self.coords.hash(state)
|
self.coords.hash(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: DimName> Copy for Point<N, D>
|
impl<N: Scalar + Copy, const D: usize> Copy for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
<DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
|
// <DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bytemuck")]
|
#[cfg(feature = "bytemuck")]
|
||||||
unsafe impl<N: Scalar, D: DimName> bytemuck::Zeroable for Point<N, D>
|
unsafe impl<N: Scalar, const D: usize> bytemuck::Zeroable for Point<N, D> where
|
||||||
where
|
VectorN<N, Const<D>>: bytemuck::Zeroable // DefaultAllocator: Allocator<N, D>,
|
||||||
VectorN<N, D>: bytemuck::Zeroable,
|
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bytemuck")]
|
#[cfg(feature = "bytemuck")]
|
||||||
unsafe impl<N: Scalar, D: DimName> bytemuck::Pod for Point<N, D>
|
unsafe impl<N: Scalar, const D: usize> bytemuck::Pod for Point<N, D>
|
||||||
where
|
where
|
||||||
N: Copy,
|
N: Copy,
|
||||||
VectorN<N, D>: bytemuck::Pod,
|
VectorN<N, Const<D>>: bytemuck::Pod,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
<DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
|
// <DefaultAllocator as Allocator<N, D>>::Buffer: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<N: Scalar, D: DimName> Serialize for Point<N, D>
|
impl<N: Scalar, const D: usize> Serialize for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
<DefaultAllocator as Allocator<N, D>>::Buffer: Serialize,
|
// <DefaultAllocator as Allocator<N, D>>::Buffer: Serialize,
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
|
@ -98,10 +93,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<'a, N: Scalar, D: DimName> Deserialize<'a> for Point<N, D>
|
impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
<DefaultAllocator as Allocator<N, D>>::Buffer: Deserialize<'a>,
|
// <DefaultAllocator as Allocator<N, D>>::Buffer: Deserialize<'a>,
|
||||||
{
|
{
|
||||||
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
||||||
where
|
where
|
||||||
|
@ -114,12 +109,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
impl<N, D> Abomonation for Point<N, D>
|
impl<N, const D: usize> Abomonation for Point<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
N: Scalar,
|
||||||
D: DimName,
|
VectorN<N, Const<D>>: Abomonation,
|
||||||
VectorN<N, D>: Abomonation,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
self.coords.entomb(writer)
|
self.coords.entomb(writer)
|
||||||
|
@ -134,9 +128,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Point<N, D>
|
impl<N: Scalar, const D: usize> Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Returns a point containing the result of `f` applied to each of its entries.
|
/// Returns a point containing the result of `f` applied to each of its entries.
|
||||||
///
|
///
|
||||||
|
@ -152,8 +146,8 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, f: F) -> Point<N2, D>
|
pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, f: F) -> Point<N2, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
self.coords.map(f).into()
|
self.coords.map(f).into()
|
||||||
}
|
}
|
||||||
|
@ -193,20 +187,21 @@ where
|
||||||
/// assert_eq!(p.to_homogeneous(), Vector4::new(10.0, 20.0, 30.0, 1.0));
|
/// assert_eq!(p.to_homogeneous(), Vector4::new(10.0, 20.0, 30.0, 1.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_homogeneous(&self) -> VectorN<N, DimNameSum<D, U1>>
|
pub fn to_homogeneous(&self) -> VectorN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
N: One,
|
N: One,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = unsafe {
|
let mut res = unsafe {
|
||||||
crate::unimplemented_or_uninitialized_generic!(
|
crate::unimplemented_or_uninitialized_generic!(
|
||||||
<DimNameSum<D, U1> as DimName>::name(),
|
<DimNameSum<Const<D>, U1> as DimName>::name(),
|
||||||
Const::<1>
|
Const::<1>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
res.fixed_slice_mut::<D, U1>(0, 0).copy_from(&self.coords);
|
res.fixed_slice_mut::<Const<D>, U1>(0, 0)
|
||||||
res[(D::dim(), 0)] = N::one();
|
.copy_from(&self.coords);
|
||||||
|
res[(D, 0)] = N::one();
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -214,7 +209,7 @@ where
|
||||||
/// Creates a new point with the given coordinates.
|
/// Creates a new point with the given coordinates.
|
||||||
#[deprecated(note = "Use Point::from(vector) instead.")]
|
#[deprecated(note = "Use Point::from(vector) instead.")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_coordinates(coords: VectorN<N, D>) -> Self {
|
pub fn from_coordinates(coords: VectorN<N, Const<D>>) -> Self {
|
||||||
Self { coords }
|
Self { coords }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +264,10 @@ where
|
||||||
/// assert_eq!(it.next(), Some(3.0));
|
/// assert_eq!(it.next(), Some(3.0));
|
||||||
/// assert_eq!(it.next(), None);
|
/// assert_eq!(it.next(), None);
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter(&self) -> MatrixIter<N, D, U1, <DefaultAllocator as Allocator<N, D>>::Buffer> {
|
pub fn iter(
|
||||||
|
&self,
|
||||||
|
) -> MatrixIter<N, Const<D>, Const<1>, <DefaultAllocator as Allocator<N, Const<D>>>::Buffer>
|
||||||
|
{
|
||||||
self.coords.iter()
|
self.coords.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +292,8 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter_mut(
|
pub fn iter_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> MatrixIterMut<N, D, U1, <DefaultAllocator as Allocator<N, D>>::Buffer> {
|
) -> MatrixIterMut<N, Const<D>, Const<1>, <DefaultAllocator as Allocator<N, Const<D>>>::Buffer>
|
||||||
|
{
|
||||||
self.coords.iter_mut()
|
self.coords.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,9 +310,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for Point<N, D>
|
impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Point<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
type Epsilon = N::Epsilon;
|
type Epsilon = N::Epsilon;
|
||||||
|
@ -329,9 +328,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + RelativeEq, D: DimName> RelativeEq for Point<N, D>
|
impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Point<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -351,9 +350,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + UlpsEq, D: DimName> UlpsEq for Point<N, D>
|
impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Point<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -367,11 +366,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Eq, D: DimName> Eq for Point<N, D> where DefaultAllocator: Allocator<N, D> {}
|
impl<N: Scalar + Eq, const D: usize> Eq for Point<N, D>
|
||||||
|
// where DefaultAllocator: Allocator<N, D>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> PartialEq for Point<N, D>
|
impl<N: Scalar, const D: usize> PartialEq for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, right: &Self) -> bool {
|
fn eq(&self, right: &Self) -> bool {
|
||||||
|
@ -379,9 +381,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PartialOrd, D: DimName> PartialOrd for Point<N, D>
|
impl<N: Scalar + PartialOrd, const D: usize> PartialOrd for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
@ -412,9 +414,9 @@ where
|
||||||
/*
|
/*
|
||||||
* inf/sup
|
* inf/sup
|
||||||
*/
|
*/
|
||||||
impl<N: Scalar + SimdPartialOrd, D: DimName> Point<N, D>
|
impl<N: Scalar + SimdPartialOrd, const D: usize> Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Computes the infimum (aka. componentwise min) of two points.
|
/// Computes the infimum (aka. componentwise min) of two points.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -441,9 +443,9 @@ where
|
||||||
* Display
|
* Display
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: Scalar + fmt::Display, D: DimName> fmt::Display for Point<N, D>
|
impl<N: Scalar + fmt::Display, const D: usize> fmt::Display for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{{")?;
|
write!(f, "{{")?;
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
/// A statically sized 1-dimensional column point.
|
/// A statically sized 1-dimensional column point.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
||||||
pub type Point1<N> = Point<N, U1>;
|
pub type Point1<N> = Point<N, 1>;
|
||||||
/// A statically sized 2-dimensional column point.
|
/// A statically sized 2-dimensional column point.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
||||||
pub type Point2<N> = Point<N, U2>;
|
pub type Point2<N> = Point<N, 2>;
|
||||||
/// A statically sized 3-dimensional column point.
|
/// A statically sized 3-dimensional column point.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
||||||
pub type Point3<N> = Point<N, U3>;
|
pub type Point3<N> = Point<N, 3>;
|
||||||
/// A statically sized 4-dimensional column point.
|
/// A statically sized 4-dimensional column point.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
||||||
pub type Point4<N> = Point<N, U4>;
|
pub type Point4<N> = Point<N, 4>;
|
||||||
/// A statically sized 5-dimensional column point.
|
/// A statically sized 5-dimensional column point.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
||||||
pub type Point5<N> = Point<N, U5>;
|
pub type Point5<N> = Point<N, 5>;
|
||||||
/// A statically sized 6-dimensional column point.
|
/// A statically sized 6-dimensional column point.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Point`](crate::Point) type too.**
|
||||||
pub type Point6<N> = Point<N, U6>;
|
pub type Point6<N> = Point<N, 6>;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rand::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, Scalar, VectorN};
|
use crate::base::{DefaultAllocator, Scalar, VectorN};
|
||||||
use crate::{
|
use crate::{
|
||||||
Const, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4,
|
Const, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4,
|
||||||
|
@ -20,16 +20,15 @@ use simba::scalar::{ClosedDiv, SupersetOf};
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
/// # Other construction methods
|
/// # Other construction methods
|
||||||
impl<N: Scalar, D: DimName> Point<N, D>
|
impl<N: Scalar, const D: usize> Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new point with uninitialized coordinates.
|
/// Creates a new point with uninitialized coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn new_uninitialized() -> Self {
|
pub unsafe fn new_uninitialized() -> Self {
|
||||||
Self::from(crate::unimplemented_or_uninitialized_generic!(
|
Self::from(crate::unimplemented_or_uninitialized_generic!(
|
||||||
D::name(),
|
Const::<D>, Const::<1>
|
||||||
Const::<1>
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,14 +105,14 @@ where
|
||||||
/// assert_eq!(pt, Some(Point2::new(1.0, 2.0)));
|
/// assert_eq!(pt, Some(Point2::new(1.0, 2.0)));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_homogeneous(v: VectorN<N, DimNameSum<D, U1>>) -> Option<Self>
|
pub fn from_homogeneous(v: VectorN<N, DimNameSum<Const<D>, U1>>) -> Option<Self>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One + ClosedDiv,
|
N: Scalar + Zero + One + ClosedDiv,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
if !v[D::dim()].is_zero() {
|
if !v[D].is_zero() {
|
||||||
let coords = v.fixed_slice::<D, U1>(0, 0) / v[D::dim()].inlined_clone();
|
let coords = v.fixed_slice::<Const<D>, U1>(0, 0) / v[D].inlined_clone();
|
||||||
Some(Self::from(coords))
|
Some(Self::from(coords))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -132,7 +131,7 @@ where
|
||||||
pub fn cast<To: Scalar>(self) -> Point<To, D>
|
pub fn cast<To: Scalar>(self) -> Point<To, D>
|
||||||
where
|
where
|
||||||
Point<To, D>: SupersetOf<Self>,
|
Point<To, D>: SupersetOf<Self>,
|
||||||
DefaultAllocator: Allocator<To, D>,
|
// DefaultAllocator: Allocator<To, D>,
|
||||||
{
|
{
|
||||||
crate::convert(self)
|
crate::convert(self)
|
||||||
}
|
}
|
||||||
|
@ -143,9 +142,9 @@ where
|
||||||
* Traits that build points.
|
* Traits that build points.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: Scalar + Bounded, D: DimName> Bounded for Point<N, D>
|
impl<N: Scalar + Bounded, const D: usize> Bounded for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_value() -> Self {
|
fn max_value() -> Self {
|
||||||
|
@ -159,9 +158,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
impl<N: Scalar, D: DimName> Distribution<Point<N, D>> for Standard
|
impl<N: Scalar, const D: usize> Distribution<Point<N, D>> for Standard
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Standard: Distribution<N>,
|
Standard: Distribution<N>,
|
||||||
{
|
{
|
||||||
/// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`.
|
/// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`.
|
||||||
|
@ -172,10 +171,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl<N: Scalar + Arbitrary + Send, D: DimName> Arbitrary for Point<N, D>
|
impl<N: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Point<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
<DefaultAllocator as Allocator<N, D>>::Buffer: Send,
|
<DefaultAllocator as Allocator<N, Const<D>>>::Buffer: Send,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn arbitrary(g: &mut Gen) -> Self {
|
fn arbitrary(g: &mut Gen) -> Self {
|
||||||
|
|
|
@ -3,8 +3,8 @@ use simba::scalar::{ClosedDiv, SubsetOf, SupersetOf};
|
||||||
use simba::simd::PrimitiveSimdValue;
|
use simba::simd::PrimitiveSimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN};
|
use crate::base::{Const, DefaultAllocator, Matrix, Scalar, VectorN};
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
|
@ -16,12 +16,11 @@ use crate::geometry::Point;
|
||||||
* Point -> Vector (homogeneous)
|
* Point -> Vector (homogeneous)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<N1, N2, D> SubsetOf<Point<N2, D>> for Point<N1, D>
|
impl<N1, N2, const D: usize> SubsetOf<Point<N2, D>> for Point<N1, D>
|
||||||
where
|
where
|
||||||
D: DimName,
|
|
||||||
N1: Scalar,
|
N1: Scalar,
|
||||||
N2: Scalar + SupersetOf<N1>,
|
N2: Scalar + SupersetOf<N1>,
|
||||||
DefaultAllocator: Allocator<N2, D> + Allocator<N1, D>,
|
// DefaultAllocator: Allocator<N2, D> + Allocator<N1, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Point<N2, D> {
|
fn to_superset(&self) -> Point<N2, D> {
|
||||||
|
@ -41,40 +40,41 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D> SubsetOf<VectorN<N2, DimNameSum<D, U1>>> for Point<N1, D>
|
impl<N1, N2, const D: usize> SubsetOf<VectorN<N2, DimNameSum<Const<D>, U1>>> for Point<N1, D>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
N1: Scalar,
|
N1: Scalar,
|
||||||
N2: Scalar + Zero + One + ClosedDiv + SupersetOf<N1>,
|
N2: Scalar + Zero + One + ClosedDiv + SupersetOf<N1>,
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator:
|
||||||
+ Allocator<N1, DimNameSum<D, U1>>
|
Allocator<N1, DimNameSum<Const<D>, U1>> + Allocator<N2, DimNameSum<Const<D>, U1>>,
|
||||||
+ Allocator<N2, DimNameSum<D, U1>>
|
// + Allocator<N1, D>
|
||||||
+ Allocator<N2, D>,
|
// + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> VectorN<N2, DimNameSum<D, U1>> {
|
fn to_superset(&self) -> VectorN<N2, DimNameSum<Const<D>, U1>> {
|
||||||
let p: Point<N2, D> = self.to_superset();
|
let p: Point<N2, D> = self.to_superset();
|
||||||
p.to_homogeneous()
|
p.to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(v: &VectorN<N2, DimNameSum<D, U1>>) -> bool {
|
fn is_in_subset(v: &VectorN<N2, DimNameSum<Const<D>, U1>>) -> bool {
|
||||||
crate::is_convertible::<_, VectorN<N1, DimNameSum<D, U1>>>(v) && !v[D::dim()].is_zero()
|
crate::is_convertible::<_, VectorN<N1, DimNameSum<D, U1>>>(v) && !v[D].is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(v: &VectorN<N2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(v: &VectorN<N2, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
let coords = v.fixed_slice::<D, U1>(0, 0) / v[D::dim()].inlined_clone();
|
let coords = v.fixed_slice::<D, U1>(0, 0) / v[D].inlined_clone();
|
||||||
Self {
|
Self {
|
||||||
coords: crate::convert_unchecked(coords),
|
coords: crate::convert_unchecked(coords),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + One, D: DimName> From<Point<N, D>> for VectorN<N, DimNameSum<D, U1>>
|
impl<N: Scalar + Zero + One, const D: usize> From<Point<N, D>>
|
||||||
|
for VectorN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(t: Point<N, D>) -> Self {
|
fn from(t: Point<N, D>) -> Self {
|
||||||
|
@ -82,23 +82,23 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Point<N, D>
|
impl<N: Scalar, const D: usize> From<VectorN<N, Const<D>>> for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(coords: VectorN<N, D>) -> Self {
|
fn from(coords: VectorN<N, Const<D>>) -> Self {
|
||||||
Point { coords }
|
Point { coords }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 2]>
|
impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 2]>
|
||||||
for Point<N, D>
|
for Point<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
|
<DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Point<N::Element, D>; 2]) -> Self {
|
fn from(arr: [Point<N::Element, D>; 2]) -> Self {
|
||||||
|
@ -106,13 +106,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 4]>
|
impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 4]>
|
||||||
for Point<N, D>
|
for Point<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
|
<DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Point<N::Element, D>; 4]) -> Self {
|
fn from(arr: [Point<N::Element, D>; 4]) -> Self {
|
||||||
|
@ -125,13 +125,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 8]>
|
impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 8]>
|
||||||
for Point<N, D>
|
for Point<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
|
<DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Point<N::Element, D>; 8]) -> Self {
|
fn from(arr: [Point<N::Element, D>; 8]) -> Self {
|
||||||
|
@ -148,13 +148,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Point<N::Element, D>; 16]>
|
impl<N: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<N::Element, D>; 16]>
|
||||||
for Point<N, D>
|
for Point<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
|
<DefaultAllocator as Allocator<N::Element, Const<D>>>::Buffer: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Point<N::Element, D>; 16]) -> Self {
|
fn from(arr: [Point<N::Element, D>; 16]) -> Self {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
|
||||||
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
|
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
|
||||||
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
use crate::base::Scalar;
|
||||||
use crate::base::{DefaultAllocator, Scalar};
|
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
|
@ -14,9 +12,10 @@ use crate::geometry::Point;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
macro_rules! deref_impl(
|
macro_rules! deref_impl(
|
||||||
($D: ty, $Target: ident $(, $comps: ident)*) => {
|
($D: expr, $Target: ident $(, $comps: ident)*) => {
|
||||||
impl<N: Scalar> Deref for Point<N, $D>
|
impl<N: Scalar> Deref for Point<N, $D>
|
||||||
where DefaultAllocator: Allocator<N, $D> {
|
// where DefaultAllocator: Allocator<N, $D>
|
||||||
|
{
|
||||||
type Target = $Target<N>;
|
type Target = $Target<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -26,7 +25,8 @@ macro_rules! deref_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar> DerefMut for Point<N, $D>
|
impl<N: Scalar> DerefMut for Point<N, $D>
|
||||||
where DefaultAllocator: Allocator<N, $D> {
|
// where DefaultAllocator: Allocator<N, $D>
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut *self.coords
|
&mut *self.coords
|
||||||
|
@ -35,9 +35,9 @@ macro_rules! deref_impl(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
deref_impl!(U1, X, x);
|
deref_impl!(1, X, x);
|
||||||
deref_impl!(U2, XY, x, y);
|
deref_impl!(2, XY, x, y);
|
||||||
deref_impl!(U3, XYZ, x, y, z);
|
deref_impl!(3, XYZ, x, y, z);
|
||||||
deref_impl!(U4, XYZW, x, y, z, w);
|
deref_impl!(4, XYZW, x, y, z, w);
|
||||||
deref_impl!(U5, XYZWA, x, y, z, w, a);
|
deref_impl!(5, XYZWA, x, y, z, w, a);
|
||||||
deref_impl!(U6, XYZWAB, x, y, z, w, a, b);
|
deref_impl!(6, XYZWAB, x, y, z, w, a, b);
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::base::constraint::{
|
||||||
};
|
};
|
||||||
use crate::base::dimension::{Dim, DimName, U1};
|
use crate::base::dimension::{Dim, DimName, U1};
|
||||||
use crate::base::storage::Storage;
|
use crate::base::storage::Storage;
|
||||||
use crate::base::{DefaultAllocator, Matrix, Scalar, Vector, VectorSum};
|
use crate::base::{Const, DefaultAllocator, Matrix, Scalar, Vector, VectorSum};
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ use crate::geometry::Point;
|
||||||
* Indexing.
|
* Indexing.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: Scalar, D: DimName> Index<usize> for Point<N, D>
|
impl<N: Scalar, const D: usize> Index<usize> for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
type Output = N;
|
type Output = N;
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> IndexMut<usize> for Point<N, D>
|
impl<N: Scalar, const D: usize> IndexMut<usize> for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
|
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
|
||||||
|
@ -47,9 +47,9 @@ where
|
||||||
* Neg.
|
* Neg.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: Scalar + ClosedNeg, D: DimName> Neg for Point<N, D>
|
impl<N: Scalar + ClosedNeg, const D: usize> Neg for Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar + ClosedNeg, D: DimName> Neg for &'a Point<N, D>
|
impl<'a, N: Scalar + ClosedNeg, const D: usize> Neg for &'a Point<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
type Output = Point<N, D>;
|
type Output = Point<N, D>;
|
||||||
|
|
||||||
|
@ -79,22 +79,22 @@ where
|
||||||
|
|
||||||
// Point - Point
|
// Point - Point
|
||||||
add_sub_impl!(Sub, sub, ClosedSub;
|
add_sub_impl!(Sub, sub, ClosedSub;
|
||||||
(D, U1), (D, U1) for D: DimName;
|
(D, U1), (D, U1);
|
||||||
self: &'a Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>;
|
self: &'a Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>;
|
||||||
&self.coords - &right.coords; 'a, 'b);
|
&self.coords - &right.coords; 'a, 'b);
|
||||||
|
|
||||||
add_sub_impl!(Sub, sub, ClosedSub;
|
add_sub_impl!(Sub, sub, ClosedSub;
|
||||||
(D, U1), (D, U1) for D: DimName;
|
(D, U1), (D, U1);
|
||||||
self: &'a Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>;
|
self: &'a Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>;
|
||||||
&self.coords - right.coords; 'a);
|
&self.coords - right.coords; 'a);
|
||||||
|
|
||||||
add_sub_impl!(Sub, sub, ClosedSub;
|
add_sub_impl!(Sub, sub, ClosedSub;
|
||||||
(D, U1), (D, U1) for D: DimName;
|
(D, U1), (D, U1);
|
||||||
self: Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>;
|
self: Point<N, D>, right: &'b Point<N, D>, Output = VectorSum<N, D, D>;
|
||||||
self.coords - &right.coords; 'b);
|
self.coords - &right.coords; 'b);
|
||||||
|
|
||||||
add_sub_impl!(Sub, sub, ClosedSub;
|
add_sub_impl!(Sub, sub, ClosedSub;
|
||||||
(D, U1), (D, U1) for D: DimName;
|
(D, U1), (D, U1);
|
||||||
self: Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>;
|
self: Point<N, D>, right: Point<N, D>, Output = VectorSum<N, D, D>;
|
||||||
self.coords - right.coords; );
|
self.coords - right.coords; );
|
||||||
|
|
||||||
|
@ -143,11 +143,11 @@ add_sub_impl!(Add, add, ClosedAdd;
|
||||||
// XXX: replace by the shared macro: add_sub_assign_impl
|
// XXX: replace by the shared macro: add_sub_assign_impl
|
||||||
macro_rules! op_assign_impl(
|
macro_rules! op_assign_impl(
|
||||||
($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$(
|
($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$(
|
||||||
impl<'b, N, D1: DimName, D2: Dim, SB> $TraitAssign<&'b Vector<N, D2, SB>> for Point<N, D1>
|
impl<'b, N, D2: Dim, SB, const D1: usize> $TraitAssign<&'b Vector<N, D2, SB>> for Point<N, D1>
|
||||||
where N: Scalar + $bound,
|
where N: Scalar + $bound,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<N, D2>,
|
||||||
DefaultAllocator: Allocator<N, D1>,
|
// DefaultAllocator: Allocator<N, D1>,
|
||||||
ShapeConstraint: SameNumberOfRows<D1, D2> {
|
ShapeConstraint: SameNumberOfRows<Const<D1>, D2> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method_assign(&mut self, right: &'b Vector<N, D2, SB>) {
|
fn $method_assign(&mut self, right: &'b Vector<N, D2, SB>) {
|
||||||
|
@ -155,10 +155,10 @@ macro_rules! op_assign_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D1: DimName, D2: Dim, SB> $TraitAssign<Vector<N, D2, SB>> for Point<N, D1>
|
impl<N, D2: Dim, SB, const D1: usize> $TraitAssign<Vector<N, D2, SB>> for Point<N, D1>
|
||||||
where N: Scalar + $bound,
|
where N: Scalar + $bound,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<N, D2>,
|
||||||
DefaultAllocator: Allocator<N, D1>,
|
// DefaultAllocator: Allocator<N, D1>,
|
||||||
ShapeConstraint: SameNumberOfRows<D1, D2> {
|
ShapeConstraint: SameNumberOfRows<D1, D2> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -198,8 +198,9 @@ md_impl_all!(
|
||||||
macro_rules! componentwise_scalarop_impl(
|
macro_rules! componentwise_scalarop_impl(
|
||||||
($Trait: ident, $method: ident, $bound: ident;
|
($Trait: ident, $method: ident, $bound: ident;
|
||||||
$TraitAssign: ident, $method_assign: ident) => {
|
$TraitAssign: ident, $method_assign: ident) => {
|
||||||
impl<N: Scalar + $bound, D: DimName> $Trait<N> for Point<N, D>
|
impl<N: Scalar + $bound, const D: usize> $Trait<N> for Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
// where DefaultAllocator: Allocator<N, D>
|
||||||
|
{
|
||||||
type Output = Point<N, D>;
|
type Output = Point<N, D>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -208,8 +209,9 @@ macro_rules! componentwise_scalarop_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar + $bound, D: DimName> $Trait<N> for &'a Point<N, D>
|
impl<'a, N: Scalar + $bound, const D: usize> $Trait<N> for &'a Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
// where DefaultAllocator: Allocator<N, D>
|
||||||
|
{
|
||||||
type Output = Point<N, D>;
|
type Output = Point<N, D>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -218,8 +220,9 @@ macro_rules! componentwise_scalarop_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + $bound, D: DimName> $TraitAssign<N> for Point<N, D>
|
impl<N: Scalar + $bound, const D: usize> $TraitAssign<N> for Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
/* where DefaultAllocator: Allocator<N, D> */
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method_assign(&mut self, right: N) {
|
fn $method_assign(&mut self, right: N) {
|
||||||
self.coords.$method_assign(right)
|
self.coords.$method_assign(right)
|
||||||
|
@ -233,8 +236,9 @@ componentwise_scalarop_impl!(Div, div, ClosedDiv; DivAssign, div_assign);
|
||||||
|
|
||||||
macro_rules! left_scalar_mul_impl(
|
macro_rules! left_scalar_mul_impl(
|
||||||
($($T: ty),* $(,)*) => {$(
|
($($T: ty),* $(,)*) => {$(
|
||||||
impl<D: DimName> Mul<Point<$T, D>> for $T
|
impl<const D: usize> Mul<Point<$T, D>> for $T
|
||||||
where DefaultAllocator: Allocator<$T, D> {
|
// where DefaultAllocator: Allocator<$T, D>
|
||||||
|
{
|
||||||
type Output = Point<$T, D>;
|
type Output = Point<$T, D>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -243,8 +247,9 @@ macro_rules! left_scalar_mul_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, D: DimName> Mul<&'b Point<$T, D>> for $T
|
impl<'b, const D: usize> Mul<&'b Point<$T, D>> for $T
|
||||||
where DefaultAllocator: Allocator<$T, D> {
|
// where DefaultAllocator: Allocator<$T, D>
|
||||||
|
{
|
||||||
type Output = Point<$T, D>;
|
type Output = Point<$T, D>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use simba::simd::SimdValue;
|
use simba::simd::SimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::{Scalar, VectorN};
|
||||||
use crate::base::dimension::DimName;
|
|
||||||
use crate::base::{DefaultAllocator, Scalar, VectorN};
|
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
impl<N: Scalar + SimdValue, D: DimName> SimdValue for Point<N, D>
|
impl<N: Scalar + SimdValue, const D: usize> SimdValue for Point<N, D>
|
||||||
where
|
where
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
type Element = Point<N::Element, D>;
|
type Element = Point<N::Element, D>;
|
||||||
type SimdBool = N::SimdBool;
|
type SimdBool = N::SimdBool;
|
||||||
|
|
|
@ -1367,7 +1367,7 @@ where
|
||||||
/// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6);
|
/// assert_relative_eq!(*rot.matrix(), expected, epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_rotation_matrix(&self) -> Rotation<N, U3> {
|
pub fn to_rotation_matrix(&self) -> Rotation<N, 3> {
|
||||||
let i = self.as_ref()[0];
|
let i = self.as_ref()[0];
|
||||||
let j = self.as_ref()[1];
|
let j = self.as_ref()[1];
|
||||||
let k = self.as_ref()[2];
|
let k = self.as_ref()[2];
|
||||||
|
|
|
@ -3,7 +3,6 @@ use num::Zero;
|
||||||
use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
|
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
|
||||||
|
|
||||||
use crate::base::dimension::U3;
|
|
||||||
use crate::base::{Matrix3, Matrix4, Scalar, Vector4};
|
use crate::base::{Matrix3, Matrix4, Scalar, Vector4};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
AbstractRotation, Isometry, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf,
|
AbstractRotation, Isometry, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf,
|
||||||
|
@ -16,11 +15,11 @@ use crate::geometry::{
|
||||||
*
|
*
|
||||||
* Quaternion -> Quaternion
|
* Quaternion -> Quaternion
|
||||||
* UnitQuaternion -> UnitQuaternion
|
* UnitQuaternion -> UnitQuaternion
|
||||||
* UnitQuaternion -> Rotation<U3>
|
* UnitQuaternion -> Rotation<3>
|
||||||
* UnitQuaternion -> Isometry<U3>
|
* UnitQuaternion -> Isometry<3>
|
||||||
* UnitQuaternion -> UnitDualQuaternion
|
* UnitQuaternion -> UnitDualQuaternion
|
||||||
* UnitQuaternion -> Similarity<U3>
|
* UnitQuaternion -> Similarity<3>
|
||||||
* UnitQuaternion -> Transform<U3>
|
* UnitQuaternion -> Transform<3>
|
||||||
* UnitQuaternion -> Matrix<U4> (homogeneous)
|
* UnitQuaternion -> Matrix<U4> (homogeneous)
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
|
@ -71,7 +70,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2> SubsetOf<Rotation<N2, U3>> for UnitQuaternion<N1>
|
impl<N1, N2> SubsetOf<Rotation<N2, 3>> for UnitQuaternion<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
|
@ -94,24 +93,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, R> SubsetOf<Isometry<N2, U3, R>> for UnitQuaternion<N1>
|
impl<N1, N2, R> SubsetOf<Isometry<N2, R, 3>> for UnitQuaternion<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, U3> + SupersetOf<Self>,
|
R: AbstractRotation<N2, 3> + SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Isometry<N2, U3, R> {
|
fn to_superset(&self) -> Isometry<N2, R, 3> {
|
||||||
Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
|
Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(iso: &Isometry<N2, U3, R>) -> bool {
|
fn is_in_subset(iso: &Isometry<N2, R, 3>) -> bool {
|
||||||
iso.translation.vector.is_zero()
|
iso.translation.vector.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(iso: &Isometry<N2, U3, R>) -> Self {
|
fn from_superset_unchecked(iso: &Isometry<N2, R, 3>) -> Self {
|
||||||
crate::convert_ref_unchecked(&iso.rotation)
|
crate::convert_ref_unchecked(&iso.rotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,46 +137,46 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, R> SubsetOf<Similarity<N2, U3, R>> for UnitQuaternion<N1>
|
impl<N1, N2, R> SubsetOf<Similarity<N2, R, 3>> for UnitQuaternion<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, U3> + SupersetOf<Self>,
|
R: AbstractRotation<N2, 3> + SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Similarity<N2, U3, R> {
|
fn to_superset(&self) -> Similarity<N2, R, 3> {
|
||||||
Similarity::from_isometry(crate::convert_ref(self), N2::one())
|
Similarity::from_isometry(crate::convert_ref(self), N2::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(sim: &Similarity<N2, U3, R>) -> bool {
|
fn is_in_subset(sim: &Similarity<N2, R, 3>) -> bool {
|
||||||
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
|
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(sim: &Similarity<N2, U3, R>) -> Self {
|
fn from_superset_unchecked(sim: &Similarity<N2, R, 3>) -> Self {
|
||||||
crate::convert_ref_unchecked(&sim.isometry)
|
crate::convert_ref_unchecked(&sim.isometry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, C> SubsetOf<Transform<N2, U3, C>> for UnitQuaternion<N1>
|
impl<N1, N2, C> SubsetOf<Transform<N2, C, 3>> for UnitQuaternion<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, U3, C> {
|
fn to_superset(&self) -> Transform<N2, C, 3> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, U3, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, 3>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, U3, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, 3>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::base::allocator::Allocator;
|
|
||||||
use crate::base::constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint};
|
use crate::base::constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint};
|
||||||
use crate::base::{DefaultAllocator, Matrix, Scalar, Unit, Vector};
|
use crate::base::{Const, Matrix, Scalar, Unit, Vector};
|
||||||
use crate::dimension::{Dim, DimName, U1};
|
use crate::dimension::{Dim, U1};
|
||||||
use crate::storage::{Storage, StorageMut};
|
use crate::storage::{Storage, StorageMut};
|
||||||
use simba::scalar::ComplexField;
|
use simba::scalar::ComplexField;
|
||||||
|
|
||||||
|
@ -13,6 +12,15 @@ pub struct Reflection<N: Scalar, D: Dim, S: Storage<N, D>> {
|
||||||
bias: N,
|
bias: N,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: ComplexField, S: Storage<N, Const<D>>, const D: usize> Reflection<N, Const<D>, S> {
|
||||||
|
/// Creates a new reflection wrt. the plane orthogonal to the given axis and that contains the
|
||||||
|
/// point `pt`.
|
||||||
|
pub fn new_containing_point(axis: Unit<Vector<N, Const<D>, S>>, pt: &Point<N, D>) -> Self {
|
||||||
|
let bias = axis.dotc(&pt.coords);
|
||||||
|
Self::new(axis, bias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: ComplexField, D: Dim, S: Storage<N, D>> Reflection<N, D, S> {
|
impl<N: ComplexField, D: Dim, S: Storage<N, D>> Reflection<N, D, S> {
|
||||||
/// Creates a new reflection wrt the plane orthogonal to the given axis and bias.
|
/// Creates a new reflection wrt the plane orthogonal to the given axis and bias.
|
||||||
///
|
///
|
||||||
|
@ -25,17 +33,6 @@ impl<N: ComplexField, D: Dim, S: Storage<N, D>> Reflection<N, D, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new reflection wrt. the plane orthogonal to the given axis and that contains the
|
|
||||||
/// point `pt`.
|
|
||||||
pub fn new_containing_point(axis: Unit<Vector<N, D, S>>, pt: &Point<N, D>) -> Self
|
|
||||||
where
|
|
||||||
D: DimName,
|
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
{
|
|
||||||
let bias = axis.dotc(&pt.coords);
|
|
||||||
Self::new(axis, bias)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The reflexion axis.
|
/// The reflexion axis.
|
||||||
pub fn axis(&self) -> &Vector<N, D, S> {
|
pub fn axis(&self) -> &Vector<N, D, S> {
|
||||||
&self.axis
|
&self.axis
|
||||||
|
|
|
@ -18,8 +18,8 @@ use simba::scalar::RealField;
|
||||||
use simba::simd::SimdRealField;
|
use simba::simd::SimdRealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, Unit, VectorN};
|
use crate::base::{CMatrixN, CVectorN, Const, DefaultAllocator, MatrixN, Scalar, Unit};
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
/// A rotation matrix.
|
/// A rotation matrix.
|
||||||
|
@ -55,34 +55,33 @@ use crate::geometry::Point;
|
||||||
///
|
///
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Rotation<N: Scalar, D: DimName>
|
pub struct Rotation<N: Scalar, const D: usize>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
matrix: MatrixN<N, D>,
|
matrix: CMatrixN<N, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash> hash::Hash for Rotation<N, D>
|
impl<N: Scalar + hash::Hash, const D: usize> hash::Hash for Rotation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
<DefaultAllocator as Allocator<N, D, D>>::Buffer: hash::Hash,
|
<DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: hash::Hash,
|
||||||
{
|
{
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
self.matrix.hash(state)
|
self.matrix.hash(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: DimName> Copy for Rotation<N, D>
|
impl<N: Scalar + Copy, const D: usize> Copy for Rotation<N, D> where
|
||||||
where
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
<DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Copy
|
||||||
<DefaultAllocator as Allocator<N, D, D>>::Buffer: Copy,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Clone for Rotation<N, D>
|
impl<N: Scalar, const D: usize> Clone for Rotation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
<DefaultAllocator as Allocator<N, D, D>>::Buffer: Clone,
|
<DefaultAllocator as Allocator<N, Const<D>, Const<D>>>::Buffer: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -91,12 +90,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
impl<N, D> Abomonation for Rotation<N, D>
|
impl<N, const D: usize> Abomonation for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
N: Scalar,
|
||||||
D: DimName,
|
CMatrixN<N, Const<D>>: Abomonation,
|
||||||
MatrixN<N, D>: Abomonation,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
self.matrix.entomb(writer)
|
self.matrix.entomb(writer)
|
||||||
|
@ -112,9 +110,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<N: Scalar, D: DimName> Serialize for Rotation<N, D>
|
impl<N: Scalar, const D: usize> Serialize for Rotation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
Owned<N, D, D>: Serialize,
|
Owned<N, D, D>: Serialize,
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -126,24 +124,24 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<'a, N: Scalar, D: DimName> Deserialize<'a> for Rotation<N, D>
|
impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Rotation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
Owned<N, D, D>: Deserialize<'a>,
|
Owned<N, D, D>: Deserialize<'a>,
|
||||||
{
|
{
|
||||||
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
||||||
where
|
where
|
||||||
Des: Deserializer<'a>,
|
Des: Deserializer<'a>,
|
||||||
{
|
{
|
||||||
let matrix = MatrixN::<N, D>::deserialize(deserializer)?;
|
let matrix = CMatrixN::<N, D>::deserialize(deserializer)?;
|
||||||
|
|
||||||
Ok(Self::from_matrix_unchecked(matrix))
|
Ok(Self::from_matrix_unchecked(matrix))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Rotation<N, D>
|
impl<N: Scalar, const D: usize> Rotation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new rotation from the given square matrix.
|
/// Creates a new rotation from the given square matrix.
|
||||||
///
|
///
|
||||||
|
@ -168,7 +166,7 @@ where
|
||||||
/// assert_eq!(*rot.matrix(), mat);
|
/// assert_eq!(*rot.matrix(), mat);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_matrix_unchecked(matrix: MatrixN<N, D>) -> Self {
|
pub fn from_matrix_unchecked(matrix: CMatrixN<N, D>) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
matrix.is_square(),
|
matrix.is_square(),
|
||||||
"Unable to create a rotation from a non-square matrix."
|
"Unable to create a rotation from a non-square matrix."
|
||||||
|
@ -179,9 +177,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Conversion to a matrix
|
/// # Conversion to a matrix
|
||||||
impl<N: Scalar, D: DimName> Rotation<N, D>
|
impl<N: Scalar, const D: usize> Rotation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
/// A reference to the underlying matrix representation of this rotation.
|
/// A reference to the underlying matrix representation of this rotation.
|
||||||
///
|
///
|
||||||
|
@ -202,14 +200,14 @@ where
|
||||||
/// assert_eq!(*rot.matrix(), expected);
|
/// assert_eq!(*rot.matrix(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matrix(&self) -> &MatrixN<N, D> {
|
pub fn matrix(&self) -> &CMatrixN<N, D> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable reference to the underlying matrix representation of this rotation.
|
/// A mutable reference to the underlying matrix representation of this rotation.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated(note = "Use `.matrix_mut_unchecked()` instead.")]
|
#[deprecated(note = "Use `.matrix_mut_unchecked()` instead.")]
|
||||||
pub unsafe fn matrix_mut(&mut self) -> &mut MatrixN<N, D> {
|
pub unsafe fn matrix_mut(&mut self) -> &mut CMatrixN<N, D> {
|
||||||
&mut self.matrix
|
&mut self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ where
|
||||||
/// non-square, non-inversible, or non-orthonormal. If one of those properties is broken,
|
/// non-square, non-inversible, or non-orthonormal. If one of those properties is broken,
|
||||||
/// subsequent method calls may be UB.
|
/// subsequent method calls may be UB.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matrix_mut_unchecked(&mut self) -> &mut MatrixN<N, D> {
|
pub fn matrix_mut_unchecked(&mut self) -> &mut CMatrixN<N, D> {
|
||||||
&mut self.matrix
|
&mut self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +242,7 @@ where
|
||||||
/// assert_eq!(mat, expected);
|
/// assert_eq!(mat, expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_inner(self) -> MatrixN<N, D> {
|
pub fn into_inner(self) -> CMatrixN<N, D> {
|
||||||
self.matrix
|
self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +250,7 @@ where
|
||||||
/// Deprecated: Use [Rotation::into_inner] instead.
|
/// Deprecated: Use [Rotation::into_inner] instead.
|
||||||
#[deprecated(note = "use `.into_inner()` instead")]
|
#[deprecated(note = "use `.into_inner()` instead")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap(self) -> MatrixN<N, D> {
|
pub fn unwrap(self) -> CMatrixN<N, D> {
|
||||||
self.matrix
|
self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,13 +277,13 @@ where
|
||||||
/// assert_eq!(rot.to_homogeneous(), expected);
|
/// assert_eq!(rot.to_homogeneous(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>>
|
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
N: Zero + One,
|
N: Zero + One,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
// We could use `MatrixN::to_homogeneous()` here, but that would imply
|
// We could use `CMatrixN::to_homogeneous()` here, but that would imply
|
||||||
// adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe
|
// adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe
|
||||||
// these things will get nicer once specialization lands in Rust.
|
// these things will get nicer once specialization lands in Rust.
|
||||||
let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity();
|
let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity();
|
||||||
|
@ -296,9 +294,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Transposition and inversion
|
/// # Transposition and inversion
|
||||||
impl<N: Scalar, D: DimName> Rotation<N, D>
|
impl<N: Scalar, const D: usize> Rotation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
/// Transposes `self`.
|
/// Transposes `self`.
|
||||||
///
|
///
|
||||||
|
@ -404,10 +402,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Transformation of a vector or a point
|
/// # Transformation of a vector or a point
|
||||||
impl<N: SimdRealField, D: DimName> Rotation<N, D>
|
impl<N: SimdRealField, const D: usize> Rotation<N, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Rotate the given point.
|
/// Rotate the given point.
|
||||||
///
|
///
|
||||||
|
@ -443,7 +441,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +479,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self.matrix().tr_mul(v)
|
self.matrix().tr_mul(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,16 +498,19 @@ where
|
||||||
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> {
|
pub fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>> {
|
||||||
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Eq, D: DimName> Eq for Rotation<N, D> where DefaultAllocator: Allocator<N, D, D> {}
|
impl<N: Scalar + Eq, const D: usize> Eq for Rotation<N, D>
|
||||||
|
// where DefaultAllocator: Allocator<N, D, D>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PartialEq, D: DimName> PartialEq for Rotation<N, D>
|
impl<N: Scalar + PartialEq, const D: usize> PartialEq for Rotation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, right: &Self) -> bool {
|
fn eq(&self, right: &Self) -> bool {
|
||||||
|
@ -517,10 +518,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: DimName> AbsDiffEq for Rotation<N, D>
|
impl<N, const D: usize> AbsDiffEq for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar + AbsDiffEq,
|
N: Scalar + AbsDiffEq,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
type Epsilon = N::Epsilon;
|
type Epsilon = N::Epsilon;
|
||||||
|
@ -536,10 +537,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: DimName> RelativeEq for Rotation<N, D>
|
impl<N, const D: usize> RelativeEq for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar + RelativeEq,
|
N: Scalar + RelativeEq,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -559,10 +560,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: DimName> UlpsEq for Rotation<N, D>
|
impl<N, const D: usize> UlpsEq for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar + UlpsEq,
|
N: Scalar + UlpsEq,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -581,10 +582,10 @@ where
|
||||||
* Display
|
* Display
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N, D: DimName> fmt::Display for Rotation<N, D>
|
impl<N, const D: usize> fmt::Display for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: RealField + fmt::Display,
|
N: RealField + fmt::Display,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<usize, D, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<usize, D, D>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let precision = f.precision().unwrap_or(3);
|
let precision = f.precision().unwrap_or(3);
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
use crate::base::dimension::{U2, U3};
|
|
||||||
|
|
||||||
use crate::geometry::Rotation;
|
use crate::geometry::Rotation;
|
||||||
|
|
||||||
/// A 2-dimensional rotation matrix.
|
/// A 2-dimensional rotation matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.**
|
||||||
pub type Rotation2<N> = Rotation<N, U2>;
|
pub type Rotation2<N> = Rotation<N, 2>;
|
||||||
|
|
||||||
/// A 3-dimensional rotation matrix.
|
/// A 3-dimensional rotation matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Rotation`](crate::Rotation) type too.**
|
||||||
pub type Rotation3<N> = Rotation<N, U3>;
|
pub type Rotation3<N> = Rotation<N, 3>;
|
||||||
|
|
|
@ -2,17 +2,15 @@ use num::{One, Zero};
|
||||||
|
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
|
use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::{MatrixN, Scalar};
|
||||||
use crate::base::dimension::DimName;
|
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar};
|
|
||||||
|
|
||||||
use crate::geometry::Rotation;
|
use crate::geometry::Rotation;
|
||||||
|
|
||||||
/// # Identity
|
/// # Identity
|
||||||
impl<N, D: DimName> Rotation<N, D>
|
impl<N, const D: usize> Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One,
|
N: Scalar + Zero + One,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new square identity rotation of the given `dimension`.
|
/// Creates a new square identity rotation of the given `dimension`.
|
||||||
///
|
///
|
||||||
|
@ -31,9 +29,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Rotation<N, D>
|
impl<N: Scalar, const D: usize> Rotation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
/// Cast the components of `self` to another type.
|
/// Cast the components of `self` to another type.
|
||||||
///
|
///
|
||||||
|
@ -47,16 +45,16 @@ where
|
||||||
pub fn cast<To: Scalar>(self) -> Rotation<To, D>
|
pub fn cast<To: Scalar>(self) -> Rotation<To, D>
|
||||||
where
|
where
|
||||||
Rotation<To, D>: SupersetOf<Self>,
|
Rotation<To, D>: SupersetOf<Self>,
|
||||||
DefaultAllocator: Allocator<To, D, D>,
|
// DefaultAllocator: Allocator<To, D, D>,
|
||||||
{
|
{
|
||||||
crate::convert(self)
|
crate::convert(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: DimName> One for Rotation<N, D>
|
impl<N, const D: usize> One for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
N: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
|
|
|
@ -4,8 +4,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::{PrimitiveSimdValue, SimdValue};
|
use simba::simd::{PrimitiveSimdValue, SimdValue};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar};
|
use crate::base::{Const, DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar};
|
||||||
|
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
AbstractRotation, Isometry, Rotation, Rotation2, Rotation3, Similarity, SuperTCategoryOf,
|
AbstractRotation, Isometry, Rotation, Rotation2, Rotation3, Similarity, SuperTCategoryOf,
|
||||||
|
@ -27,11 +27,11 @@ use crate::geometry::{
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<N1, N2, D: DimName> SubsetOf<Rotation<N2, D>> for Rotation<N1, D>
|
impl<N1, N2, const D: usize> SubsetOf<Rotation<N2, D>> for Rotation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D, D>,
|
// DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Rotation<N2, D> {
|
fn to_superset(&self) -> Rotation<N2, D> {
|
||||||
|
@ -120,113 +120,112 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R> SubsetOf<Isometry<N2, D, R>> for Rotation<N1, D>
|
impl<N1, N2, R, const D: usize> SubsetOf<Isometry<N2, R, D>> for Rotation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, D> + SupersetOf<Self>,
|
R: AbstractRotation<N2, D> + SupersetOf<Self>,
|
||||||
DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Isometry<N2, D, R> {
|
fn to_superset(&self) -> Isometry<N2, R, D> {
|
||||||
Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
|
Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(iso: &Isometry<N2, D, R>) -> bool {
|
fn is_in_subset(iso: &Isometry<N2, R, D>) -> bool {
|
||||||
iso.translation.vector.is_zero()
|
iso.translation.vector.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(iso: &Isometry<N2, D, R>) -> Self {
|
fn from_superset_unchecked(iso: &Isometry<N2, R, D>) -> Self {
|
||||||
crate::convert_ref_unchecked(&iso.rotation)
|
crate::convert_ref_unchecked(&iso.rotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R> SubsetOf<Similarity<N2, D, R>> for Rotation<N1, D>
|
impl<N1, N2, R, const D: usize> SubsetOf<Similarity<N2, R, D>> for Rotation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, D> + SupersetOf<Self>,
|
R: AbstractRotation<N2, D> + SupersetOf<Self>,
|
||||||
DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Similarity<N2, D, R> {
|
fn to_superset(&self) -> Similarity<N2, R, D> {
|
||||||
Similarity::from_parts(Translation::identity(), crate::convert_ref(self), N2::one())
|
Similarity::from_parts(Translation::identity(), crate::convert_ref(self), N2::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(sim: &Similarity<N2, D, R>) -> bool {
|
fn is_in_subset(sim: &Similarity<N2, R, D>) -> bool {
|
||||||
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
|
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(sim: &Similarity<N2, D, R>) -> Self {
|
fn from_superset_unchecked(sim: &Similarity<N2, R, D>) -> Self {
|
||||||
crate::convert_ref_unchecked(&sim.isometry.rotation)
|
crate::convert_ref_unchecked(&sim.isometry.rotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D, C> SubsetOf<Transform<N2, D, C>> for Rotation<N1, D>
|
impl<N1, N2, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Rotation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal()
|
Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
|
||||||
DefaultAllocator: Allocator<N1, D, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N2, D, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<(usize, usize), D>,
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// Allocator<N1, D, D>
|
||||||
+ Allocator<(usize, usize), D>,
|
// + Allocator<N2, D, D>
|
||||||
{
|
{
|
||||||
// needed by .is_special_orthogonal()
|
// needed by .is_special_orthogonal()
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, D, C> {
|
fn to_superset(&self) -> Transform<N2, C, D> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, D, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Rotation<N1, D>
|
impl<N1, N2, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>> for Rotation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .is_special_orthogonal()
|
Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .is_special_orthogonal()
|
||||||
DefaultAllocator: Allocator<N1, D, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N2, D, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<(usize, usize), D>,
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N1, D, D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N2, D, D>
|
||||||
+ Allocator<(usize, usize), D>,
|
|
||||||
{
|
{
|
||||||
// needed by .is_special_orthogonal()
|
// needed by .is_special_orthogonal()
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> {
|
fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
|
||||||
self.to_homogeneous().to_superset()
|
self.to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool {
|
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
|
||||||
let rot = m.fixed_slice::<D, D>(0, 0);
|
let rot = m.fixed_slice::<D, D>(0, 0);
|
||||||
let bottom = m.fixed_slice::<U1, D>(D::dim(), 0);
|
let bottom = m.fixed_slice::<U1, D>(D, 0);
|
||||||
|
|
||||||
// Scalar types agree.
|
// Scalar types agree.
|
||||||
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
||||||
// The block part is a rotation.
|
// The block part is a rotation.
|
||||||
rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) &&
|
rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) &&
|
||||||
// The bottom row is (0, 0, ..., 1)
|
// The bottom row is (0, 0, ..., 1)
|
||||||
bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one()
|
bottom.iter().all(|e| e.is_zero()) && m[(D, D)] == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
let r = m.fixed_slice::<D, D>(0, 0);
|
let r = m.fixed_slice::<D, D>(0, 0);
|
||||||
Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned()))
|
Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned()))
|
||||||
}
|
}
|
||||||
|
@ -260,12 +259,12 @@ impl<N: RealField> From<Rotation3<N>> for Matrix3<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 2]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 2]>
|
||||||
for Rotation<N, D>
|
for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 2]>,
|
N: From<[<N as SimdValue>::Element; 2]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Rotation<N::Element, D>; 2]) -> Self {
|
fn from(arr: [Rotation<N::Element, D>; 2]) -> Self {
|
||||||
|
@ -276,12 +275,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 4]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 4]>
|
||||||
for Rotation<N, D>
|
for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 4]>,
|
N: From<[<N as SimdValue>::Element; 4]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Rotation<N::Element, D>; 4]) -> Self {
|
fn from(arr: [Rotation<N::Element, D>; 4]) -> Self {
|
||||||
|
@ -294,12 +293,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 8]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 8]>
|
||||||
for Rotation<N, D>
|
for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 8]>,
|
N: From<[<N as SimdValue>::Element; 8]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Rotation<N::Element, D>; 8]) -> Self {
|
fn from(arr: [Rotation<N::Element, D>; 8]) -> Self {
|
||||||
|
@ -316,12 +315,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Rotation<N::Element, D>; 16]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Rotation<N::Element, D>; 16]>
|
||||||
for Rotation<N, D>
|
for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 16]>,
|
N: From<[<N as SimdValue>::Element; 16]>,
|
||||||
N::Element: Scalar + Copy,
|
N::Element: Scalar + Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Rotation<N::Element, D>; 16]) -> Self {
|
fn from(arr: [Rotation<N::Element, D>; 16]) -> Self {
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
use simba::simd::SimdValue;
|
use simba::simd::SimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::{MatrixN, Scalar};
|
||||||
use crate::base::dimension::DimName;
|
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar};
|
|
||||||
|
|
||||||
use crate::geometry::Rotation;
|
use crate::geometry::Rotation;
|
||||||
|
|
||||||
impl<N, D> SimdValue for Rotation<N, D>
|
impl<N, const D: usize> SimdValue for Rotation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar + SimdValue,
|
N: Scalar + SimdValue,
|
||||||
D: DimName,
|
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
// DefaultAllocator: Allocator<N, D, D> + Allocator<N::Element, D, D>,
|
||||||
{
|
{
|
||||||
type Element = Rotation<N::Element, D>;
|
type Element = Rotation<N::Element, D>;
|
||||||
type SimdBool = N::SimdBool;
|
type SimdBool = N::SimdBool;
|
||||||
|
|
|
@ -16,9 +16,9 @@ use simba::scalar::{RealField, SubsetOf};
|
||||||
use simba::simd::SimdRealField;
|
use simba::simd::SimdRealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN};
|
use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar};
|
||||||
use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
|
use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
|
||||||
|
|
||||||
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
|
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
|
||||||
|
@ -39,20 +39,20 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
|
||||||
DefaultAllocator: Allocator<N, D>,
|
DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Deserialize<'de>"))
|
Owned<N, D>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
pub struct Similarity<N: Scalar, D: DimName, R>
|
pub struct Similarity<N: Scalar, R, const D: usize>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// The part of this similarity that does not include the scaling factor.
|
/// The part of this similarity that does not include the scaling factor.
|
||||||
pub isometry: Isometry<N, D, R>,
|
pub isometry: Isometry<N, R, D>,
|
||||||
scaling: N,
|
scaling: N,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
impl<N: Scalar, D: DimName, R> Abomonation for Similarity<N, D, R>
|
impl<N: Scalar, R, const D: usize> Abomonation for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
Isometry<N, D, R>: Abomonation,
|
Isometry<N, R, D>: Abomonation,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
self.isometry.entomb(writer)
|
self.isometry.entomb(writer)
|
||||||
|
@ -67,11 +67,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash
|
impl<N: Scalar + hash::Hash, R: hash::Hash, const D: usize> hash::Hash for Similarity<N, R, D>
|
||||||
for Similarity<N, D, R>
|
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: hash::Hash,
|
Owned<N, Const<D>>: hash::Hash,
|
||||||
{
|
{
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
self.isometry.hash(state);
|
self.isometry.hash(state);
|
||||||
|
@ -79,17 +78,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy + Zero, D: DimName + Copy, R: AbstractRotation<N, D> + Copy> Copy
|
impl<N: Scalar + Copy + Zero, R: AbstractRotation<N, D> + Copy, const D: usize> Copy
|
||||||
for Similarity<N, D, R>
|
for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Copy,
|
Owned<N, Const<D>>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Similarity<N, D, R>
|
impl<N: Scalar + Zero, R: AbstractRotation<N, D> + Clone, const D: usize> Clone
|
||||||
where
|
for Similarity<N, R, D>
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// where
|
||||||
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -97,10 +97,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero, D: DimName, R> Similarity<N, D, R>
|
impl<N: Scalar + Zero, R, const D: usize> Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new similarity from its rotational and translational parts.
|
/// Creates a new similarity from its rotational and translational parts.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -110,7 +110,7 @@ where
|
||||||
|
|
||||||
/// Creates a new similarity from its rotational and translational parts.
|
/// Creates a new similarity from its rotational and translational parts.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_isometry(isometry: Isometry<N, D, R>, scaling: N) -> Self {
|
pub fn from_isometry(isometry: Isometry<N, R, D>, scaling: N) -> Self {
|
||||||
assert!(!scaling.is_zero(), "The scaling factor must not be zero.");
|
assert!(!scaling.is_zero(), "The scaling factor must not be zero.");
|
||||||
|
|
||||||
Self { isometry, scaling }
|
Self { isometry, scaling }
|
||||||
|
@ -128,9 +128,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName, R> Similarity<N, D, R>
|
impl<N: Scalar, R, const D: usize> Similarity<N, R, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// The scaling factor of this similarity transformation.
|
/// The scaling factor of this similarity transformation.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -139,11 +139,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new similarity that applies only a scaling factor.
|
/// Creates a new similarity that applies only a scaling factor.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -282,7 +282,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(18.0, 15.0, -12.0), epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ where
|
||||||
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.5, 2.0), epsilon = 1.0e-5);
|
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.5, 2.0), epsilon = 1.0e-5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self.isometry.inverse_transform_vector(v) / self.scaling()
|
self.isometry.inverse_transform_vector(v) / self.scaling()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,17 +331,17 @@ where
|
||||||
// and makes it harder to use it, e.g., for Transform × Isometry implementation.
|
// and makes it harder to use it, e.g., for Transform × Isometry implementation.
|
||||||
// This is OK since all constructors of the isometry enforce the Rotation bound already (and
|
// This is OK since all constructors of the isometry enforce the Rotation bound already (and
|
||||||
// explicit struct construction is prevented by the private scaling factor).
|
// explicit struct construction is prevented by the private scaling factor).
|
||||||
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Converts this similarity into its equivalent homogeneous transformation matrix.
|
/// Converts this similarity into its equivalent homogeneous transformation matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>>
|
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>,
|
R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = self.isometry.to_homogeneous();
|
let mut res = self.isometry.to_homogeneous();
|
||||||
|
|
||||||
|
@ -353,17 +353,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> Eq for Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Eq for Similarity<N, R, D> where
|
||||||
where
|
R: AbstractRotation<N, D> + Eq // DefaultAllocator: Allocator<N, D>,
|
||||||
R: AbstractRotation<N, D> + Eq,
|
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> PartialEq for Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> PartialEq for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + PartialEq,
|
R: AbstractRotation<N, D> + PartialEq,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, right: &Self) -> bool {
|
fn eq(&self, right: &Self) -> bool {
|
||||||
|
@ -371,10 +369,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, R> AbsDiffEq for Similarity<N, D, R>
|
impl<N: RealField, R, const D: usize> AbsDiffEq for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>,
|
R: AbstractRotation<N, D> + AbsDiffEq<Epsilon = N::Epsilon>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
type Epsilon = N::Epsilon;
|
type Epsilon = N::Epsilon;
|
||||||
|
@ -391,10 +389,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, R> RelativeEq for Similarity<N, D, R>
|
impl<N: RealField, R, const D: usize> RelativeEq for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>,
|
R: AbstractRotation<N, D> + RelativeEq<Epsilon = N::Epsilon>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -417,10 +415,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, R> UlpsEq for Similarity<N, D, R>
|
impl<N: RealField, R, const D: usize> UlpsEq for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>,
|
R: AbstractRotation<N, D> + UlpsEq<Epsilon = N::Epsilon>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -440,11 +437,11 @@ where
|
||||||
* Display
|
* Display
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N, D: DimName, R> fmt::Display for Similarity<N, D, R>
|
impl<N, R, const D: usize> fmt::Display for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N: RealField + fmt::Display,
|
N: RealField + fmt::Display,
|
||||||
R: AbstractRotation<N, D> + fmt::Display,
|
R: AbstractRotation<N, D> + fmt::Display,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let precision = f.precision().unwrap_or(3);
|
let precision = f.precision().unwrap_or(3);
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use crate::base::dimension::{U2, U3};
|
|
||||||
|
|
||||||
use crate::geometry::{Rotation2, Rotation3, Similarity, UnitComplex, UnitQuaternion};
|
use crate::geometry::{Rotation2, Rotation3, Similarity, UnitComplex, UnitQuaternion};
|
||||||
|
|
||||||
/// A 2-dimensional similarity.
|
/// A 2-dimensional similarity.
|
||||||
pub type Similarity2<N> = Similarity<N, U2, UnitComplex<N>>;
|
pub type Similarity2<N> = Similarity<N, UnitComplex<N>, 2>;
|
||||||
|
|
||||||
/// A 3-dimensional similarity.
|
/// A 3-dimensional similarity.
|
||||||
pub type Similarity3<N> = Similarity<N, U3, UnitQuaternion<N>>;
|
pub type Similarity3<N> = Similarity<N, UnitQuaternion<N>, 3>;
|
||||||
|
|
||||||
/// A 2-dimensional similarity using a rotation matrix for its rotation part.
|
/// A 2-dimensional similarity using a rotation matrix for its rotation part.
|
||||||
pub type SimilarityMatrix2<N> = Similarity<N, U2, Rotation2<N>>;
|
pub type SimilarityMatrix2<N> = Similarity<N, Rotation2<N>, 2>;
|
||||||
|
|
||||||
/// A 3-dimensional similarity using a rotation matrix for its rotation part.
|
/// A 3-dimensional similarity using a rotation matrix for its rotation part.
|
||||||
pub type SimilarityMatrix3<N> = Similarity<N, U3, Rotation3<N>>;
|
pub type SimilarityMatrix3<N> = Similarity<N, Rotation3<N>, 3>;
|
||||||
|
|
|
@ -13,20 +13,18 @@ use rand::{
|
||||||
use simba::scalar::SupersetOf;
|
use simba::scalar::SupersetOf;
|
||||||
use simba::simd::SimdRealField;
|
use simba::simd::SimdRealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::{Vector2, Vector3};
|
||||||
use crate::base::dimension::{DimName, U2, U3};
|
|
||||||
use crate::base::{DefaultAllocator, Vector2, Vector3};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity,
|
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity,
|
||||||
Translation, UnitComplex, UnitQuaternion,
|
Translation, UnitComplex, UnitQuaternion,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity similarity.
|
/// Creates a new identity similarity.
|
||||||
///
|
///
|
||||||
|
@ -49,11 +47,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> One for Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> One for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity similarity.
|
/// Creates a new identity similarity.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -63,15 +61,15 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
impl<N: crate::RealField, D: DimName, R> Distribution<Similarity<N, D, R>> for Standard
|
impl<N: crate::RealField, R, const D: usize> Distribution<Similarity<N, R, D>> for Standard
|
||||||
where
|
where
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Standard: Distribution<N> + Distribution<R>,
|
Standard: Distribution<N> + Distribution<R>,
|
||||||
{
|
{
|
||||||
/// Generate an arbitrary random variate for testing purposes.
|
/// Generate an arbitrary random variate for testing purposes.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Similarity<N, D, R> {
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Similarity<N, R, D> {
|
||||||
let mut s = rng.gen();
|
let mut s = rng.gen();
|
||||||
while relative_eq!(s, N::zero()) {
|
while relative_eq!(s, N::zero()) {
|
||||||
s = rng.gen()
|
s = rng.gen()
|
||||||
|
@ -81,11 +79,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: AbstractRotation<N, D>,
|
R: AbstractRotation<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// The similarity that applies the scaling factor `scaling`, followed by the rotation `r` with
|
/// The similarity that applies the scaling factor `scaling`, followed by the rotation `r` with
|
||||||
/// its axis passing through the point `p`.
|
/// its axis passing through the point `p`.
|
||||||
|
@ -110,12 +108,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl<N, D: DimName, R> Arbitrary for Similarity<N, D, R>
|
impl<N, R, const D: usize> Arbitrary for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N: crate::RealField + Arbitrary + Send,
|
N: crate::RealField + Arbitrary + Send,
|
||||||
N::Element: crate::RealField,
|
N::Element: crate::RealField,
|
||||||
R: AbstractRotation<N, D> + Arbitrary + Send,
|
R: AbstractRotation<N, D> + Arbitrary + Send,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Send,
|
Owned<N, D>: Send,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -136,7 +134,7 @@ where
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 2D similarity.
|
// 2D similarity.
|
||||||
impl<N: SimdRealField> Similarity<N, U2, Rotation2<N>>
|
impl<N: SimdRealField> Similarity<N, Rotation2<N>, 2>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
|
@ -170,15 +168,15 @@ where
|
||||||
/// let sim2 = sim.cast::<f32>();
|
/// let sim2 = sim.cast::<f32>();
|
||||||
/// assert_eq!(sim2, SimilarityMatrix2::<f32>::identity());
|
/// assert_eq!(sim2, SimilarityMatrix2::<f32>::identity());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn cast<To: Scalar>(self) -> Similarity<To, U2, Rotation2<To>>
|
pub fn cast<To: Scalar>(self) -> Similarity<To, Rotation2<To>, 2>
|
||||||
where
|
where
|
||||||
Similarity<To, U2, Rotation2<To>>: SupersetOf<Self>,
|
Similarity<To, Rotation2<To>, 2>: SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
crate::convert(self)
|
crate::convert(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> Similarity<N, U2, UnitComplex<N>>
|
impl<N: SimdRealField> Similarity<N, UnitComplex<N>, 2>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
|
@ -212,9 +210,9 @@ where
|
||||||
/// let sim2 = sim.cast::<f32>();
|
/// let sim2 = sim.cast::<f32>();
|
||||||
/// assert_eq!(sim2, Similarity2::<f32>::identity());
|
/// assert_eq!(sim2, Similarity2::<f32>::identity());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn cast<To: Scalar>(self) -> Similarity<To, U2, UnitComplex<To>>
|
pub fn cast<To: Scalar>(self) -> Similarity<To, UnitComplex<To>, 2>
|
||||||
where
|
where
|
||||||
Similarity<To, U2, UnitComplex<To>>: SupersetOf<Self>,
|
Similarity<To, UnitComplex<To>, 2>: SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
crate::convert(self)
|
crate::convert(self)
|
||||||
}
|
}
|
||||||
|
@ -223,7 +221,7 @@ where
|
||||||
// 3D rotation.
|
// 3D rotation.
|
||||||
macro_rules! similarity_construction_impl(
|
macro_rules! similarity_construction_impl(
|
||||||
($Rot: ident) => {
|
($Rot: ident) => {
|
||||||
impl<N: SimdRealField> Similarity<N, U3, $Rot<N>>
|
impl<N: SimdRealField> Similarity<N, $Rot<N>, 3>
|
||||||
where N::Element: SimdRealField {
|
where N::Element: SimdRealField {
|
||||||
/// Creates a new similarity from a translation, rotation axis-angle, and scaling
|
/// Creates a new similarity from a translation, rotation axis-angle, and scaling
|
||||||
/// factor.
|
/// factor.
|
||||||
|
@ -253,7 +251,7 @@ macro_rules! similarity_construction_impl(
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(translation: Vector3<N>, axisangle: Vector3<N>, scaling: N) -> Self
|
pub fn new(translation: Vector3<N>, axisangle: Vector3<N>, scaling: N) -> Self
|
||||||
{
|
{
|
||||||
Self::from_isometry(Isometry::<_, U3, $Rot<N>>::new(translation, axisangle), scaling)
|
Self::from_isometry(Isometry::<_, $Rot<N>, 3>::new(translation, axisangle), scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast the components of `self` to another type.
|
/// Cast the components of `self` to another type.
|
||||||
|
@ -265,9 +263,9 @@ macro_rules! similarity_construction_impl(
|
||||||
/// let sim2 = sim.cast::<f32>();
|
/// let sim2 = sim.cast::<f32>();
|
||||||
/// assert_eq!(sim2, Similarity3::<f32>::identity());
|
/// assert_eq!(sim2, Similarity3::<f32>::identity());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn cast<To: Scalar>(self) -> Similarity<To, U3, $Rot<To>>
|
pub fn cast<To: Scalar>(self) -> Similarity<To, $Rot<To>, 3>
|
||||||
where
|
where
|
||||||
Similarity<To, U3, $Rot<To>>: SupersetOf<Self>,
|
Similarity<To, $Rot<To>, 3>: SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
crate::convert(self)
|
crate::convert(self)
|
||||||
}
|
}
|
||||||
|
@ -310,7 +308,7 @@ macro_rules! similarity_construction_impl(
|
||||||
up: &Vector3<N>,
|
up: &Vector3<N>,
|
||||||
scaling: N)
|
scaling: N)
|
||||||
-> Self {
|
-> Self {
|
||||||
Self::from_isometry(Isometry::<_, U3, $Rot<N>>::face_towards(eye, target, up), scaling)
|
Self::from_isometry(Isometry::<_, $Rot<N>, 3>::face_towards(eye, target, up), scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deprecated: Use [SimilarityMatrix3::face_towards] instead.
|
/// Deprecated: Use [SimilarityMatrix3::face_towards] instead.
|
||||||
|
@ -358,7 +356,7 @@ macro_rules! similarity_construction_impl(
|
||||||
up: &Vector3<N>,
|
up: &Vector3<N>,
|
||||||
scaling: N)
|
scaling: N)
|
||||||
-> Self {
|
-> Self {
|
||||||
Self::from_isometry(Isometry::<_, U3, $Rot<N>>::look_at_rh(eye, target, up), scaling)
|
Self::from_isometry(Isometry::<_, $Rot<N>, 3>::look_at_rh(eye, target, up), scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a left-handed look-at view matrix including a scaling factor.
|
/// Builds a left-handed look-at view matrix including a scaling factor.
|
||||||
|
@ -396,7 +394,7 @@ macro_rules! similarity_construction_impl(
|
||||||
up: &Vector3<N>,
|
up: &Vector3<N>,
|
||||||
scaling: N)
|
scaling: N)
|
||||||
-> Self {
|
-> Self {
|
||||||
Self::from_isometry(Isometry::<_, _, $Rot<N>>::look_at_lh(eye, target, up), scaling)
|
Self::from_isometry(Isometry::<_, $Rot<N>, _>::look_at_lh(eye, target, up), scaling)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
|
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimMin, DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar};
|
use crate::base::{Const, DefaultAllocator, MatrixN, Scalar};
|
||||||
|
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
|
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
|
||||||
|
@ -20,27 +20,27 @@ use crate::geometry::{
|
||||||
* Similarity -> Matrix (homogeneous)
|
* Similarity -> Matrix (homogeneous)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R1, R2> SubsetOf<Similarity<N2, D, R2>> for Similarity<N1, D, R1>
|
impl<N1, N2, R1, R2, const D: usize> SubsetOf<Similarity<N2, R2, D>> for Similarity<N1, R1, D>
|
||||||
where
|
where
|
||||||
N1: RealField + SubsetOf<N2>,
|
N1: RealField + SubsetOf<N2>,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R1: AbstractRotation<N1, D> + SubsetOf<R2>,
|
R1: AbstractRotation<N1, D> + SubsetOf<R2>,
|
||||||
R2: AbstractRotation<N2, D>,
|
R2: AbstractRotation<N2, D>,
|
||||||
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Similarity<N2, D, R2> {
|
fn to_superset(&self) -> Similarity<N2, R2, D> {
|
||||||
Similarity::from_isometry(self.isometry.to_superset(), self.scaling().to_superset())
|
Similarity::from_isometry(self.isometry.to_superset(), self.scaling().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(sim: &Similarity<N2, D, R2>) -> bool {
|
fn is_in_subset(sim: &Similarity<N2, R2, D>) -> bool {
|
||||||
crate::is_convertible::<_, Isometry<N1, D, R1>>(&sim.isometry)
|
crate::is_convertible::<_, Isometry<N1, R1, D>>(&sim.isometry)
|
||||||
&& crate::is_convertible::<_, N1>(&sim.scaling())
|
&& crate::is_convertible::<_, N1>(&sim.scaling())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(sim: &Similarity<N2, D, R2>) -> Self {
|
fn from_superset_unchecked(sim: &Similarity<N2, R2, D>) -> Self {
|
||||||
Similarity::from_isometry(
|
Similarity::from_isometry(
|
||||||
sim.isometry.to_subset_unchecked(),
|
sim.isometry.to_subset_unchecked(),
|
||||||
sim.scaling().to_subset_unchecked(),
|
sim.scaling().to_subset_unchecked(),
|
||||||
|
@ -48,64 +48,64 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D, R, C> SubsetOf<Transform<N2, D, C>> for Similarity<N1, D, R>
|
impl<N1, N2, R, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Similarity<N1, R, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
R: AbstractRotation<N1, D>
|
R: AbstractRotation<N1, D>
|
||||||
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>>
|
+ SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
|
||||||
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>,
|
+ SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
|
||||||
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .determinant()
|
Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .determinant()
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, D, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<(usize, usize), D>
|
||||||
+ Allocator<(usize, usize), D>
|
// + Allocator<N1, D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N1, D, D>
|
||||||
+ Allocator<N2, D, D>
|
// + Allocator<N2, D, D>
|
||||||
+ Allocator<N2, D>,
|
// + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, D, C> {
|
fn to_superset(&self) -> Transform<N2, C, D> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, D, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D, R> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Similarity<N1, D, R>
|
impl<N1, N2, R, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>
|
||||||
|
for Similarity<N1, R, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N1, D>
|
R: AbstractRotation<N1, D>
|
||||||
+ SubsetOf<MatrixN<N1, DimNameSum<D, U1>>>
|
+ SubsetOf<MatrixN<N1, DimNameSum<Const<D>, U1>>>
|
||||||
+ SubsetOf<MatrixN<N2, DimNameSum<D, U1>>>,
|
+ SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>,
|
||||||
D: DimNameAdd<U1> + DimMin<D, Output = D>, // needed by .determinant()
|
Const<D>: DimNameAdd<U1> + DimMin<Const<D>, Output = Const<D>>, // needed by .determinant()
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, D, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<(usize, usize), D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N1, D>
|
||||||
+ Allocator<(usize, usize), D>
|
// + Allocator<N1, D, D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N2, D, D>
|
||||||
+ Allocator<N2, D, D>
|
// + Allocator<N2, D>
|
||||||
+ Allocator<N2, D>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> {
|
fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
|
||||||
self.to_homogeneous().to_superset()
|
self.to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool {
|
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
|
||||||
let mut rot = m.fixed_slice::<D, D>(0, 0).clone_owned();
|
let mut rot = m.fixed_slice::<D, D>(0, 0).clone_owned();
|
||||||
if rot
|
if rot
|
||||||
.fixed_columns_mut::<U1>(0)
|
.fixed_columns_mut::<U1>(0)
|
||||||
|
@ -128,20 +128,20 @@ where
|
||||||
rot.fixed_columns_mut::<U1>(2).neg_mut();
|
rot.fixed_columns_mut::<U1>(2).neg_mut();
|
||||||
}
|
}
|
||||||
|
|
||||||
let bottom = m.fixed_slice::<U1, D>(D::dim(), 0);
|
let bottom = m.fixed_slice::<U1, D>(D, 0);
|
||||||
// Scalar types agree.
|
// Scalar types agree.
|
||||||
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
||||||
// The normalized block part is a rotation.
|
// The normalized block part is a rotation.
|
||||||
// rot.is_special_orthogonal(N2::default_epsilon().sqrt()) &&
|
// rot.is_special_orthogonal(N2::default_epsilon().sqrt()) &&
|
||||||
// The bottom row is (0, 0, ..., 1)
|
// The bottom row is (0, 0, ..., 1)
|
||||||
bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one()
|
bottom.iter().all(|e| e.is_zero()) && m[(D, D)] == N2::one()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
let mut mm = m.clone_owned();
|
let mut mm = m.clone_owned();
|
||||||
let na = mm.fixed_slice_mut::<D, U1>(0, 0).normalize_mut();
|
let na = mm.fixed_slice_mut::<D, U1>(0, 0).normalize_mut();
|
||||||
let nb = mm.fixed_slice_mut::<D, U1>(0, 1).normalize_mut();
|
let nb = mm.fixed_slice_mut::<D, U1>(0, 1).normalize_mut();
|
||||||
|
@ -158,7 +158,7 @@ where
|
||||||
scale = -scale;
|
scale = -scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
let t = m.fixed_slice::<D, U1>(0, D::dim()).into_owned();
|
let t = m.fixed_slice::<D, U1>(0, D).into_owned();
|
||||||
let t = Translation {
|
let t = Translation {
|
||||||
vector: crate::convert_unchecked(t),
|
vector: crate::convert_unchecked(t),
|
||||||
};
|
};
|
||||||
|
@ -171,30 +171,31 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> From<Similarity<N, D, R>> for MatrixN<N, DimNameSum<D, U1>>
|
impl<N: SimdRealField, R, const D: usize> From<Similarity<N, R, D>>
|
||||||
|
for MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
R: SubsetOf<MatrixN<N, DimNameSum<D, U1>>>,
|
R: SubsetOf<MatrixN<N, DimNameSum<Const<D>, U1>>>,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, // + Allocator<N, D>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(sim: Similarity<N, D, R>) -> Self {
|
fn from(sim: Similarity<N, R, D>) -> Self {
|
||||||
sim.to_homogeneous()
|
sim.to_homogeneous()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
|
impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
|
||||||
From<[Similarity<N::Element, D, R::Element>; 2]> for Similarity<N, D, R>
|
From<[Similarity<N::Element, R::Element, D>; 2]> for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 2]>,
|
N: From<[<N as SimdValue>::Element; 2]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Zero + Copy,
|
N::Element: Scalar + Zero + Copy,
|
||||||
R::Element: Scalar + Zero + Copy,
|
R::Element: Scalar + Zero + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Similarity<N::Element, D, R::Element>; 2]) -> Self {
|
fn from(arr: [Similarity<N::Element, R::Element, D>; 2]) -> Self {
|
||||||
let iso = Isometry::from([arr[0].isometry.clone(), arr[1].isometry.clone()]);
|
let iso = Isometry::from([arr[0].isometry.clone(), arr[1].isometry.clone()]);
|
||||||
let scale = N::from([arr[0].scaling(), arr[1].scaling()]);
|
let scale = N::from([arr[0].scaling(), arr[1].scaling()]);
|
||||||
|
|
||||||
|
@ -202,18 +203,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
|
impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
|
||||||
From<[Similarity<N::Element, D, R::Element>; 4]> for Similarity<N, D, R>
|
From<[Similarity<N::Element, R::Element, D>; 4]> for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 4]>,
|
N: From<[<N as SimdValue>::Element; 4]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Zero + Copy,
|
N::Element: Scalar + Zero + Copy,
|
||||||
R::Element: Scalar + Zero + Copy,
|
R::Element: Scalar + Zero + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Similarity<N::Element, D, R::Element>; 4]) -> Self {
|
fn from(arr: [Similarity<N::Element, R::Element, D>; 4]) -> Self {
|
||||||
let iso = Isometry::from([
|
let iso = Isometry::from([
|
||||||
arr[0].isometry.clone(),
|
arr[0].isometry.clone(),
|
||||||
arr[1].isometry.clone(),
|
arr[1].isometry.clone(),
|
||||||
|
@ -231,18 +232,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
|
impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
|
||||||
From<[Similarity<N::Element, D, R::Element>; 8]> for Similarity<N, D, R>
|
From<[Similarity<N::Element, R::Element, D>; 8]> for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 8]>,
|
N: From<[<N as SimdValue>::Element; 8]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Zero + Copy,
|
N::Element: Scalar + Zero + Copy,
|
||||||
R::Element: Scalar + Zero + Copy,
|
R::Element: Scalar + Zero + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Similarity<N::Element, D, R::Element>; 8]) -> Self {
|
fn from(arr: [Similarity<N::Element, R::Element, D>; 8]) -> Self {
|
||||||
let iso = Isometry::from([
|
let iso = Isometry::from([
|
||||||
arr[0].isometry.clone(),
|
arr[0].isometry.clone(),
|
||||||
arr[1].isometry.clone(),
|
arr[1].isometry.clone(),
|
||||||
|
@ -268,18 +269,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
|
impl<N: Scalar + Zero + PrimitiveSimdValue, R, const D: usize>
|
||||||
From<[Similarity<N::Element, D, R::Element>; 16]> for Similarity<N, D, R>
|
From<[Similarity<N::Element, R::Element, D>; 16]> for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 16]>,
|
N: From<[<N as SimdValue>::Element; 16]>,
|
||||||
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
|
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
N::Element: Scalar + Zero + Copy,
|
N::Element: Scalar + Zero + Copy,
|
||||||
R::Element: Scalar + Zero + Copy,
|
R::Element: Scalar + Zero + Copy,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Similarity<N::Element, D, R::Element>; 16]) -> Self {
|
fn from(arr: [Similarity<N::Element, R::Element, D>; 16]) -> Self {
|
||||||
let iso = Isometry::from([
|
let iso = Isometry::from([
|
||||||
arr[0].isometry.clone(),
|
arr[0].isometry.clone(),
|
||||||
arr[1].isometry.clone(),
|
arr[1].isometry.clone(),
|
||||||
|
|
|
@ -144,7 +144,7 @@ macro_rules! similarity_binop_assign_impl_all(
|
||||||
// Similarity ÷ Similarity
|
// Similarity ÷ Similarity
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => &self * &rhs;
|
[val val] => &self * &rhs;
|
||||||
[ref val] => self * &rhs;
|
[ref val] => self * &rhs;
|
||||||
[val ref] => &self * rhs;
|
[val ref] => &self * rhs;
|
||||||
|
@ -157,7 +157,7 @@ similarity_binop_impl_all!(
|
||||||
|
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Div, div;
|
Div, div;
|
||||||
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
|
@ -167,7 +167,7 @@ similarity_binop_impl_all!(
|
||||||
// Similarity ×= Translation
|
// Similarity ×= Translation
|
||||||
similarity_binop_assign_impl_all!(
|
similarity_binop_assign_impl_all!(
|
||||||
MulAssign, mul_assign;
|
MulAssign, mul_assign;
|
||||||
self: Similarity<N, D, R>, rhs: Translation<N, D>;
|
self: Similarity<N, R, D>, rhs: Translation<N, D>;
|
||||||
[val] => *self *= &rhs;
|
[val] => *self *= &rhs;
|
||||||
[ref] => {
|
[ref] => {
|
||||||
let shift = self.isometry.rotation.transform_vector(&rhs.vector) * self.scaling();
|
let shift = self.isometry.rotation.transform_vector(&rhs.vector) * self.scaling();
|
||||||
|
@ -179,7 +179,7 @@ similarity_binop_assign_impl_all!(
|
||||||
// Similarity ÷= Similarity
|
// Similarity ÷= Similarity
|
||||||
similarity_binop_assign_impl_all!(
|
similarity_binop_assign_impl_all!(
|
||||||
MulAssign, mul_assign;
|
MulAssign, mul_assign;
|
||||||
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Similarity<N, R, D>;
|
||||||
[val] => *self *= &rhs;
|
[val] => *self *= &rhs;
|
||||||
[ref] => {
|
[ref] => {
|
||||||
*self *= &rhs.isometry;
|
*self *= &rhs.isometry;
|
||||||
|
@ -189,7 +189,7 @@ similarity_binop_assign_impl_all!(
|
||||||
|
|
||||||
similarity_binop_assign_impl_all!(
|
similarity_binop_assign_impl_all!(
|
||||||
DivAssign, div_assign;
|
DivAssign, div_assign;
|
||||||
self: Similarity<N, D, R>, rhs: Similarity<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Similarity<N, R, D>;
|
||||||
[val] => *self /= &rhs;
|
[val] => *self /= &rhs;
|
||||||
// TODO: don't invert explicitly.
|
// TODO: don't invert explicitly.
|
||||||
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
|
@ -199,7 +199,7 @@ similarity_binop_assign_impl_all!(
|
||||||
// Similarity ÷= Isometry
|
// Similarity ÷= Isometry
|
||||||
similarity_binop_assign_impl_all!(
|
similarity_binop_assign_impl_all!(
|
||||||
MulAssign, mul_assign;
|
MulAssign, mul_assign;
|
||||||
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Isometry<N, R, D>;
|
||||||
[val] => *self *= &rhs;
|
[val] => *self *= &rhs;
|
||||||
[ref] => {
|
[ref] => {
|
||||||
let shift = self.isometry.rotation.transform_vector(&rhs.translation.vector) * self.scaling();
|
let shift = self.isometry.rotation.transform_vector(&rhs.translation.vector) * self.scaling();
|
||||||
|
@ -210,7 +210,7 @@ similarity_binop_assign_impl_all!(
|
||||||
|
|
||||||
similarity_binop_assign_impl_all!(
|
similarity_binop_assign_impl_all!(
|
||||||
DivAssign, div_assign;
|
DivAssign, div_assign;
|
||||||
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Isometry<N, R, D>;
|
||||||
[val] => *self /= &rhs;
|
[val] => *self /= &rhs;
|
||||||
// TODO: don't invert explicitly.
|
// TODO: don't invert explicitly.
|
||||||
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
|
@ -238,7 +238,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
MulAssign, mul_assign where N: SimdRealField for N::Element: SimdRealField;
|
MulAssign, mul_assign where N: SimdRealField for N::Element: SimdRealField;
|
||||||
(U3, U3), (U3, U3) for;
|
(U3, U3), (U3, U3) for;
|
||||||
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>;
|
self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>;
|
||||||
[val] => self.isometry.rotation *= rhs;
|
[val] => self.isometry.rotation *= rhs;
|
||||||
[ref] => self.isometry.rotation *= *rhs;
|
[ref] => self.isometry.rotation *= *rhs;
|
||||||
);
|
);
|
||||||
|
@ -246,7 +246,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
DivAssign, div_assign where N: SimdRealField for N::Element: SimdRealField;
|
DivAssign, div_assign where N: SimdRealField for N::Element: SimdRealField;
|
||||||
(U3, U3), (U3, U3) for;
|
(U3, U3), (U3, U3) for;
|
||||||
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>;
|
self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>;
|
||||||
// TODO: don't invert explicitly?
|
// TODO: don't invert explicitly?
|
||||||
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
|
@ -273,7 +273,7 @@ md_assign_impl_all!(
|
||||||
// Similarity ÷ Isometry
|
// Similarity ÷ Isometry
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>, Output = Similarity<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Isometry<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => &self * &rhs;
|
[val val] => &self * &rhs;
|
||||||
[ref val] => self * &rhs;
|
[ref val] => self * &rhs;
|
||||||
[val ref] => &self * rhs;
|
[val ref] => &self * rhs;
|
||||||
|
@ -289,7 +289,7 @@ similarity_binop_impl_all!(
|
||||||
|
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Div, div;
|
Div, div;
|
||||||
self: Similarity<N, D, R>, rhs: Isometry<N, D, R>, Output = Similarity<N, D, R>;
|
self: Similarity<N, R, D>, rhs: Isometry<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
|
@ -300,7 +300,7 @@ similarity_binop_impl_all!(
|
||||||
// Isometry ÷ Similarity
|
// Isometry ÷ Similarity
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Isometry<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>;
|
self: Isometry<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => {
|
[val val] => {
|
||||||
let scaling = rhs.scaling();
|
let scaling = rhs.scaling();
|
||||||
Similarity::from_isometry(self * rhs.isometry, scaling)
|
Similarity::from_isometry(self * rhs.isometry, scaling)
|
||||||
|
@ -321,7 +321,7 @@ similarity_binop_impl_all!(
|
||||||
|
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Div, div;
|
Div, div;
|
||||||
self: Isometry<N, D, R>, rhs: Similarity<N, D, R>, Output = Similarity<N, D, R>;
|
self: Isometry<N, R, D>, rhs: Similarity<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
|
@ -331,7 +331,7 @@ similarity_binop_impl_all!(
|
||||||
// Similarity × Point
|
// Similarity × Point
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Similarity<N, D, R>, right: Point<N, D>, Output = Point<N, D>;
|
self: Similarity<N, R, D>, right: Point<N, D>, Output = Point<N, D>;
|
||||||
[val val] => {
|
[val val] => {
|
||||||
let scaling = self.scaling();
|
let scaling = self.scaling();
|
||||||
self.isometry.translation * (self.isometry.rotation.transform_point(&right) * scaling)
|
self.isometry.translation * (self.isometry.rotation.transform_point(&right) * scaling)
|
||||||
|
@ -347,7 +347,7 @@ similarity_binop_impl_all!(
|
||||||
// Similarity × Vector
|
// Similarity × Vector
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Similarity<N, D, R>, right: VectorN<N, D>, Output = VectorN<N, D>;
|
self: Similarity<N, R, D>, right: VectorN<N, D>, Output = VectorN<N, D>;
|
||||||
[val val] => self.isometry.rotation.transform_vector(&right) * self.scaling();
|
[val val] => self.isometry.rotation.transform_vector(&right) * self.scaling();
|
||||||
[ref val] => self.isometry.rotation.transform_vector(&right) * self.scaling();
|
[ref val] => self.isometry.rotation.transform_vector(&right) * self.scaling();
|
||||||
[val ref] => self.isometry.rotation.transform_vector(right) * self.scaling();
|
[val ref] => self.isometry.rotation.transform_vector(right) * self.scaling();
|
||||||
|
@ -357,7 +357,7 @@ similarity_binop_impl_all!(
|
||||||
// Similarity × Translation
|
// Similarity × Translation
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Similarity<N, D, R>, right: Translation<N, D>, Output = Similarity<N, D, R>;
|
self: Similarity<N, R, D>, right: Translation<N, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => &self * &right;
|
[val val] => &self * &right;
|
||||||
[ref val] => self * &right;
|
[ref val] => self * &right;
|
||||||
[val ref] => &self * right;
|
[val ref] => &self * right;
|
||||||
|
@ -374,7 +374,7 @@ similarity_binop_impl_all!(
|
||||||
// Translation × Similarity
|
// Translation × Similarity
|
||||||
similarity_binop_impl_all!(
|
similarity_binop_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
self: Translation<N, D>, right: Similarity<N, D, R>, Output = Similarity<N, D, R>;
|
self: Translation<N, D>, right: Similarity<N, R, D>, Output = Similarity<N, R, D>;
|
||||||
[val val] => {
|
[val val] => {
|
||||||
let scaling = right.scaling();
|
let scaling = right.scaling();
|
||||||
Similarity::from_isometry(self * right.isometry, scaling)
|
Similarity::from_isometry(self * right.isometry, scaling)
|
||||||
|
@ -506,8 +506,8 @@ similarity_from_composition_impl_all!(
|
||||||
similarity_from_composition_impl_all!(
|
similarity_from_composition_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
(U4, U1), (U3, U1);
|
(U4, U1), (U3, U1);
|
||||||
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>,
|
self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
|
||||||
Output = Similarity<N, U3, UnitQuaternion<N>>;
|
Output = Similarity<N, UnitQuaternion<N>, 3>;
|
||||||
[val val] => {
|
[val val] => {
|
||||||
let scaling = self.scaling();
|
let scaling = self.scaling();
|
||||||
Similarity::from_isometry(self.isometry * rhs, scaling)
|
Similarity::from_isometry(self.isometry * rhs, scaling)
|
||||||
|
@ -524,8 +524,8 @@ similarity_from_composition_impl_all!(
|
||||||
similarity_from_composition_impl_all!(
|
similarity_from_composition_impl_all!(
|
||||||
Mul, mul;
|
Mul, mul;
|
||||||
(U4, U1), (U3, U1);
|
(U4, U1), (U3, U1);
|
||||||
self: UnitQuaternion<N>, right: Similarity<N, U3, UnitQuaternion<N>>,
|
self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>,
|
||||||
Output = Similarity<N, U3, UnitQuaternion<N>>;
|
Output = Similarity<N, UnitQuaternion<N>, 3>;
|
||||||
[val val] => &self * &right;
|
[val val] => &self * &right;
|
||||||
[ref val] => self * &right;
|
[ref val] => self * &right;
|
||||||
[val ref] => &self * right;
|
[val ref] => &self * right;
|
||||||
|
@ -536,8 +536,8 @@ similarity_from_composition_impl_all!(
|
||||||
similarity_from_composition_impl_all!(
|
similarity_from_composition_impl_all!(
|
||||||
Div, div;
|
Div, div;
|
||||||
(U4, U1), (U3, U1);
|
(U4, U1), (U3, U1);
|
||||||
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>,
|
self: Similarity<N, UnitQuaternion<N>, 3>, rhs: UnitQuaternion<N>,
|
||||||
Output = Similarity<N, U3, UnitQuaternion<N>>;
|
Output = Similarity<N, UnitQuaternion<N>, 3>;
|
||||||
[val val] => {
|
[val val] => {
|
||||||
let scaling = self.scaling();
|
let scaling = self.scaling();
|
||||||
Similarity::from_isometry(self.isometry / rhs, scaling)
|
Similarity::from_isometry(self.isometry / rhs, scaling)
|
||||||
|
@ -554,8 +554,8 @@ similarity_from_composition_impl_all!(
|
||||||
similarity_from_composition_impl_all!(
|
similarity_from_composition_impl_all!(
|
||||||
Div, div;
|
Div, div;
|
||||||
(U4, U1), (U3, U1);
|
(U4, U1), (U3, U1);
|
||||||
self: UnitQuaternion<N>, right: Similarity<N, U3, UnitQuaternion<N>>,
|
self: UnitQuaternion<N>, right: Similarity<N, UnitQuaternion<N>, 3>,
|
||||||
Output = Similarity<N, U3, UnitQuaternion<N>>;
|
Output = Similarity<N, UnitQuaternion<N>, 3>;
|
||||||
// TODO: don't call inverse explicitly?
|
// TODO: don't call inverse explicitly?
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
use simba::simd::{SimdRealField, SimdValue};
|
use simba::simd::{SimdRealField, SimdValue};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
|
||||||
use crate::base::dimension::DimName;
|
|
||||||
use crate::base::DefaultAllocator;
|
|
||||||
|
|
||||||
use crate::geometry::{AbstractRotation, Isometry, Similarity};
|
use crate::geometry::{AbstractRotation, Isometry, Similarity};
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName, R> SimdValue for Similarity<N, D, R>
|
impl<N: SimdRealField, R, const D: usize> SimdValue for Similarity<N, R, D>
|
||||||
where
|
where
|
||||||
N::Element: SimdRealField,
|
N::Element: SimdRealField,
|
||||||
R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>,
|
R: SimdValue<SimdBool = N::SimdBool> + AbstractRotation<N, D>,
|
||||||
R::Element: AbstractRotation<N::Element, D>,
|
R::Element: AbstractRotation<N::Element, D>,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
type Element = Similarity<N::Element, D, R::Element>;
|
type Element = Similarity<N::Element, R::Element, D>;
|
||||||
type SimdBool = N::SimdBool;
|
type SimdBool = N::SimdBool;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::{Const, Scalar, ToTypenum};
|
||||||
use crate::base::{DefaultAllocator, DimName, Scalar, ToTypenum};
|
|
||||||
use crate::geometry::{Point, Point2, Point3};
|
use crate::geometry::{Point, Point2, Point3};
|
||||||
use typenum::{self, Cmp, Greater};
|
use typenum::{self, Cmp, Greater};
|
||||||
|
|
||||||
|
@ -10,7 +9,7 @@ macro_rules! impl_swizzle {
|
||||||
/// Builds a new point from components of `self`.
|
/// Builds a new point from components of `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $name(&self) -> $Result<N>
|
pub fn $name(&self) -> $Result<N>
|
||||||
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
|
||||||
$Result::new($(self[$i].inlined_clone()),*)
|
$Result::new($(self[$i].inlined_clone()),*)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
@ -19,10 +18,10 @@ macro_rules! impl_swizzle {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Swizzling
|
/// # Swizzling
|
||||||
impl<N: Scalar, D> Point<N, D>
|
impl<N: Scalar, const D: usize> Point<N, D>
|
||||||
where
|
where
|
||||||
D: DimName + ToTypenum,
|
Const<D>: ToTypenum,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
impl_swizzle!(
|
impl_swizzle!(
|
||||||
where U0: xx() -> Point2[0, 0],
|
where U0: xx() -> Point2[0, 0],
|
||||||
|
|
|
@ -9,9 +9,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use simba::scalar::RealField;
|
use simba::scalar::RealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
use crate::base::{DefaultAllocator, MatrixN, VectorN};
|
use crate::base::{CMatrixN, CVectorN, Const, DefaultAllocator, MatrixN};
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ pub trait TCategory: Any + Debug + Copy + PartialEq + Send {
|
||||||
|
|
||||||
/// Checks that the given matrix is a valid homogeneous representation of an element of the
|
/// Checks that the given matrix is a valid homogeneous representation of an element of the
|
||||||
/// category `Self`.
|
/// category `Self`.
|
||||||
fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool
|
fn check_homogeneous_invariants<N: RealField, const D: usize>(mat: &CMatrixN<N, D>) -> bool
|
||||||
where
|
where
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy;
|
||||||
DefaultAllocator: Allocator<N, D, D>;
|
// DefaultAllocator: Allocator<N, D, D>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traits that gives the `Transform` category that is compatible with the result of the
|
/// Traits that gives the `Transform` category that is compatible with the result of the
|
||||||
|
@ -71,10 +71,10 @@ pub enum TAffine {}
|
||||||
|
|
||||||
impl TCategory for TGeneral {
|
impl TCategory for TGeneral {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_homogeneous_invariants<N: RealField, D: DimName>(_: &MatrixN<N, D>) -> bool
|
fn check_homogeneous_invariants<N: RealField, const D: usize>(_: &CMatrixN<N, D>) -> bool
|
||||||
where
|
where
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -82,10 +82,10 @@ impl TCategory for TGeneral {
|
||||||
|
|
||||||
impl TCategory for TProjective {
|
impl TCategory for TProjective {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool
|
fn check_homogeneous_invariants<N: RealField, const D: usize>(mat: &CMatrixN<N, D>) -> bool
|
||||||
where
|
where
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
mat.is_invertible()
|
mat.is_invertible()
|
||||||
}
|
}
|
||||||
|
@ -98,12 +98,12 @@ impl TCategory for TAffine {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_homogeneous_invariants<N: RealField, D: DimName>(mat: &MatrixN<N, D>) -> bool
|
fn check_homogeneous_invariants<N: RealField, const D: usize>(mat: &CMatrixN<N, D>) -> bool
|
||||||
where
|
where
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
// DefaultAllocator: Allocator<N, D, D>,
|
||||||
{
|
{
|
||||||
let last = D::dim() - 1;
|
let last = D - 1;
|
||||||
mat.is_invertible()
|
mat.is_invertible()
|
||||||
&& mat[(last, last)] == N::one()
|
&& mat[(last, last)] == N::one()
|
||||||
&& (0..last).all(|i| mat[(last, i)].is_zero())
|
&& (0..last).all(|i| mat[(last, i)].is_zero())
|
||||||
|
@ -157,33 +157,36 @@ super_tcategory_impl!(
|
||||||
/// 3D transformation.
|
/// 3D transformation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Transform<N: RealField, D: DimNameAdd<U1>, C: TCategory>
|
pub struct Transform<N: RealField, C: TCategory, const D: usize>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
matrix: MatrixN<N, DimNameSum<D, U1>>,
|
matrix: MatrixN<N, DimNameSum<Const<D>, U1>>,
|
||||||
_phantom: PhantomData<C>,
|
_phantom: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// impl<N: RealField + hash::Hash, D: DimNameAdd<U1> + hash::Hash, C: TCategory> hash::Hash for Transform<N, D, C>
|
// impl<N: RealField + hash::Hash, D: DimNameAdd<U1> + hash::Hash, C: TCategory> hash::Hash for Transform<N, C, D>
|
||||||
// where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
// where DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
// Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: hash::Hash {
|
// Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: hash::Hash {
|
||||||
// fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
// fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
// self.matrix.hash(state);
|
// self.matrix.hash(state);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1> + Copy, C: TCategory> Copy for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Copy for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Copy,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
|
Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Clone for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Clone for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -192,10 +195,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Serialize for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Serialize for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Serialize,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
|
Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Serialize,
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
|
@ -206,29 +210,33 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<'a, N: RealField, D: DimNameAdd<U1>, C: TCategory> Deserialize<'a> for Transform<N, D, C>
|
impl<'a, N: RealField, C: TCategory, const D: usize> Deserialize<'a> for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Deserialize<'a>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
|
Owned<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: Deserialize<'a>,
|
||||||
{
|
{
|
||||||
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
||||||
where
|
where
|
||||||
Des: Deserializer<'a>,
|
Des: Deserializer<'a>,
|
||||||
{
|
{
|
||||||
let matrix = MatrixN::<N, DimNameSum<D, U1>>::deserialize(deserializer)?;
|
let matrix = MatrixN::<N, DimNameSum<Const<D>, U1>>::deserialize(deserializer)?;
|
||||||
|
|
||||||
Ok(Transform::from_matrix_unchecked(matrix))
|
Ok(Transform::from_matrix_unchecked(matrix))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField + Eq, D: DimNameAdd<U1>, C: TCategory> Eq for Transform<N, D, C> where
|
impl<N: RealField + Eq, C: TCategory, const D: usize> Eq for Transform<N, C, D>
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
where
|
||||||
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> PartialEq for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> PartialEq for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, right: &Self) -> bool {
|
fn eq(&self, right: &Self) -> bool {
|
||||||
|
@ -236,14 +244,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
/// Creates a new transformation from the given homogeneous matrix. The transformation category
|
/// Creates a new transformation from the given homogeneous matrix. The transformation category
|
||||||
/// of `Self` is not checked to be verified by the given matrix.
|
/// of `Self` is not checked to be verified by the given matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_matrix_unchecked(matrix: MatrixN<N, DimNameSum<D, U1>>) -> Self {
|
pub fn from_matrix_unchecked(matrix: MatrixN<N, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
Transform {
|
Transform {
|
||||||
matrix,
|
matrix,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
|
@ -263,7 +272,7 @@ where
|
||||||
/// assert_eq!(t.into_inner(), m);
|
/// assert_eq!(t.into_inner(), m);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_inner(self) -> MatrixN<N, DimNameSum<D, U1>> {
|
pub fn into_inner(self) -> MatrixN<N, DimNameSum<Const<D>, U1>> {
|
||||||
self.matrix
|
self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +280,7 @@ where
|
||||||
/// Deprecated: Use [Transform::into_inner] instead.
|
/// Deprecated: Use [Transform::into_inner] instead.
|
||||||
#[deprecated(note = "use `.into_inner()` instead")]
|
#[deprecated(note = "use `.into_inner()` instead")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap(self) -> MatrixN<N, DimNameSum<D, U1>> {
|
pub fn unwrap(self) -> MatrixN<N, DimNameSum<Const<D>, U1>> {
|
||||||
self.matrix
|
self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +297,7 @@ where
|
||||||
/// assert_eq!(*t.matrix(), m);
|
/// assert_eq!(*t.matrix(), m);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matrix(&self) -> &MatrixN<N, DimNameSum<D, U1>> {
|
pub fn matrix(&self) -> &MatrixN<N, DimNameSum<Const<D>, U1>> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +324,7 @@ where
|
||||||
/// assert_eq!(*t.matrix(), expected);
|
/// assert_eq!(*t.matrix(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matrix_mut_unchecked(&mut self) -> &mut MatrixN<N, DimNameSum<D, U1>> {
|
pub fn matrix_mut_unchecked(&mut self) -> &mut MatrixN<N, DimNameSum<Const<D>, U1>> {
|
||||||
&mut self.matrix
|
&mut self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +335,7 @@ where
|
||||||
/// `TAffine` because not all projective transformations are affine (the other way-round is
|
/// `TAffine` because not all projective transformations are affine (the other way-round is
|
||||||
/// valid though).
|
/// valid though).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_category<CNew: SuperTCategoryOf<C>>(self) -> Transform<N, D, CNew> {
|
pub fn set_category<CNew: SuperTCategoryOf<C>>(self) -> Transform<N, CNew, D> {
|
||||||
Transform::from_matrix_unchecked(self.matrix)
|
Transform::from_matrix_unchecked(self.matrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +344,7 @@ where
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
note = "This method is redundant with automatic `Copy` and the `.clone()` method and will be removed in a future release."
|
note = "This method is redundant with automatic `Copy` and the `.clone()` method and will be removed in a future release."
|
||||||
)]
|
)]
|
||||||
pub fn clone_owned(&self) -> Transform<N, D, C> {
|
pub fn clone_owned(&self) -> Transform<N, C, D> {
|
||||||
Transform::from_matrix_unchecked(self.matrix.clone_owned())
|
Transform::from_matrix_unchecked(self.matrix.clone_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +361,7 @@ where
|
||||||
/// assert_eq!(t.into_inner(), m);
|
/// assert_eq!(t.into_inner(), m);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> {
|
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>> {
|
||||||
self.matrix().clone_owned()
|
self.matrix().clone_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +390,7 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
||||||
pub fn try_inverse(self) -> Option<Transform<N, D, C>> {
|
pub fn try_inverse(self) -> Option<Transform<N, C, D>> {
|
||||||
if let Some(m) = self.matrix.try_inverse() {
|
if let Some(m) = self.matrix.try_inverse() {
|
||||||
Some(Transform::from_matrix_unchecked(m))
|
Some(Transform::from_matrix_unchecked(m))
|
||||||
} else {
|
} else {
|
||||||
|
@ -407,7 +416,7 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use inverse_mut()?"]
|
#[must_use = "Did you mean to use inverse_mut()?"]
|
||||||
pub fn inverse(self) -> Transform<N, D, C>
|
pub fn inverse(self) -> Transform<N, C, D>
|
||||||
where
|
where
|
||||||
C: SubTCategoryOf<TProjective>,
|
C: SubTCategoryOf<TProjective>,
|
||||||
{
|
{
|
||||||
|
@ -470,14 +479,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: DimNameAdd<U1>, C> Transform<N, D, C>
|
impl<N, C, const D: usize> Transform<N, C, D>
|
||||||
where
|
where
|
||||||
N: RealField,
|
N: RealField,
|
||||||
C: TCategory,
|
C: TCategory,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
Const<D>: DimNameAdd<U1>,
|
||||||
+ Allocator<N, DimNameSum<D, U1>>
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N, D, D>
|
+ Allocator<N, DimNameSum<Const<D>, U1>>, // + Allocator<N, D, D>
|
||||||
+ Allocator<N, D>,
|
// + Allocator<N, D>
|
||||||
{
|
{
|
||||||
/// Transform the given point by this transformation.
|
/// Transform the given point by this transformation.
|
||||||
///
|
///
|
||||||
|
@ -492,18 +501,18 @@ where
|
||||||
///
|
///
|
||||||
/// This is the same as the multiplication `self * v`.
|
/// This is the same as the multiplication `self * v`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Transform<N, C, D>
|
||||||
where
|
where
|
||||||
|
Const<D>: DimNameAdd<U1>,
|
||||||
C: SubTCategoryOf<TProjective>,
|
C: SubTCategoryOf<TProjective>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N, DimNameSum<D, U1>>
|
+ Allocator<N, DimNameSum<Const<D>, U1>>, // + Allocator<N, D, D>
|
||||||
+ Allocator<N, D, D>
|
// + Allocator<N, D>
|
||||||
+ Allocator<N, D>,
|
|
||||||
{
|
{
|
||||||
/// Transform the given point by the inverse of this transformation.
|
/// Transform the given point by the inverse of this transformation.
|
||||||
/// This may be cheaper than inverting the transformation and transforming
|
/// This may be cheaper than inverting the transformation and transforming
|
||||||
|
@ -517,27 +526,29 @@ where
|
||||||
/// This may be cheaper than inverting the transformation and transforming
|
/// This may be cheaper than inverting the transformation and transforming
|
||||||
/// the vector.
|
/// the vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
pub fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> {
|
||||||
self.clone().inverse() * v
|
self.clone().inverse() * v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>> Transform<N, D, TGeneral>
|
impl<N: RealField, const D: usize> Transform<N, TGeneral, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
/// A mutable reference to underlying matrix. Use `.matrix_mut_unchecked` instead if this
|
/// A mutable reference to underlying matrix. Use `.matrix_mut_unchecked` instead if this
|
||||||
/// transformation category is not `TGeneral`.
|
/// transformation category is not `TGeneral`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn matrix_mut(&mut self) -> &mut MatrixN<N, DimNameSum<D, U1>> {
|
pub fn matrix_mut(&mut self) -> &mut MatrixN<N, DimNameSum<Const<D>, U1>> {
|
||||||
self.matrix_mut_unchecked()
|
self.matrix_mut_unchecked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> AbsDiffEq for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> AbsDiffEq for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
|
Const<D>: DimNameAdd<U1>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
type Epsilon = N::Epsilon;
|
type Epsilon = N::Epsilon;
|
||||||
|
|
||||||
|
@ -552,10 +563,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> RelativeEq for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> RelativeEq for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
|
Const<D>: DimNameAdd<U1>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_relative() -> Self::Epsilon {
|
fn default_max_relative() -> Self::Epsilon {
|
||||||
|
@ -574,10 +586,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> UlpsEq for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> UlpsEq for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
|
Const<D>: DimNameAdd<U1>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default_max_ulps() -> u32 {
|
fn default_max_ulps() -> u32 {
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
use crate::base::dimension::{U2, U3};
|
|
||||||
|
|
||||||
use crate::geometry::{TAffine, TGeneral, TProjective, Transform};
|
use crate::geometry::{TAffine, TGeneral, TProjective, Transform};
|
||||||
|
|
||||||
/// A 2D general transformation that may not be invertible. Stored as a homogeneous 3x3 matrix.
|
/// A 2D general transformation that may not be invertible. Stored as a homogeneous 3x3 matrix.
|
||||||
pub type Transform2<N> = Transform<N, U2, TGeneral>;
|
pub type Transform2<N> = Transform<N, TGeneral, 2>;
|
||||||
/// An invertible 2D general transformation. Stored as a homogeneous 3x3 matrix.
|
/// An invertible 2D general transformation. Stored as a homogeneous 3x3 matrix.
|
||||||
pub type Projective2<N> = Transform<N, U2, TProjective>;
|
pub type Projective2<N> = Transform<N, TProjective, 2>;
|
||||||
/// A 2D affine transformation. Stored as a homogeneous 3x3 matrix.
|
/// A 2D affine transformation. Stored as a homogeneous 3x3 matrix.
|
||||||
pub type Affine2<N> = Transform<N, U2, TAffine>;
|
pub type Affine2<N> = Transform<N, TAffine, 2>;
|
||||||
|
|
||||||
/// A 3D general transformation that may not be inversible. Stored as a homogeneous 4x4 matrix.
|
/// A 3D general transformation that may not be inversible. Stored as a homogeneous 4x4 matrix.
|
||||||
pub type Transform3<N> = Transform<N, U3, TGeneral>;
|
pub type Transform3<N> = Transform<N, TGeneral, 3>;
|
||||||
/// An invertible 3D general transformation. Stored as a homogeneous 4x4 matrix.
|
/// An invertible 3D general transformation. Stored as a homogeneous 4x4 matrix.
|
||||||
pub type Projective3<N> = Transform<N, U3, TProjective>;
|
pub type Projective3<N> = Transform<N, TProjective, 3>;
|
||||||
/// A 3D affine transformation. Stored as a homogeneous 4x4 matrix.
|
/// A 3D affine transformation. Stored as a homogeneous 4x4 matrix.
|
||||||
pub type Affine3<N> = Transform<N, U3, TAffine>;
|
pub type Affine3<N> = Transform<N, TAffine, 3>;
|
||||||
|
|
|
@ -4,13 +4,14 @@ use simba::scalar::RealField;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN};
|
use crate::base::{Const, DefaultAllocator, MatrixN};
|
||||||
|
|
||||||
use crate::geometry::{TCategory, Transform};
|
use crate::geometry::{TCategory, Transform};
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity transform.
|
/// Creates a new identity transform.
|
||||||
///
|
///
|
||||||
|
@ -42,13 +43,14 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn identity() -> Self {
|
pub fn identity() -> Self {
|
||||||
Self::from_matrix_unchecked(MatrixN::<_, DimNameSum<D, U1>>::identity())
|
Self::from_matrix_unchecked(MatrixN::<_, DimNameSum<Const<D>, U1>>::identity())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> One for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> One for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity transform.
|
/// Creates a new identity transform.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1,74 +1,76 @@
|
||||||
use simba::scalar::{RealField, SubsetOf};
|
use simba::scalar::{RealField, SubsetOf};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN};
|
use crate::base::{Const, DefaultAllocator, MatrixN};
|
||||||
|
|
||||||
use crate::geometry::{SuperTCategoryOf, TCategory, Transform};
|
use crate::geometry::{SuperTCategoryOf, TCategory, Transform};
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, C1, C2> SubsetOf<Transform<N2, D, C2>> for Transform<N1, D, C1>
|
impl<N1, N2, C1, C2, const D: usize> SubsetOf<Transform<N2, C2, D>> for Transform<N1, C1, D>
|
||||||
where
|
where
|
||||||
N1: RealField + SubsetOf<N2>,
|
N1: RealField + SubsetOf<N2>,
|
||||||
N2: RealField,
|
N2: RealField,
|
||||||
C1: TCategory,
|
C1: TCategory,
|
||||||
C2: SuperTCategoryOf<C1>,
|
C2: SuperTCategoryOf<C1>,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
N1::Epsilon: Copy,
|
N1::Epsilon: Copy,
|
||||||
N2::Epsilon: Copy,
|
N2::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, D, C2> {
|
fn to_superset(&self) -> Transform<N2, C2, D> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, D, C2>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C2, D>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, D, C2>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C2, D>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, C> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Transform<N1, D, C>
|
impl<N1, N2, C, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>>
|
||||||
|
for Transform<N1, C, D>
|
||||||
where
|
where
|
||||||
N1: RealField + SubsetOf<N2>,
|
N1: RealField + SubsetOf<N2>,
|
||||||
N2: RealField,
|
N2: RealField,
|
||||||
C: TCategory,
|
C: TCategory,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
N1::Epsilon: Copy,
|
N1::Epsilon: Copy,
|
||||||
N2::Epsilon: Copy,
|
N2::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> {
|
fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
|
||||||
self.matrix().to_superset()
|
self.matrix().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool {
|
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
|
||||||
C::check_homogeneous_invariants(m)
|
C::check_homogeneous_invariants(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
Self::from_matrix_unchecked(crate::convert_ref_unchecked(m))
|
Self::from_matrix_unchecked(crate::convert_ref_unchecked(m))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: RealField, D: DimName, C> From<Transform<N, D, C>> for MatrixN<N, DimNameSum<D, U1>>
|
impl<N: RealField, C, const D: usize> From<Transform<N, C, D>>
|
||||||
|
for MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
C: TCategory,
|
C: TCategory,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(t: Transform<N, D, C>) -> Self {
|
fn from(t: Transform<N, C, D>) -> Self {
|
||||||
t.to_homogeneous()
|
t.to_homogeneous()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,10 +79,10 @@ use crate::geometry::{
|
||||||
* Indexing.
|
* Indexing.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: RealField, D, C: TCategory> Index<(usize, usize)> for Transform<N, D, C>
|
impl<N: RealField, C: TCategory, const D: usize> Index<(usize, usize)> for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
D: DimName + DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
type Output = N;
|
type Output = N;
|
||||||
|
|
||||||
|
@ -93,10 +93,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only general transformations are mutably indexable.
|
// Only general transformations are mutably indexable.
|
||||||
impl<N: RealField, D> IndexMut<(usize, usize)> for Transform<N, D, TGeneral>
|
impl<N: RealField, const D: usize> IndexMut<(usize, usize)> for Transform<N, TGeneral, D>
|
||||||
where
|
where
|
||||||
D: DimName + DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, ij: (usize, usize)) -> &mut N {
|
fn index_mut(&mut self, ij: (usize, usize)) -> &mut N {
|
||||||
|
@ -108,7 +108,7 @@ where
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
|
||||||
self: Transform<N, D, C>, rhs: VectorN<N, D>, Output = VectorN<N, D>;
|
self: Transform<N, C, D>, rhs: VectorN<N, D>, Output = VectorN<N, D>;
|
||||||
[val val] => &self * &rhs;
|
[val val] => &self * &rhs;
|
||||||
[ref val] => self * &rhs;
|
[ref val] => self * &rhs;
|
||||||
[val ref] => &self * rhs;
|
[val ref] => &self * rhs;
|
||||||
|
@ -133,7 +133,7 @@ md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
|
||||||
where DefaultAllocator: Allocator<N, D, D>;
|
where DefaultAllocator: Allocator<N, D, D>;
|
||||||
self: Transform<N, D, C>, rhs: Point<N, D>, Output = Point<N, D>;
|
self: Transform<N, C, D>, rhs: Point<N, D>, Output = Point<N, D>;
|
||||||
[val val] => &self * &rhs;
|
[val val] => &self * &rhs;
|
||||||
[ref val] => self * &rhs;
|
[ref val] => self * &rhs;
|
||||||
[val ref] => &self * rhs;
|
[val ref] => &self * rhs;
|
||||||
|
@ -170,7 +170,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Transform<N, D, C>, rhs: Rotation<N, D>, Output = Transform<N, D, C::Representative>;
|
self: Transform<N, C, D>, rhs: Rotation<N, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
|
@ -181,7 +181,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Rotation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
self: Rotation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -192,7 +192,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>;
|
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>;
|
||||||
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>, Output = Transform<N, U3, C::Representative>;
|
self: Transform<N, C, 3>, rhs: UnitQuaternion<N>, Output = Transform<N, C::Representative, 3>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
|
@ -203,7 +203,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>;
|
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>;
|
||||||
self: UnitQuaternion<N>, rhs: Transform<N, U3, C>, Output = Transform<N, U3, C::Representative>;
|
self: UnitQuaternion<N>, rhs: Transform<N, C, 3>, Output = Transform<N, C::Representative, 3>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -215,7 +215,7 @@ md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
self: Transform<N, D, C>, rhs: Isometry<N, D, R>, Output = Transform<N, D, C::Representative>;
|
self: Transform<N, C, D>, rhs: Isometry<N, R, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
|
@ -227,7 +227,7 @@ md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
||||||
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
self: Isometry<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
self: Isometry<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -239,7 +239,7 @@ md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
self: Transform<N, D, C>, rhs: Similarity<N, D, R>, Output = Transform<N, D, C::Representative>;
|
self: Transform<N, C, D>, rhs: Similarity<N, R, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
|
@ -251,7 +251,7 @@ md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
||||||
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
self: Similarity<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
self: Similarity<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -270,7 +270,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Transform<N, D, C>, rhs: Translation<N, D>, Output = Transform<N, D, C::Representative>;
|
self: Transform<N, C, D>, rhs: Translation<N, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
|
@ -282,7 +282,7 @@ md_impl_all!(
|
||||||
Mul, mul where N: RealField;
|
Mul, mul where N: RealField;
|
||||||
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
||||||
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Translation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
self: Translation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -304,7 +304,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Div, div where N: RealField;
|
Div, div where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Transform<N, D, C>, rhs: Rotation<N, D>, Output = Transform<N, D, C::Representative>;
|
self: Transform<N, C, D>, rhs: Rotation<N, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
|
@ -315,7 +315,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Div, div where N: RealField;
|
Div, div where N: RealField;
|
||||||
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Rotation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
self: Rotation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
|
@ -326,7 +326,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Div, div where N: RealField;
|
Div, div where N: RealField;
|
||||||
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>;
|
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>;
|
||||||
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>, Output = Transform<N, U3, C::Representative>;
|
self: Transform<N, C, 3>, rhs: UnitQuaternion<N>, Output = Transform<N, C::Representative, 3>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
|
@ -337,7 +337,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Div, div where N: RealField;
|
Div, div where N: RealField;
|
||||||
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>;
|
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>;
|
||||||
self: UnitQuaternion<N>, rhs: Transform<N, U3, C>, Output = Transform<N, U3, C::Representative>;
|
self: UnitQuaternion<N>, rhs: Transform<N, C, 3>, Output = Transform<N, C::Representative, 3>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
|
@ -350,7 +350,7 @@ md_impl_all!(
|
||||||
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
||||||
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
||||||
// self: Transform<N, D, C>, rhs: Isometry<N, D, R>, Output = Transform<N, D, C::Representative>;
|
// self: Transform<N, C, D>, rhs: Isometry<N, R, D>, Output = Transform<N, C::Representative, D>;
|
||||||
// [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous());
|
// [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous());
|
||||||
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.inverse().to_homogeneous());
|
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.inverse().to_homogeneous());
|
||||||
// [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous());
|
// [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.inverse().to_homogeneous());
|
||||||
|
@ -363,7 +363,7 @@ md_impl_all!(
|
||||||
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
||||||
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
||||||
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
||||||
// self: Isometry<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
// self: Isometry<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -377,7 +377,7 @@ md_impl_all!(
|
||||||
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
||||||
// where SB::Alloc: Allocator<N, D, D >
|
// where SB::Alloc: Allocator<N, D, D >
|
||||||
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
||||||
// self: Transform<N, D, C>, rhs: Similarity<N, D, R>, Output = Transform<N, D, C::Representative>;
|
// self: Transform<N, C, D>, rhs: Similarity<N, R, D>, Output = Transform<N, C::Representative, D>;
|
||||||
// [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
// [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
|
||||||
// [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
// [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
|
||||||
|
@ -391,7 +391,7 @@ md_impl_all!(
|
||||||
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >
|
||||||
// where SA::Alloc: Allocator<N, D, D >
|
// where SA::Alloc: Allocator<N, D, D >
|
||||||
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
|
||||||
// self: Similarity<N, D, R>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
// self: Similarity<N, R, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
|
||||||
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
|
||||||
|
@ -402,7 +402,7 @@ md_impl_all!(
|
||||||
md_impl_all!(
|
md_impl_all!(
|
||||||
Div, div where N: RealField;
|
Div, div where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Transform<N, D, C>, rhs: Translation<N, D>, Output = Transform<N, D, C::Representative>;
|
self: Transform<N, C, D>, rhs: Translation<N, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
||||||
|
@ -414,7 +414,7 @@ md_impl_all!(
|
||||||
Div, div where N: RealField;
|
Div, div where N: RealField;
|
||||||
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
|
||||||
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>;
|
||||||
self: Translation<N, D>, rhs: Transform<N, D, C>, Output = Transform<N, D, C::Representative>;
|
self: Translation<N, D>, rhs: Transform<N, C, D>, Output = Transform<N, C::Representative, D>;
|
||||||
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self.inverse() * rhs };
|
||||||
|
@ -435,7 +435,7 @@ md_assign_impl_all!(
|
||||||
MulAssign, mul_assign where N: RealField;
|
MulAssign, mul_assign where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
self: Transform<N, D, C>, rhs: Similarity<N, D, R>;
|
self: Transform<N, C, D>, rhs: Similarity<N, R, D>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
);
|
);
|
||||||
|
@ -445,7 +445,7 @@ md_assign_impl_all!(
|
||||||
MulAssign, mul_assign where N: RealField;
|
MulAssign, mul_assign where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
self: Transform<N, D, C>, rhs: Isometry<N, D, R>;
|
self: Transform<N, C, D>, rhs: Isometry<N, R, D>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
);
|
);
|
||||||
|
@ -462,7 +462,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
MulAssign, mul_assign where N: RealField;
|
MulAssign, mul_assign where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
|
||||||
self: Transform<N, D, C>, rhs: Translation<N, D>;
|
self: Transform<N, C, D>, rhs: Translation<N, D>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
);
|
);
|
||||||
|
@ -471,7 +471,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
MulAssign, mul_assign where N: RealField;
|
MulAssign, mul_assign where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory;
|
||||||
self: Transform<N, D, C>, rhs: Rotation<N, D>;
|
self: Transform<N, C, D>, rhs: Rotation<N, D>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
);
|
);
|
||||||
|
@ -480,7 +480,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
MulAssign, mul_assign where N: RealField;
|
MulAssign, mul_assign where N: RealField;
|
||||||
(U4, U4), (U4, U1) for C: TCategory;
|
(U4, U4), (U4, U1) for C: TCategory;
|
||||||
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>;
|
self: Transform<N, C, 3>, rhs: UnitQuaternion<N>;
|
||||||
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
|
||||||
);
|
);
|
||||||
|
@ -500,7 +500,7 @@ md_assign_impl_all!(
|
||||||
// DivAssign, div_assign;
|
// DivAssign, div_assign;
|
||||||
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
// self: Transform<N, D, C>, rhs: Similarity<N, D, R>;
|
// self: Transform<N, C, D>, rhs: Similarity<N, R, D>;
|
||||||
// [val] => *self *= rhs.inverse();
|
// [val] => *self *= rhs.inverse();
|
||||||
// [ref] => *self *= rhs.inverse();
|
// [ref] => *self *= rhs.inverse();
|
||||||
// );
|
// );
|
||||||
|
@ -511,7 +511,7 @@ md_assign_impl_all!(
|
||||||
// DivAssign, div_assign;
|
// DivAssign, div_assign;
|
||||||
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
|
||||||
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<MatrixN<N, DimNameSum<D, U1>> >;
|
||||||
// self: Transform<N, D, C>, rhs: Isometry<N, D, R>;
|
// self: Transform<N, C, D>, rhs: Isometry<N, R, D>;
|
||||||
// [val] => *self *= rhs.inverse();
|
// [val] => *self *= rhs.inverse();
|
||||||
// [ref] => *self *= rhs.inverse();
|
// [ref] => *self *= rhs.inverse();
|
||||||
// );
|
// );
|
||||||
|
@ -520,7 +520,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
DivAssign, div_assign where N: RealField;
|
DivAssign, div_assign where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory;
|
||||||
self: Transform<N, D, C>, rhs: Translation<N, D>;
|
self: Transform<N, C, D>, rhs: Translation<N, D>;
|
||||||
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
);
|
);
|
||||||
|
@ -529,7 +529,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
DivAssign, div_assign where N: RealField;
|
DivAssign, div_assign where N: RealField;
|
||||||
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory;
|
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory;
|
||||||
self: Transform<N, D, C>, rhs: Rotation<N, D>;
|
self: Transform<N, C, D>, rhs: Rotation<N, D>;
|
||||||
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
);
|
);
|
||||||
|
@ -538,7 +538,7 @@ md_assign_impl_all!(
|
||||||
md_assign_impl_all!(
|
md_assign_impl_all!(
|
||||||
DivAssign, div_assign where N: RealField;
|
DivAssign, div_assign where N: RealField;
|
||||||
(U4, U4), (U4, U1) for C: TCategory;
|
(U4, U4), (U4, U1) for C: TCategory;
|
||||||
self: Transform<N, U3, C>, rhs: UnitQuaternion<N>;
|
self: Transform<N, C, 3>, rhs: UnitQuaternion<N>;
|
||||||
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,19 +2,20 @@ use simba::simd::SimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar};
|
use crate::base::{Const, DefaultAllocator, MatrixN, Scalar};
|
||||||
use crate::RealField;
|
use crate::RealField;
|
||||||
|
|
||||||
use crate::geometry::{TCategory, Transform};
|
use crate::geometry::{TCategory, Transform};
|
||||||
|
|
||||||
impl<N: RealField, D: DimNameAdd<U1>, C> SimdValue for Transform<N, D, C>
|
impl<N: RealField, C, const D: usize> SimdValue for Transform<N, C, D>
|
||||||
where
|
where
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
C: TCategory,
|
C: TCategory,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
Const<D>: DimNameAdd<U1>,
|
||||||
+ Allocator<N::Element, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
|
+ Allocator<N::Element, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
type Element = Transform<N::Element, D, C>;
|
type Element = Transform<N::Element, C, D>;
|
||||||
type SimdBool = N::SimdBool;
|
type SimdBool = N::SimdBool;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -14,45 +14,44 @@ use abomonation::Abomonation;
|
||||||
use simba::scalar::{ClosedAdd, ClosedNeg, ClosedSub};
|
use simba::scalar::{ClosedAdd, ClosedNeg, ClosedSub};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN};
|
use crate::base::{CVectorN, Const, DefaultAllocator, MatrixN, Scalar};
|
||||||
|
|
||||||
use crate::geometry::Point;
|
use crate::geometry::Point;
|
||||||
|
|
||||||
/// A translation.
|
/// A translation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Translation<N: Scalar, D: DimName>
|
pub struct Translation<N: Scalar, const D: usize>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
|
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
|
||||||
/// translated.
|
/// translated.
|
||||||
pub vector: VectorN<N, D>,
|
pub vector: CVectorN<N, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash> hash::Hash for Translation<N, D>
|
impl<N: Scalar + hash::Hash, const D: usize> hash::Hash for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: hash::Hash,
|
Owned<N, Const<D>>: hash::Hash,
|
||||||
{
|
{
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
self.vector.hash(state)
|
self.vector.hash(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: DimName> Copy for Translation<N, D>
|
impl<N: Scalar + Copy, const D: usize> Copy for Translation<N, D> where
|
||||||
where
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
Owned<N, Const<D>>: Copy
|
||||||
Owned<N, D>: Copy,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Clone for Translation<N, D>
|
impl<N: Scalar, const D: usize> Clone for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Clone,
|
Owned<N, Const<D>>: Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -65,8 +64,8 @@ impl<N, D> Abomonation for Translation<N, D>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
N: Scalar,
|
||||||
D: DimName,
|
D: DimName,
|
||||||
VectorN<N, D>: Abomonation,
|
CVectorN<N, D>: Abomonation,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
self.vector.entomb(writer)
|
self.vector.entomb(writer)
|
||||||
|
@ -82,9 +81,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<N: Scalar, D: DimName> Serialize for Translation<N, D>
|
impl<N: Scalar, const D: usize> Serialize for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Serialize,
|
Owned<N, D>: Serialize,
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -96,29 +95,29 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<'a, N: Scalar, D: DimName> Deserialize<'a> for Translation<N, D>
|
impl<'a, N: Scalar, const D: usize> Deserialize<'a> for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Deserialize<'a>,
|
Owned<N, D>: Deserialize<'a>,
|
||||||
{
|
{
|
||||||
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
||||||
where
|
where
|
||||||
Des: Deserializer<'a>,
|
Des: Deserializer<'a>,
|
||||||
{
|
{
|
||||||
let matrix = VectorN::<N, D>::deserialize(deserializer)?;
|
let matrix = CVectorN::<N, D>::deserialize(deserializer)?;
|
||||||
|
|
||||||
Ok(Translation::from(matrix))
|
Ok(Translation::from(matrix))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Translation<N, D>
|
impl<N: Scalar, const D: usize> Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new translation from the given vector.
|
/// Creates a new translation from the given vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated(note = "Use `::from` instead.")]
|
#[deprecated(note = "Use `::from` instead.")]
|
||||||
pub fn from_vector(vector: VectorN<N, D>) -> Translation<N, D> {
|
pub fn from_vector(vector: CVectorN<N, D>) -> Translation<N, D> {
|
||||||
Translation { vector }
|
Translation { vector }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,15 +163,14 @@ where
|
||||||
/// assert_eq!(t.to_homogeneous(), expected);
|
/// assert_eq!(t.to_homogeneous(), expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>>
|
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
N: Zero + One,
|
N: Zero + One,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator: Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity();
|
let mut res = MatrixN::<N, DimNameSum<D, U1>>::identity();
|
||||||
res.fixed_slice_mut::<D, U1>(0, D::dim())
|
res.fixed_slice_mut::<D, U1>(0, D).copy_from(&self.vector);
|
||||||
.copy_from(&self.vector);
|
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -204,9 +202,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + ClosedAdd, D: DimName> Translation<N, D>
|
impl<N: Scalar + ClosedAdd, const D: usize> Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Translate the given point.
|
/// Translate the given point.
|
||||||
///
|
///
|
||||||
|
@ -224,9 +222,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + ClosedSub, D: DimName> Translation<N, D>
|
impl<N: Scalar + ClosedSub, const D: usize> Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Translate the given point by the inverse of this translation.
|
/// Translate the given point by the inverse of this translation.
|
||||||
///
|
///
|
||||||
|
@ -242,11 +240,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Eq, D: DimName> Eq for Translation<N, D> where DefaultAllocator: Allocator<N, D> {}
|
impl<N: Scalar + Eq, const D: usize> Eq for Translation<N, D>
|
||||||
|
// where DefaultAllocator: Allocator<N, D>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PartialEq, D: DimName> PartialEq for Translation<N, D>
|
impl<N: Scalar + PartialEq, const D: usize> PartialEq for Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, right: &Translation<N, D>) -> bool {
|
fn eq(&self, right: &Translation<N, D>) -> bool {
|
||||||
|
@ -254,9 +255,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for Translation<N, D>
|
impl<N: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
type Epsilon = N::Epsilon;
|
type Epsilon = N::Epsilon;
|
||||||
|
@ -272,9 +273,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + RelativeEq, D: DimName> RelativeEq for Translation<N, D>
|
impl<N: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -294,9 +295,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + UlpsEq, D: DimName> UlpsEq for Translation<N, D>
|
impl<N: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
N::Epsilon: Copy,
|
N::Epsilon: Copy,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -315,9 +316,9 @@ where
|
||||||
* Display
|
* Display
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N: Scalar + fmt::Display, D: DimName> fmt::Display for Translation<N, D>
|
impl<N: Scalar + fmt::Display, const D: usize> fmt::Display for Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<usize, D>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let precision = f.precision().unwrap_or(3);
|
let precision = f.precision().unwrap_or(3);
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
|
||||||
|
|
||||||
use crate::geometry::Translation;
|
use crate::geometry::Translation;
|
||||||
|
|
||||||
/// A 1-dimensional translation.
|
/// A 1-dimensional translation.
|
||||||
pub type Translation1<N> = Translation<N, U1>;
|
pub type Translation1<N> = Translation<N, 1>;
|
||||||
|
|
||||||
/// A 2-dimensional translation.
|
/// A 2-dimensional translation.
|
||||||
pub type Translation2<N> = Translation<N, U2>;
|
pub type Translation2<N> = Translation<N, 2>;
|
||||||
|
|
||||||
/// A 3-dimensional translation.
|
/// A 3-dimensional translation.
|
||||||
pub type Translation3<N> = Translation<N, U3>;
|
pub type Translation3<N> = Translation<N, 3>;
|
||||||
|
|
||||||
/// A 4-dimensional translation.
|
/// A 4-dimensional translation.
|
||||||
pub type Translation4<N> = Translation<N, U4>;
|
pub type Translation4<N> = Translation<N, 4>;
|
||||||
|
|
||||||
/// A 5-dimensional translation.
|
/// A 5-dimensional translation.
|
||||||
pub type Translation5<N> = Translation<N, U5>;
|
pub type Translation5<N> = Translation<N, 5>;
|
||||||
|
|
||||||
/// A 6-dimensional translation.
|
/// A 6-dimensional translation.
|
||||||
pub type Translation6<N> = Translation<N, U6>;
|
pub type Translation6<N> = Translation<N, 6>;
|
||||||
|
|
|
@ -12,15 +12,13 @@ use rand::{
|
||||||
|
|
||||||
use simba::scalar::{ClosedAdd, SupersetOf};
|
use simba::scalar::{ClosedAdd, SupersetOf};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::{CVectorN, Scalar};
|
||||||
use crate::base::dimension::{DimName, U1, U2, U3, U4, U5, U6};
|
|
||||||
use crate::base::{DefaultAllocator, Scalar, VectorN};
|
|
||||||
|
|
||||||
use crate::geometry::Translation;
|
use crate::geometry::Translation;
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> Translation<N, D>
|
impl<N: Scalar, const D: usize> Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new identity translation.
|
/// Creates a new identity translation.
|
||||||
///
|
///
|
||||||
|
@ -41,7 +39,7 @@ where
|
||||||
where
|
where
|
||||||
N: Zero,
|
N: Zero,
|
||||||
{
|
{
|
||||||
Self::from(VectorN::<N, D>::from_element(N::zero()))
|
Self::from(CVectorN::<N, D>::from_element(N::zero()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast the components of `self` to another type.
|
/// Cast the components of `self` to another type.
|
||||||
|
@ -56,15 +54,15 @@ where
|
||||||
pub fn cast<To: Scalar>(self) -> Translation<To, D>
|
pub fn cast<To: Scalar>(self) -> Translation<To, D>
|
||||||
where
|
where
|
||||||
Translation<To, D>: SupersetOf<Self>,
|
Translation<To, D>: SupersetOf<Self>,
|
||||||
DefaultAllocator: Allocator<To, D>,
|
// DefaultAllocator: Allocator<To, D>,
|
||||||
{
|
{
|
||||||
crate::convert(self)
|
crate::convert(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + ClosedAdd, D: DimName> One for Translation<N, D>
|
impl<N: Scalar + Zero + ClosedAdd, const D: usize> One for Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
|
@ -73,27 +71,27 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
impl<N: Scalar, D: DimName> Distribution<Translation<N, D>> for Standard
|
impl<N: Scalar, const D: usize> Distribution<Translation<N, D>> for Standard
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Standard: Distribution<N>,
|
Standard: Distribution<N>,
|
||||||
{
|
{
|
||||||
/// Generate an arbitrary random variate for testing purposes.
|
/// Generate an arbitrary random variate for testing purposes.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> {
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> {
|
||||||
Translation::from(rng.gen::<VectorN<N, D>>())
|
Translation::from(rng.gen::<CVectorN<N, D>>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl<N: Scalar + Arbitrary + Send, D: DimName> Arbitrary for Translation<N, D>
|
impl<N: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Translation<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
Owned<N, D>: Send,
|
Owned<N, D>: Send,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn arbitrary(rng: &mut Gen) -> Self {
|
fn arbitrary(rng: &mut Gen) -> Self {
|
||||||
let v: VectorN<N, D> = Arbitrary::arbitrary(rng);
|
let v: CVectorN<N, D> = Arbitrary::arbitrary(rng);
|
||||||
Self::from(v)
|
Self::from(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,16 +102,17 @@ where
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
macro_rules! componentwise_constructors_impl(
|
macro_rules! componentwise_constructors_impl(
|
||||||
($($doc: expr; $D: ty, $($args: ident:$irow: expr),*);* $(;)*) => {$(
|
($($doc: expr; $D: expr, $($args: ident:$irow: expr),*);* $(;)*) => {$(
|
||||||
impl<N: Scalar> Translation<N, $D>
|
impl<N: Scalar> Translation<N, $D>
|
||||||
where DefaultAllocator: Allocator<N, $D> {
|
// where DefaultAllocator: Allocator<N, $D>
|
||||||
|
{
|
||||||
#[doc = "Initializes this translation from its components."]
|
#[doc = "Initializes this translation from its components."]
|
||||||
#[doc = "# Example\n```"]
|
#[doc = "# Example\n```"]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
#[doc = "```"]
|
#[doc = "```"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new($($args: N),*) -> Self {
|
pub fn new($($args: N),*) -> Self {
|
||||||
Self::from(VectorN::<N, $D>::new($($args),*))
|
Self::from(CVectorN::<N, $D>::new($($args),*))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*}
|
)*}
|
||||||
|
@ -121,15 +120,15 @@ macro_rules! componentwise_constructors_impl(
|
||||||
|
|
||||||
componentwise_constructors_impl!(
|
componentwise_constructors_impl!(
|
||||||
"# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);";
|
"# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);";
|
||||||
U1, x:0;
|
1, x:0;
|
||||||
"# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);";
|
"# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);";
|
||||||
U2, x:0, y:1;
|
2, x:0, y:1;
|
||||||
"# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);";
|
"# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);";
|
||||||
U3, x:0, y:1, z:2;
|
3, x:0, y:1, z:2;
|
||||||
"# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);";
|
"# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);";
|
||||||
U4, x:0, y:1, z:2, w:3;
|
4, x:0, y:1, z:2, w:3;
|
||||||
"# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);";
|
"# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);";
|
||||||
U5, x:0, y:1, z:2, w:3, a:4;
|
5, x:0, y:1, z:2, w:3, a:4;
|
||||||
"# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);";
|
"# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);";
|
||||||
U6, x:0, y:1, z:2, w:3, a:4, b:5;
|
6, x:0, y:1, z:2, w:3, a:4, b:5;
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,8 +4,8 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::PrimitiveSimdValue;
|
use simba::simd::PrimitiveSimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
|
||||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN};
|
use crate::base::{Const, DefaultAllocator, MatrixN, Scalar, VectorN};
|
||||||
|
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
|
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
|
||||||
|
@ -24,11 +24,11 @@ use crate::geometry::{
|
||||||
* Translation -> Matrix (homogeneous)
|
* Translation -> Matrix (homogeneous)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<N1, N2, D: DimName> SubsetOf<Translation<N2, D>> for Translation<N1, D>
|
impl<N1, N2, const D: usize> SubsetOf<Translation<N2, D>> for Translation<N1, D>
|
||||||
where
|
where
|
||||||
N1: Scalar,
|
N1: Scalar,
|
||||||
N2: Scalar + SupersetOf<N1>,
|
N2: Scalar + SupersetOf<N1>,
|
||||||
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Translation<N2, D> {
|
fn to_superset(&self) -> Translation<N2, D> {
|
||||||
|
@ -48,25 +48,25 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R> SubsetOf<Isometry<N2, D, R>> for Translation<N1, D>
|
impl<N1, N2, R, const D: usize> SubsetOf<Isometry<N2, R, D>> for Translation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, D>,
|
R: AbstractRotation<N2, D>,
|
||||||
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Isometry<N2, D, R> {
|
fn to_superset(&self) -> Isometry<N2, R, D> {
|
||||||
Isometry::from_parts(self.to_superset(), R::identity())
|
Isometry::from_parts(self.to_superset(), R::identity())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(iso: &Isometry<N2, D, R>) -> bool {
|
fn is_in_subset(iso: &Isometry<N2, R, D>) -> bool {
|
||||||
iso.rotation == R::identity()
|
iso.rotation == R::identity()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(iso: &Isometry<N2, D, R>) -> Self {
|
fn from_superset_unchecked(iso: &Isometry<N2, R, D>) -> Self {
|
||||||
Self::from_superset_unchecked(&iso.translation)
|
Self::from_superset_unchecked(&iso.translation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,96 +95,96 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D: DimName, R> SubsetOf<Similarity<N2, D, R>> for Translation<N1, D>
|
impl<N1, N2, R, const D: usize> SubsetOf<Similarity<N2, R, D>> for Translation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, D>,
|
R: AbstractRotation<N2, D>,
|
||||||
DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
// DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Similarity<N2, D, R> {
|
fn to_superset(&self) -> Similarity<N2, R, D> {
|
||||||
Similarity::from_parts(self.to_superset(), R::identity(), N2::one())
|
Similarity::from_parts(self.to_superset(), R::identity(), N2::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(sim: &Similarity<N2, D, R>) -> bool {
|
fn is_in_subset(sim: &Similarity<N2, R, D>) -> bool {
|
||||||
sim.isometry.rotation == R::identity() && sim.scaling() == N2::one()
|
sim.isometry.rotation == R::identity() && sim.scaling() == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(sim: &Similarity<N2, D, R>) -> Self {
|
fn from_superset_unchecked(sim: &Similarity<N2, R, D>) -> Self {
|
||||||
Self::from_superset_unchecked(&sim.isometry.translation)
|
Self::from_superset_unchecked(&sim.isometry.translation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D, C> SubsetOf<Transform<N2, D, C>> for Translation<N1, D>
|
impl<N1, N2, C, const D: usize> SubsetOf<Transform<N2, C, D>> for Translation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N2, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, D, C> {
|
fn to_superset(&self) -> Transform<N2, C, D> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, D, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, D>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, D>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, D> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Translation<N1, D>
|
impl<N1, N2, const D: usize> SubsetOf<MatrixN<N2, DimNameSum<Const<D>, U1>>> for Translation<N1, D>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N1, D>
|
DefaultAllocator: Allocator<N1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
|
||||||
+ Allocator<N2, D>
|
+ Allocator<N2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
||||||
+ Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>>
|
// + Allocator<N1, D>
|
||||||
+ Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
// + Allocator<N2, D>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> {
|
fn to_superset(&self) -> MatrixN<N2, DimNameSum<Const<D>, U1>> {
|
||||||
self.to_homogeneous().to_superset()
|
self.to_homogeneous().to_superset()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool {
|
fn is_in_subset(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> bool {
|
||||||
let id = m.fixed_slice::<DimNameSum<D, U1>, D>(0, 0);
|
let id = m.fixed_slice::<DimNameSum<Const<D>, U1>, D>(0, 0);
|
||||||
|
|
||||||
// Scalar types agree.
|
// Scalar types agree.
|
||||||
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) &&
|
||||||
// The block part does nothing.
|
// The block part does nothing.
|
||||||
id.is_identity(N2::zero()) &&
|
id.is_identity(N2::zero()) &&
|
||||||
// The normalization factor is one.
|
// The normalization factor is one.
|
||||||
m[(D::dim(), D::dim())] == N2::one()
|
m[(D, D)] == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self {
|
fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<Const<D>, U1>>) -> Self {
|
||||||
let t = m.fixed_slice::<D, U1>(0, D::dim());
|
let t = m.fixed_slice::<D, U1>(0, D);
|
||||||
Self {
|
Self {
|
||||||
vector: crate::convert_unchecked(t.into_owned()),
|
vector: crate::convert_unchecked(t.into_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Zero + One, D: DimName> From<Translation<N, D>> for MatrixN<N, DimNameSum<D, U1>>
|
impl<N: Scalar + Zero + One, const D: usize> From<Translation<N, D>>
|
||||||
|
for MatrixN<N, DimNameSum<Const<D>, U1>>
|
||||||
where
|
where
|
||||||
D: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
|
DefaultAllocator:
|
||||||
|
Allocator<N, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> + Allocator<N, Const<D>>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(t: Translation<N, D>) -> Self {
|
fn from(t: Translation<N, D>) -> Self {
|
||||||
|
@ -192,22 +192,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Translation<N, D>
|
impl<N: Scalar, const D: usize> From<VectorN<N, Const<D>>> for Translation<N, D>
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(vector: VectorN<N, D>) -> Self {
|
fn from(vector: VectorN<N, Const<D>>) -> Self {
|
||||||
Translation { vector }
|
Translation { vector }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 2]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 2]>
|
||||||
for Translation<N, D>
|
for Translation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Translation<N::Element, D>; 2]) -> Self {
|
fn from(arr: [Translation<N::Element, D>; 2]) -> Self {
|
||||||
|
@ -218,12 +218,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 4]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 4]>
|
||||||
for Translation<N, D>
|
for Translation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Translation<N::Element, D>; 4]) -> Self {
|
fn from(arr: [Translation<N::Element, D>; 4]) -> Self {
|
||||||
|
@ -236,12 +236,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 8]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 8]>
|
||||||
for Translation<N, D>
|
for Translation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Translation<N::Element, D>; 8]) -> Self {
|
fn from(arr: [Translation<N::Element, D>; 8]) -> Self {
|
||||||
|
@ -258,12 +258,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 16]>
|
impl<N: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<N::Element, D>; 16]>
|
||||||
for Translation<N, D>
|
for Translation<N, D>
|
||||||
where
|
where
|
||||||
N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
|
N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [Translation<N::Element, D>; 16]) -> Self {
|
fn from(arr: [Translation<N::Element, D>; 16]) -> Self {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
|
||||||
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
|
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
|
||||||
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
use crate::base::Scalar;
|
||||||
use crate::base::{DefaultAllocator, Scalar};
|
|
||||||
|
|
||||||
use crate::geometry::Translation;
|
use crate::geometry::Translation;
|
||||||
|
|
||||||
|
@ -15,9 +13,10 @@ use crate::geometry::Translation;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
macro_rules! deref_impl(
|
macro_rules! deref_impl(
|
||||||
($D: ty, $Target: ident $(, $comps: ident)*) => {
|
($D: expr, $Target: ident $(, $comps: ident)*) => {
|
||||||
impl<N: Scalar> Deref for Translation<N, $D>
|
impl<N: Scalar> Deref for Translation<N, $D>
|
||||||
where DefaultAllocator: Allocator<N, $D> {
|
// where DefaultAllocator: Allocator<N, $D>
|
||||||
|
{
|
||||||
type Target = $Target<N>;
|
type Target = $Target<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -27,7 +26,8 @@ macro_rules! deref_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar> DerefMut for Translation<N, $D>
|
impl<N: Scalar> DerefMut for Translation<N, $D>
|
||||||
where DefaultAllocator: Allocator<N, $D> {
|
// where DefaultAllocator: Allocator<N, $D>
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { mem::transmute(self) }
|
unsafe { mem::transmute(self) }
|
||||||
|
@ -36,9 +36,9 @@ macro_rules! deref_impl(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
deref_impl!(U1, X, x);
|
deref_impl!(1, X, x);
|
||||||
deref_impl!(U2, XY, x, y);
|
deref_impl!(2, XY, x, y);
|
||||||
deref_impl!(U3, XYZ, x, y, z);
|
deref_impl!(3, XYZ, x, y, z);
|
||||||
deref_impl!(U4, XYZW, x, y, z, w);
|
deref_impl!(4, XYZW, x, y, z, w);
|
||||||
deref_impl!(U5, XYZWA, x, y, z, w, a);
|
deref_impl!(5, XYZWA, x, y, z, w, a);
|
||||||
deref_impl!(U6, XYZWAB, x, y, z, w, a, b);
|
deref_impl!(6, XYZWAB, x, y, z, w, a, b);
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use simba::simd::SimdValue;
|
use simba::simd::SimdValue;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::VectorN;
|
||||||
use crate::base::dimension::DimName;
|
|
||||||
use crate::base::{DefaultAllocator, VectorN};
|
|
||||||
use crate::Scalar;
|
use crate::Scalar;
|
||||||
|
|
||||||
use crate::geometry::Translation;
|
use crate::geometry::Translation;
|
||||||
|
|
||||||
impl<N: Scalar + SimdValue, D: DimName> SimdValue for Translation<N, D>
|
impl<N: Scalar + SimdValue, const D: usize> SimdValue for Translation<N, D>
|
||||||
where
|
where
|
||||||
N::Element: Scalar,
|
N::Element: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
|
||||||
{
|
{
|
||||||
type Element = Translation<N::Element, D>;
|
type Element = Translation<N::Element, D>;
|
||||||
type SimdBool = N::SimdBool;
|
type SimdBool = N::SimdBool;
|
||||||
|
|
|
@ -4,7 +4,6 @@ use num_complex::Complex;
|
||||||
use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
use simba::scalar::{RealField, SubsetOf, SupersetOf};
|
||||||
use simba::simd::{PrimitiveSimdValue, SimdRealField};
|
use simba::simd::{PrimitiveSimdValue, SimdRealField};
|
||||||
|
|
||||||
use crate::base::dimension::U2;
|
|
||||||
use crate::base::{Matrix2, Matrix3, Scalar};
|
use crate::base::{Matrix2, Matrix3, Scalar};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
AbstractRotation, Isometry, Rotation2, Similarity, SuperTCategoryOf, TAffine, Transform,
|
AbstractRotation, Isometry, Rotation2, Similarity, SuperTCategoryOf, TAffine, Transform,
|
||||||
|
@ -17,9 +16,9 @@ use crate::geometry::{
|
||||||
*
|
*
|
||||||
* UnitComplex -> UnitComplex
|
* UnitComplex -> UnitComplex
|
||||||
* UnitComplex -> Rotation<U1>
|
* UnitComplex -> Rotation<U1>
|
||||||
* UnitComplex -> Isometry<U2>
|
* UnitComplex -> Isometry<2>
|
||||||
* UnitComplex -> Similarity<U2>
|
* UnitComplex -> Similarity<2>
|
||||||
* UnitComplex -> Transform<U2>
|
* UnitComplex -> Transform<2>
|
||||||
* UnitComplex -> Matrix<U3> (homogeneous)
|
* UnitComplex -> Matrix<U3> (homogeneous)
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
|
@ -70,68 +69,68 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, R> SubsetOf<Isometry<N2, U2, R>> for UnitComplex<N1>
|
impl<N1, N2, R> SubsetOf<Isometry<N2, R, 2>> for UnitComplex<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, U2> + SupersetOf<Self>,
|
R: AbstractRotation<N2, 2> + SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Isometry<N2, U2, R> {
|
fn to_superset(&self) -> Isometry<N2, R, 2> {
|
||||||
Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
|
Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(iso: &Isometry<N2, U2, R>) -> bool {
|
fn is_in_subset(iso: &Isometry<N2, R, 2>) -> bool {
|
||||||
iso.translation.vector.is_zero()
|
iso.translation.vector.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(iso: &Isometry<N2, U2, R>) -> Self {
|
fn from_superset_unchecked(iso: &Isometry<N2, R, 2>) -> Self {
|
||||||
crate::convert_ref_unchecked(&iso.rotation)
|
crate::convert_ref_unchecked(&iso.rotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, R> SubsetOf<Similarity<N2, U2, R>> for UnitComplex<N1>
|
impl<N1, N2, R> SubsetOf<Similarity<N2, R, 2>> for UnitComplex<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
R: AbstractRotation<N2, U2> + SupersetOf<Self>,
|
R: AbstractRotation<N2, 2> + SupersetOf<Self>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Similarity<N2, U2, R> {
|
fn to_superset(&self) -> Similarity<N2, R, 2> {
|
||||||
Similarity::from_isometry(crate::convert_ref(self), N2::one())
|
Similarity::from_isometry(crate::convert_ref(self), N2::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(sim: &Similarity<N2, U2, R>) -> bool {
|
fn is_in_subset(sim: &Similarity<N2, R, 2>) -> bool {
|
||||||
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
|
sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(sim: &Similarity<N2, U2, R>) -> Self {
|
fn from_superset_unchecked(sim: &Similarity<N2, R, 2>) -> Self {
|
||||||
crate::convert_ref_unchecked(&sim.isometry)
|
crate::convert_ref_unchecked(&sim.isometry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N1, N2, C> SubsetOf<Transform<N2, U2, C>> for UnitComplex<N1>
|
impl<N1, N2, C> SubsetOf<Transform<N2, C, 2>> for UnitComplex<N1>
|
||||||
where
|
where
|
||||||
N1: RealField,
|
N1: RealField,
|
||||||
N2: RealField + SupersetOf<N1>,
|
N2: RealField + SupersetOf<N1>,
|
||||||
C: SuperTCategoryOf<TAffine>,
|
C: SuperTCategoryOf<TAffine>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> Transform<N2, U2, C> {
|
fn to_superset(&self) -> Transform<N2, C, 2> {
|
||||||
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(t: &Transform<N2, U2, C>) -> bool {
|
fn is_in_subset(t: &Transform<N2, C, 2>) -> bool {
|
||||||
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
<Self as SubsetOf<_>>::is_in_subset(t.matrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(t: &Transform<N2, U2, C>) -> Self {
|
fn from_superset_unchecked(t: &Transform<N2, C, 2>) -> Self {
|
||||||
Self::from_superset_unchecked(t.matrix())
|
Self::from_superset_unchecked(t.matrix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -384,9 +384,12 @@ pub fn partial_sort2<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<(&'a T, &'
|
||||||
/// * [distance](fn.distance.html)
|
/// * [distance](fn.distance.html)
|
||||||
/// * [distance_squared](fn.distance_squared.html)
|
/// * [distance_squared](fn.distance_squared.html)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn center<N: SimdComplexField, D: DimName>(p1: &Point<N, D>, p2: &Point<N, D>) -> Point<N, D>
|
pub fn center<N: SimdComplexField, const D: usize>(
|
||||||
where
|
p1: &Point<N, D>,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
p2: &Point<N, D>,
|
||||||
|
) -> Point<N, D>
|
||||||
|
// where
|
||||||
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into()
|
((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into()
|
||||||
}
|
}
|
||||||
|
@ -398,12 +401,12 @@ where
|
||||||
/// * [center](fn.center.html)
|
/// * [center](fn.center.html)
|
||||||
/// * [distance_squared](fn.distance_squared.html)
|
/// * [distance_squared](fn.distance_squared.html)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn distance<N: SimdComplexField, D: DimName>(
|
pub fn distance<N: SimdComplexField, const D: usize>(
|
||||||
p1: &Point<N, D>,
|
p1: &Point<N, D>,
|
||||||
p2: &Point<N, D>,
|
p2: &Point<N, D>,
|
||||||
) -> N::SimdRealField
|
) -> N::SimdRealField
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
(&p2.coords - &p1.coords).norm()
|
(&p2.coords - &p1.coords).norm()
|
||||||
}
|
}
|
||||||
|
@ -415,12 +418,12 @@ where
|
||||||
/// * [center](fn.center.html)
|
/// * [center](fn.center.html)
|
||||||
/// * [distance](fn.distance.html)
|
/// * [distance](fn.distance.html)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn distance_squared<N: SimdComplexField, D: DimName>(
|
pub fn distance_squared<N: SimdComplexField, const D: usize>(
|
||||||
p1: &Point<N, D>,
|
p1: &Point<N, D>,
|
||||||
p2: &Point<N, D>,
|
p2: &Point<N, D>,
|
||||||
) -> N::SimdRealField
|
) -> N::SimdRealField
|
||||||
where
|
// where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
// DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
(&p2.coords - &p1.coords).norm_squared()
|
(&p2.coords - &p1.coords).norm_squared()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue