2020-03-21 19:16:46 +08:00
|
|
|
|
use num::{One, Zero};
|
2018-02-02 19:26:35 +08:00
|
|
|
|
use std::ops::{Div, DivAssign, Mul, MulAssign};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-03-22 06:22:55 +08:00
|
|
|
|
use simba::scalar::{ClosedAdd, ClosedMul};
|
|
|
|
|
use simba::simd::SimdRealField;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2019-03-23 21:29:07 +08:00
|
|
|
|
use crate::base::allocator::Allocator;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
use crate::base::dimension::{U1, U2, U3};
|
2021-04-11 17:00:38 +08:00
|
|
|
|
use crate::base::{Const, DefaultAllocator, SVector, Unit};
|
2020-03-21 19:16:46 +08:00
|
|
|
|
use crate::Scalar;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-03-25 02:06:28 +08:00
|
|
|
|
use crate::geometry::{
|
|
|
|
|
AbstractRotation, Isometry, Point, Rotation, Translation, UnitComplex, UnitQuaternion,
|
|
|
|
|
};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: there are several cloning of rotations that we could probably get rid of (but we didn't
|
2016-12-05 05:44:42 +08:00
|
|
|
|
// yet because that would require to add a bound like `where for<'a, 'b> &'a R: Mul<&'b R, Output = R>`
|
|
|
|
|
// which is quite ugly.
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* In this file, we provide:
|
|
|
|
|
* =========================
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* (Operators)
|
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry × Isometry
|
|
|
|
|
* Isometry × R
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry ÷ Isometry
|
|
|
|
|
* Isometry ÷ R
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry × Point
|
|
|
|
|
* Isometry × Vector
|
2018-02-02 19:26:29 +08:00
|
|
|
|
* Isometry × Unit<Vector>
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry × Translation
|
|
|
|
|
* Translation × Isometry
|
|
|
|
|
* Translation × R -> Isometry<R>
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* NOTE: The following are provided explicitly because we can't have R × Isometry.
|
|
|
|
|
* Rotation × Isometry<Rotation>
|
|
|
|
|
* UnitQuaternion × Isometry<UnitQuaternion>
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Rotation ÷ Isometry<Rotation>
|
|
|
|
|
* UnitQuaternion ÷ Isometry<UnitQuaternion>
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Rotation × Translation -> Isometry<Rotation>
|
|
|
|
|
* UnitQuaternion × Translation -> Isometry<UnitQuaternion>
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* (Assignment Operators)
|
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry ×= Translation
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry ×= Isometry
|
|
|
|
|
* Isometry ×= R
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Isometry ÷= Isometry
|
|
|
|
|
* Isometry ÷= R
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
macro_rules! isometry_binop_impl(
|
|
|
|
|
($Op: ident, $op: ident;
|
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
|
|
|
|
|
$action: expr; $($lives: tt),*) => {
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<$($lives ,)* T: SimdRealField, R, const D: usize> $Op<$Rhs> for $Lhs
|
|
|
|
|
where T::Element: SimdRealField,
|
|
|
|
|
R: AbstractRotation<T, D>, {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
type Output = $Output;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn $op($lhs, $rhs: $Rhs) -> Self::Output {
|
|
|
|
|
$action
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! isometry_binop_impl_all(
|
|
|
|
|
($Op: ident, $op: ident;
|
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
|
|
|
|
|
[val val] => $action_val_val: expr;
|
|
|
|
|
[ref val] => $action_ref_val: expr;
|
|
|
|
|
[val ref] => $action_val_ref: expr;
|
|
|
|
|
[ref ref] => $action_ref_ref: expr;) => {
|
|
|
|
|
isometry_binop_impl!(
|
|
|
|
|
$Op, $op;
|
|
|
|
|
$lhs: $Lhs, $rhs: $Rhs, Output = $Output;
|
|
|
|
|
$action_val_val; );
|
|
|
|
|
|
|
|
|
|
isometry_binop_impl!(
|
|
|
|
|
$Op, $op;
|
|
|
|
|
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Output;
|
|
|
|
|
$action_ref_val; 'a);
|
|
|
|
|
|
|
|
|
|
isometry_binop_impl!(
|
|
|
|
|
$Op, $op;
|
|
|
|
|
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Output;
|
|
|
|
|
$action_val_ref; 'b);
|
|
|
|
|
|
|
|
|
|
isometry_binop_impl!(
|
|
|
|
|
$Op, $op;
|
|
|
|
|
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Output;
|
|
|
|
|
$action_ref_ref; 'a, 'b);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! isometry_binop_assign_impl_all(
|
|
|
|
|
($OpAssign: ident, $op_assign: ident;
|
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
|
|
|
|
|
[val] => $action_val: expr;
|
|
|
|
|
[ref] => $action_ref: expr;) => {
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<T: SimdRealField, R, const D: usize> $OpAssign<$Rhs> for $Lhs
|
|
|
|
|
where T::Element: SimdRealField,
|
|
|
|
|
R: AbstractRotation<T, D> {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn $op_assign(&mut $lhs, $rhs: $Rhs) {
|
|
|
|
|
$action_val
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<'b, T: SimdRealField, R, const D: usize> $OpAssign<&'b $Rhs> for $Lhs
|
|
|
|
|
where T::Element: SimdRealField,
|
|
|
|
|
R: AbstractRotation<T, D> {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn $op_assign(&mut $lhs, $rhs: &'b $Rhs) {
|
|
|
|
|
$action_ref
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry × Isometry
|
|
|
|
|
// Isometry ÷ Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, rhs: Isometry<T, R, D>, Output = Isometry<T, R, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val val] => &self * &rhs;
|
|
|
|
|
[ref val] => self * &rhs;
|
|
|
|
|
[val ref] => &self * rhs;
|
|
|
|
|
[ref ref] => {
|
|
|
|
|
let shift = self.rotation.transform_vector(&rhs.translation.vector);
|
|
|
|
|
|
2020-10-26 01:23:24 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2018-10-28 14:33:39 +08:00
|
|
|
|
Isometry::from_parts(Translation::from(&self.translation.vector + shift),
|
2020-11-15 23:57:49 +08:00
|
|
|
|
self.rotation.clone() * rhs.rotation.clone()) // TODO: too bad we have to clone.
|
2016-12-05 05:44:42 +08:00
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Div, div;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, rhs: Isometry<T, R, D>, Output = Isometry<T, R, D>;
|
2020-10-26 01:23:24 +08:00
|
|
|
|
[val 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() };
|
|
|
|
|
[ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry ×= Translation
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_assign_impl_all!(
|
|
|
|
|
MulAssign, mul_assign;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, rhs: Translation<T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val] => *self *= &rhs;
|
2020-10-26 19:44:53 +08:00
|
|
|
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let shift = self.rotation.transform_vector(&rhs.vector);
|
|
|
|
|
self.translation.vector += shift;
|
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry ×= Isometry
|
|
|
|
|
// Isometry ÷= Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_assign_impl_all!(
|
|
|
|
|
MulAssign, mul_assign;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, rhs: Isometry<T, R, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val] => *self *= &rhs;
|
|
|
|
|
[ref] => {
|
|
|
|
|
let shift = self.rotation.transform_vector(&rhs.translation.vector);
|
|
|
|
|
self.translation.vector += shift;
|
|
|
|
|
self.rotation *= rhs.rotation.clone();
|
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
isometry_binop_assign_impl_all!(
|
|
|
|
|
DivAssign, div_assign;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, rhs: Isometry<T, R, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val] => *self /= &rhs;
|
2020-10-26 19:44:53 +08:00
|
|
|
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry ×= R
|
|
|
|
|
// Isometry ÷= R
|
2020-03-21 19:16:46 +08:00
|
|
|
|
md_assign_impl_all!(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
MulAssign, mul_assign where T: SimdRealField for T::Element: SimdRealField;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(Const<D>, U1), (Const<D>, Const<D>)
|
|
|
|
|
const D; for; where;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val] => self.rotation *= rhs;
|
|
|
|
|
[ref] => self.rotation *= rhs.clone();
|
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
md_assign_impl_all!(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
DivAssign, div_assign where T: SimdRealField for T::Element: SimdRealField;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(Const<D>, U1), (Const<D>, Const<D>)
|
|
|
|
|
const D; for; where;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: don't invert explicitly?
|
2020-10-26 19:44:53 +08:00
|
|
|
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
|
|
|
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
md_assign_impl_all!(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
MulAssign, mul_assign where T: SimdRealField for T::Element: SimdRealField;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(U3, U3), (U3, U3)
|
|
|
|
|
const; for; where;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val] => self.rotation *= rhs;
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref] => self.rotation *= *rhs;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
md_assign_impl_all!(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
DivAssign, div_assign where T: SimdRealField for T::Element: SimdRealField;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(U3, U3), (U3, U3)
|
|
|
|
|
const; for; where;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: don't invert explicitly?
|
2020-10-26 19:44:53 +08:00
|
|
|
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
|
|
|
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2020-03-25 02:06:28 +08:00
|
|
|
|
md_assign_impl_all!(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
MulAssign, mul_assign where T: SimdRealField for T::Element: SimdRealField;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(U2, U2), (U2, U2)
|
|
|
|
|
const; for; where;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
|
2020-03-25 02:06:28 +08:00
|
|
|
|
[val] => self.rotation *= rhs;
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref] => self.rotation *= *rhs;
|
2020-03-25 02:06:28 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
md_assign_impl_all!(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
DivAssign, div_assign where T: SimdRealField for T::Element: SimdRealField;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(U2, U2), (U2, U2)
|
|
|
|
|
const; for; where;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: don't invert explicitly?
|
2020-10-26 19:44:53 +08:00
|
|
|
|
[val] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
|
|
|
|
[ref] => #[allow(clippy::suspicious_op_assign_impl)] { *self *= rhs.inverse() };
|
2020-03-25 02:06:28 +08:00
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry × Point
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, right: Point<T, D>, Output = Point<T, D>;
|
2017-08-03 01:37:44 +08:00
|
|
|
|
[val val] => self.translation * self.rotation.transform_point(&right);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[ref val] => &self.translation * self.rotation.transform_point(&right);
|
2017-08-03 01:37:44 +08:00
|
|
|
|
[val ref] => self.translation * self.rotation.transform_point(right);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[ref ref] => &self.translation * self.rotation.transform_point(right);
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry × Vector
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Mul, mul;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: because of `transform_vector`, we cant use a generic storage type for the rhs vector,
|
2021-04-11 17:00:38 +08:00
|
|
|
|
// i.e., right: Vector<T, D, S> where S: Storage<T, D>.
|
|
|
|
|
self: Isometry<T, R, D>, right: SVector<T, D>, Output = SVector<T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val val] => self.rotation.transform_vector(&right);
|
|
|
|
|
[ref val] => self.rotation.transform_vector(&right);
|
|
|
|
|
[val ref] => self.rotation.transform_vector(right);
|
|
|
|
|
[ref ref] => self.rotation.transform_vector(right);
|
|
|
|
|
);
|
|
|
|
|
|
2018-02-02 19:26:29 +08:00
|
|
|
|
// Isometry × Unit<Vector>
|
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Mul, mul;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: because of `transform_vector`, we cant use a generic storage type for the rhs vector,
|
2021-04-11 17:00:38 +08:00
|
|
|
|
// i.e., right: Vector<T, D, S> where S: Storage<T, D>.
|
|
|
|
|
self: Isometry<T, R, D>, right: Unit<SVector<T, D>>, Output = Unit<SVector<T, D>>;
|
2018-02-02 19:26:29 +08:00
|
|
|
|
[val val] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
|
|
|
|
|
[ref val] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
|
|
|
|
|
[val ref] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
|
|
|
|
|
[ref ref] => Unit::new_unchecked(self.rotation.transform_vector(right.as_ref()));
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Isometry × Translation
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, R, D>, right: Translation<T, D>, Output = Isometry<T, R, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val val] => &self * &right;
|
|
|
|
|
[ref val] => self * &right;
|
|
|
|
|
[val ref] => &self * right;
|
|
|
|
|
[ref ref] => {
|
2020-10-26 01:23:24 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let new_tr = &self.translation.vector + self.rotation.transform_vector(&right.vector);
|
2018-10-28 14:33:39 +08:00
|
|
|
|
Isometry::from_parts(Translation::from(new_tr), self.rotation.clone())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Translation × Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_binop_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation<T, D>, right: Isometry<T, R, D>, Output = Isometry<T, R, D>;
|
2017-08-03 01:37:44 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self * right.translation, right.rotation);
|
|
|
|
|
[ref val] => Isometry::from_parts(self * &right.translation, right.rotation);
|
|
|
|
|
[val ref] => Isometry::from_parts(self * &right.translation, right.rotation.clone());
|
|
|
|
|
[ref ref] => Isometry::from_parts(self * &right.translation, right.rotation.clone());
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! isometry_from_composition_impl(
|
|
|
|
|
($Op: ident, $op: ident;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
$($Dims: ident),*;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
|
|
|
|
|
$action: expr; $($lives: tt),*) => {
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<$($lives ,)* T: SimdRealField $(, const $Dims: usize)*> $Op<$Rhs> for $Lhs
|
|
|
|
|
where T::Element: SimdRealField {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
type Output = $Output;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn $op($lhs, $rhs: $Rhs) -> Self::Output {
|
|
|
|
|
$action
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! isometry_from_composition_impl_all(
|
|
|
|
|
($Op: ident, $op: ident;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
$($Dims: ident),*;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Output: ty;
|
|
|
|
|
[val val] => $action_val_val: expr;
|
|
|
|
|
[ref val] => $action_ref_val: expr;
|
|
|
|
|
[val ref] => $action_val_ref: expr;
|
|
|
|
|
[ref ref] => $action_ref_ref: expr;) => {
|
|
|
|
|
|
|
|
|
|
isometry_from_composition_impl!(
|
|
|
|
|
$Op, $op;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
$($Dims),*;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
$lhs: $Lhs, $rhs: $Rhs, Output = $Output;
|
|
|
|
|
$action_val_val; );
|
|
|
|
|
|
|
|
|
|
isometry_from_composition_impl!(
|
|
|
|
|
$Op, $op;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
$($Dims),*;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Output;
|
|
|
|
|
$action_ref_val; 'a);
|
|
|
|
|
|
|
|
|
|
isometry_from_composition_impl!(
|
|
|
|
|
$Op, $op;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
$($Dims),*;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Output;
|
|
|
|
|
$action_val_ref; 'b);
|
|
|
|
|
|
|
|
|
|
isometry_from_composition_impl!(
|
|
|
|
|
$Op, $op;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
$($Dims),*;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Output;
|
|
|
|
|
$action_ref_ref; 'a, 'b);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Rotation × Translation
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
D;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Rotation<T, D>, right: Translation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
|
2018-10-28 14:33:39 +08:00
|
|
|
|
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
|
|
|
|
[ref val] => Isometry::from_parts(Translation::from(self * right.vector), self.clone());
|
|
|
|
|
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
|
|
|
|
[ref ref] => Isometry::from_parts(Translation::from(self * &right.vector), self.clone());
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// UnitQuaternion × Translation
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, right: Translation<T, 3>,
|
|
|
|
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
2018-10-28 14:33:39 +08:00
|
|
|
|
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self);
|
2018-10-28 14:33:39 +08:00
|
|
|
|
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), *self);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
// Isometry × Rotation
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
D;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
|
|
|
|
|
Output = Isometry<T, Rotation<T, D>, D>;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
2020-11-15 23:57:49 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone.
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Rotation × Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
D;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Rotation<T, D>, right: Isometry<T, Rotation<T, D>, D>,
|
|
|
|
|
Output = Isometry<T, Rotation<T, D>, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val val] => &self * &right;
|
|
|
|
|
[ref val] => self * &right;
|
|
|
|
|
[val ref] => &self * right;
|
|
|
|
|
[ref ref] => {
|
|
|
|
|
let shift = self * &right.translation.vector;
|
2018-10-28 14:33:39 +08:00
|
|
|
|
Isometry::from_parts(Translation::from(shift), self * &right.rotation)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
// Isometry ÷ Rotation
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Div, div;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
D;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
|
|
|
|
|
Output = Isometry<T, Rotation<T, D>, D>;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
2020-11-15 23:57:49 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone.
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
|
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Rotation ÷ Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Div, div;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
D;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Rotation<T, D>, right: Isometry<T, Rotation<T, D>, D>,
|
|
|
|
|
Output = Isometry<T, Rotation<T, D>, D>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: don't call inverse explicitly?
|
2020-10-26 01:23:24 +08:00
|
|
|
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
|
|
|
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
|
|
|
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
|
|
|
|
[ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
// Isometry × UnitQuaternion
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
|
|
|
|
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone.
|
|
|
|
|
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation * *rhs);
|
2020-03-21 19:16:46 +08:00
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// UnitQuaternion × Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, right: Isometry<T, UnitQuaternion<T>, 3>,
|
|
|
|
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
[val val] => &self * &right;
|
|
|
|
|
[ref val] => self * &right;
|
|
|
|
|
[val ref] => &self * right;
|
|
|
|
|
[ref ref] => {
|
|
|
|
|
let shift = self * &right.translation.vector;
|
2018-10-28 14:33:39 +08:00
|
|
|
|
Isometry::from_parts(Translation::from(shift), self * &right.rotation)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
// Isometry ÷ UnitQuaternion
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Div, div;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
|
|
|
|
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone.
|
|
|
|
|
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation / *rhs);
|
2020-03-21 19:16:46 +08:00
|
|
|
|
);
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// UnitQuaternion ÷ Isometry
|
2016-12-05 05:44:42 +08:00
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Div, div;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, right: Isometry<T, UnitQuaternion<T>, 3>,
|
|
|
|
|
Output = Isometry<T, UnitQuaternion<T>, 3>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: don't call inverse explicitly?
|
2020-10-26 01:23:24 +08:00
|
|
|
|
[val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
|
|
|
|
[ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
|
|
|
|
[val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
|
|
|
|
[ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
2018-04-27 13:52:41 +08:00
|
|
|
|
|
|
|
|
|
// Translation × Rotation
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
D;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation<T, D>, right: Rotation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
|
2018-04-27 13:52:41 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self, right);
|
|
|
|
|
[ref val] => Isometry::from_parts(self.clone(), right);
|
|
|
|
|
[val ref] => Isometry::from_parts(self, right.clone());
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.clone(), right.clone());
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Translation × UnitQuaternion
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation<T, 3>, right: UnitQuaternion<T>, Output = Isometry<T, UnitQuaternion<T>, 3>;
|
2018-04-27 13:52:41 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self, right);
|
|
|
|
|
[ref val] => Isometry::from_parts(self.clone(), right);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[val ref] => Isometry::from_parts(self, *right);
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.clone(), *right);
|
2018-04-27 13:52:41 +08:00
|
|
|
|
);
|
2020-03-25 02:06:28 +08:00
|
|
|
|
|
|
|
|
|
// Isometry × UnitComplex
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
|
|
|
|
|
Output = Isometry<T, UnitComplex<T>, 2>;
|
2020-03-25 02:06:28 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone.
|
|
|
|
|
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation * *rhs);
|
2020-03-25 02:06:28 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Isometry ÷ UnitComplex
|
|
|
|
|
isometry_from_composition_impl_all!(
|
|
|
|
|
Div, div;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
|
|
|
|
|
Output = Isometry<T, UnitComplex<T>, 2>;
|
2020-03-25 02:06:28 +08:00
|
|
|
|
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
2020-11-19 19:55:15 +08:00
|
|
|
|
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone.
|
|
|
|
|
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
|
|
|
|
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation / *rhs);
|
2020-03-25 02:06:28 +08:00
|
|
|
|
);
|