2021-06-18 15:45:37 +08:00
|
|
|
|
// The macros break if the references are taken out, for some reason.
|
|
|
|
|
#![allow(clippy::op_ref)]
|
|
|
|
|
|
2020-12-16 22:02:02 +08:00
|
|
|
|
/*
|
|
|
|
|
* This file provides:
|
|
|
|
|
*
|
|
|
|
|
* NOTE: Work in progress https://github.com/dimforge/nalgebra/issues/487
|
|
|
|
|
*
|
|
|
|
|
* (Dual Quaternion)
|
|
|
|
|
*
|
|
|
|
|
* Index<usize>
|
|
|
|
|
* IndexMut<usize>
|
|
|
|
|
*
|
|
|
|
|
* (Assignment Operators)
|
|
|
|
|
*
|
2021-01-29 08:41:55 +08:00
|
|
|
|
* -DualQuaternion
|
2020-12-16 22:02:02 +08:00
|
|
|
|
* DualQuaternion × Scalar
|
|
|
|
|
* DualQuaternion × DualQuaternion
|
|
|
|
|
* DualQuaternion + DualQuaternion
|
|
|
|
|
* DualQuaternion - DualQuaternion
|
2021-01-29 08:41:55 +08:00
|
|
|
|
* DualQuaternion × UnitDualQuaternion
|
|
|
|
|
* DualQuaternion ÷ UnitDualQuaternion
|
|
|
|
|
* -UnitDualQuaternion
|
|
|
|
|
* UnitDualQuaternion × DualQuaternion
|
|
|
|
|
* UnitDualQuaternion × UnitDualQuaternion
|
|
|
|
|
* UnitDualQuaternion ÷ UnitDualQuaternion
|
|
|
|
|
* UnitDualQuaternion × Translation3
|
|
|
|
|
* UnitDualQuaternion ÷ Translation3
|
|
|
|
|
* UnitDualQuaternion × UnitQuaternion
|
|
|
|
|
* UnitDualQuaternion ÷ UnitQuaternion
|
|
|
|
|
* Translation3 × UnitDualQuaternion
|
|
|
|
|
* Translation3 ÷ UnitDualQuaternion
|
|
|
|
|
* UnitQuaternion × UnitDualQuaternion
|
|
|
|
|
* UnitQuaternion ÷ UnitDualQuaternion
|
|
|
|
|
* UnitDualQuaternion × Isometry3
|
|
|
|
|
* UnitDualQuaternion ÷ Isometry3
|
|
|
|
|
* Isometry3 × UnitDualQuaternion
|
|
|
|
|
* Isometry3 ÷ UnitDualQuaternion
|
|
|
|
|
* UnitDualQuaternion × Point
|
|
|
|
|
* UnitDualQuaternion × Vector
|
|
|
|
|
* UnitDualQuaternion × Unit<Vector>
|
2020-12-16 22:02:02 +08:00
|
|
|
|
*
|
|
|
|
|
* ---
|
|
|
|
|
*
|
|
|
|
|
* References:
|
|
|
|
|
* Multiplication:
|
|
|
|
|
* - https://cs.gmu.edu/~jmlien/teaching/cs451/uploads/Main/dual-quaternion.pdf
|
|
|
|
|
*/
|
|
|
|
|
|
2021-01-29 07:46:14 +08:00
|
|
|
|
use crate::base::storage::Storage;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
use crate::{
|
2021-04-12 16:32:17 +08:00
|
|
|
|
DualQuaternion, Isometry3, Point, Point3, Quaternion, SimdRealField, Translation3, Unit,
|
|
|
|
|
UnitDualQuaternion, UnitQuaternion, Vector, Vector3, U3,
|
2021-01-29 06:25:32 +08:00
|
|
|
|
};
|
|
|
|
|
use std::ops::{
|
2021-01-29 07:46:14 +08:00
|
|
|
|
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
|
2021-01-29 06:25:32 +08:00
|
|
|
|
};
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
|
impl<T: SimdRealField> AsRef<[T; 8]> for DualQuaternion<T> {
|
2020-12-18 23:09:56 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn as_ref(&self) -> &[T; 8] {
|
2021-08-03 00:41:46 +08:00
|
|
|
|
unsafe { &*(self as *const Self as *const [T; 8]) }
|
2020-12-18 23:09:56 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
|
impl<T: SimdRealField> AsMut<[T; 8]> for DualQuaternion<T> {
|
2020-12-18 23:09:56 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn as_mut(&mut self) -> &mut [T; 8] {
|
2021-08-03 00:41:46 +08:00
|
|
|
|
unsafe { &mut *(self as *mut Self as *mut [T; 8]) }
|
2020-12-18 23:09:56 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
|
impl<T: SimdRealField> Index<usize> for DualQuaternion<T> {
|
2021-04-11 17:00:38 +08:00
|
|
|
|
type Output = T;
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, i: usize) -> &Self::Output {
|
2020-12-18 23:09:56 +08:00
|
|
|
|
&self.as_ref()[i]
|
2020-12-16 22:02:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
|
impl<T: SimdRealField> IndexMut<usize> for DualQuaternion<T> {
|
2020-12-16 22:02:02 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn index_mut(&mut self, i: usize) -> &mut T {
|
2020-12-18 23:09:56 +08:00
|
|
|
|
&mut self.as_mut()[i]
|
2020-12-16 22:02:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<T: SimdRealField> Neg for DualQuaternion<T>
|
2020-12-16 22:02:02 +08:00
|
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
|
T::Element: SimdRealField,
|
2020-12-16 22:02:02 +08:00
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
type Output = DualQuaternion<T>;
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn neg(self) -> Self::Output {
|
|
|
|
|
DualQuaternion::from_real_and_dual(-self.real, -self.dual)
|
2020-12-16 22:02:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<'a, T: SimdRealField> Neg for &'a DualQuaternion<T>
|
2020-12-16 22:02:02 +08:00
|
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
|
T::Element: SimdRealField,
|
2020-12-16 22:02:02 +08:00
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
type Output = DualQuaternion<T>;
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn neg(self) -> Self::Output {
|
|
|
|
|
DualQuaternion::from_real_and_dual(-&self.real, -&self.dual)
|
2020-12-16 22:02:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<T: SimdRealField> Neg for UnitDualQuaternion<T>
|
2020-12-16 22:02:02 +08:00
|
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
|
T::Element: SimdRealField,
|
2020-12-16 22:02:02 +08:00
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
type Output = UnitDualQuaternion<T>;
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn neg(self) -> Self::Output {
|
|
|
|
|
UnitDualQuaternion::new_unchecked(-self.into_inner())
|
2020-12-16 22:02:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<'a, T: SimdRealField> Neg for &'a UnitDualQuaternion<T>
|
2020-12-16 22:02:02 +08:00
|
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
|
T::Element: SimdRealField,
|
2020-12-16 22:02:02 +08:00
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
type Output = UnitDualQuaternion<T>;
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn neg(self) -> Self::Output {
|
|
|
|
|
UnitDualQuaternion::new_unchecked(-self.as_ref())
|
2020-12-16 22:02:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
macro_rules! dual_quaternion_op_impl(
|
|
|
|
|
($Op: ident, $op: ident;
|
|
|
|
|
($LhsRDim: ident, $LhsCDim: ident), ($RhsRDim: ident, $RhsCDim: ident)
|
|
|
|
|
$(for $Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*;
|
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty $(=> $VDimA: ty, $VDimB: ty)*;
|
|
|
|
|
$action: expr; $($lives: tt),*) => {
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<$($lives ,)* T: SimdRealField $(, $Storage: $StoragesBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs
|
2021-04-12 16:32:17 +08:00
|
|
|
|
where T::Element: SimdRealField, {
|
2021-01-29 06:25:32 +08:00
|
|
|
|
type Output = $Result;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn $op($lhs, $rhs: $Rhs) -> Self::Output {
|
|
|
|
|
$action
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// DualQuaternion + DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Add, add;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: &'b DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
&self.real + &rhs.real,
|
|
|
|
|
&self.dual + &rhs.dual,
|
|
|
|
|
);
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Add, add;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
&self.real + rhs.real,
|
|
|
|
|
&self.dual + rhs.dual,
|
|
|
|
|
);
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Add, add;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self.real + &rhs.real,
|
|
|
|
|
self.dual + &rhs.dual,
|
|
|
|
|
);
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Add, add;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self.real + rhs.real,
|
|
|
|
|
self.dual + rhs.dual,
|
|
|
|
|
); );
|
|
|
|
|
|
|
|
|
|
// DualQuaternion - DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Sub, sub;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: &'b DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
&self.real - &rhs.real,
|
|
|
|
|
&self.dual - &rhs.dual,
|
|
|
|
|
);
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Sub, sub;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
&self.real - rhs.real,
|
|
|
|
|
&self.dual - rhs.dual,
|
|
|
|
|
);
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Sub, sub;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self.real - &rhs.real,
|
|
|
|
|
self.dual - &rhs.dual,
|
|
|
|
|
);
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Sub, sub;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self.real - rhs.real,
|
|
|
|
|
self.dual - rhs.dual,
|
|
|
|
|
); );
|
|
|
|
|
|
|
|
|
|
// DualQuaternion × DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: &'b DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
&self.real * &rhs.real,
|
|
|
|
|
&self.real * &rhs.dual + &self.dual * &rhs.real,
|
|
|
|
|
);
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
self * &rhs;
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * rhs;
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: DualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * &rhs; );
|
|
|
|
|
|
2021-01-29 08:27:40 +08:00
|
|
|
|
// DualQuaternion × UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self * rhs.dual_quaternion();
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self * rhs.dual_quaternion();
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self * rhs.dual_quaternion();
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self * rhs.dual_quaternion(););
|
|
|
|
|
|
|
|
|
|
// DualQuaternion ÷ UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{ self * rhs.inverse().dual_quaternion() };
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a DualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{ self * rhs.inverse().dual_quaternion() };
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{ self * rhs.inverse().dual_quaternion() };
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{ self * rhs.inverse().dual_quaternion() };);
|
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
// UnitDualQuaternion × UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
UnitDualQuaternion::new_unchecked(self.as_ref() * rhs.as_ref());
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
self * &rhs;
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * rhs;
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * &rhs; );
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ÷ UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)] { self * rhs.inverse() };
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
self / &rhs;
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self / rhs;
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitDualQuaternion<T>, Output = UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self / &rhs; );
|
|
|
|
|
|
2021-01-29 08:27:40 +08:00
|
|
|
|
// UnitDualQuaternion × DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b DualQuaternion<T>,
|
|
|
|
|
Output = DualQuaternion<T> => U1, U4;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self.dual_quaternion() * rhs;
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: DualQuaternion<T>,
|
|
|
|
|
Output = DualQuaternion<T> => U3, U3;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self.dual_quaternion() * rhs;
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b DualQuaternion<T>,
|
|
|
|
|
Output = DualQuaternion<T> => U3, U3;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self.dual_quaternion() * rhs;
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: DualQuaternion<T>,
|
|
|
|
|
Output = DualQuaternion<T> => U3, U3;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
self.dual_quaternion() * rhs;);
|
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
// UnitDualQuaternion × UnitQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U1, U4;
|
|
|
|
|
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner()));
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
|
|
|
|
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner()));
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
|
|
|
|
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner()));
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
|
|
|
|
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner())););
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
// UnitQuaternion × UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U1, U4;
|
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs;);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
2021-01-29 07:45:34 +08:00
|
|
|
|
// UnitDualQuaternion ÷ UnitQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U1, U4;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_rotation(rhs.inverse()) };
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_rotation(rhs.inverse()) };
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_rotation(rhs.inverse()) };
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_rotation(rhs.inverse()) };);
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
|
|
|
|
// UnitQuaternion ÷ UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U1, U4;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(
|
2021-01-29 07:45:34 +08:00
|
|
|
|
DualQuaternion::from_real(self.into_inner())
|
|
|
|
|
) * rhs.inverse()
|
|
|
|
|
}; 'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(
|
2021-01-29 07:45:34 +08:00
|
|
|
|
DualQuaternion::from_real(self.into_inner())
|
|
|
|
|
) * rhs.inverse()
|
|
|
|
|
}; 'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(
|
2021-01-29 07:45:34 +08:00
|
|
|
|
DualQuaternion::from_real(self.into_inner())
|
|
|
|
|
) * rhs.inverse()
|
|
|
|
|
}; 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U3;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
UnitDualQuaternion::<T>::new_unchecked(
|
2021-01-29 07:45:34 +08:00
|
|
|
|
DualQuaternion::from_real(self.into_inner())
|
|
|
|
|
) * rhs.inverse()
|
|
|
|
|
};);
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion × Translation3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
self * UnitDualQuaternion::<T>::from_parts(*rhs, UnitQuaternion::identity());
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self * UnitDualQuaternion::<T>::from_parts(rhs, UnitQuaternion::identity());
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
self * UnitDualQuaternion::<T>::from_parts(*rhs, UnitQuaternion::identity());
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self * UnitDualQuaternion::<T>::from_parts(rhs, UnitQuaternion::identity()); );
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ÷ Translation3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_parts(rhs.inverse(), UnitQuaternion::identity()) };
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_parts(rhs.inverse(), UnitQuaternion::identity()) };
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_parts(rhs.inverse(), UnitQuaternion::identity()) };
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Translation3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
{ self * UnitDualQuaternion::<T>::from_parts(rhs.inverse(), UnitQuaternion::identity()) };);
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
|
|
|
|
// Translation3 × UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) * rhs;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) * rhs;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation3<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_parts(self, UnitQuaternion::identity()) * rhs;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_parts(self, UnitQuaternion::identity()) * rhs;);
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
|
|
|
|
// Translation3 ÷ UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) / rhs;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) / rhs;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation3<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_parts(self, UnitQuaternion::identity()) / rhs;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Translation3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_parts(self, UnitQuaternion::identity()) / rhs;);
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
// UnitDualQuaternion × Isometry3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self * UnitDualQuaternion::<T>::from_isometry(rhs);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self * UnitDualQuaternion::<T>::from_isometry(&rhs);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self * UnitDualQuaternion::<T>::from_isometry(rhs);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self * UnitDualQuaternion::<T>::from_isometry(&rhs); );
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
2021-01-29 08:41:55 +08:00
|
|
|
|
// UnitDualQuaternion ÷ Isometry3
|
2021-01-29 06:25:32 +08:00
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
// TODO: can we avoid the conversion to a rotation matrix?
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self / UnitDualQuaternion::<T>::from_isometry(rhs);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self / UnitDualQuaternion::<T>::from_isometry(&rhs);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self / UnitDualQuaternion::<T>::from_isometry(rhs);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U4, U1), (U3, U3);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Isometry3<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
self / UnitDualQuaternion::<T>::from_isometry(&rhs); );
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
// Isometry × UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a Isometry3<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(self) * rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a Isometry3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(self) * rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry3<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(&self) * rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(&self) * rhs; );
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
// Isometry ÷ UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a Isometry3<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
2021-02-25 21:45:26 +08:00
|
|
|
|
// TODO: can we avoid the conversion from a rotation matrix?
|
2021-04-11 17:00:38 +08:00
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(self) / rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a Isometry3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(self) / rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry3<T>, rhs: &'b UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(&self) / rhs;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Div, div;
|
|
|
|
|
(U3, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Isometry3<T>, rhs: UnitDualQuaternion<T>,
|
|
|
|
|
Output = UnitDualQuaternion<T> => U3, U1;
|
|
|
|
|
UnitDualQuaternion::<T>::from_isometry(&self) / rhs; );
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion × Vector
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Vector<T, U3, SB>,
|
|
|
|
|
Output = Vector3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
Unit::new_unchecked(self.as_ref().real) * rhs;
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Vector<T, U3, SB>,
|
|
|
|
|
Output = Vector3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
self * &rhs;
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Vector<T, U3, SB>,
|
|
|
|
|
Output = Vector3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * rhs;
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Vector<T, U3, SB>,
|
|
|
|
|
Output = Vector3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * &rhs; );
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion × Point
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Point3<T>,
|
|
|
|
|
Output = Point3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
let two: T = crate::convert(2.0f64);
|
2021-06-18 15:45:37 +08:00
|
|
|
|
let q_point = Quaternion::from_parts(T::zero(), rhs.coords);
|
2021-01-29 06:25:32 +08:00
|
|
|
|
Point::from(
|
|
|
|
|
((self.as_ref().real * q_point + self.as_ref().dual * two) * self.as_ref().real.conjugate())
|
|
|
|
|
.vector()
|
|
|
|
|
.into_owned(),
|
|
|
|
|
)
|
|
|
|
|
};
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Point3<T>,
|
|
|
|
|
Output = Point3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
self * &rhs;
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Point3<T>,
|
|
|
|
|
Output = Point3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * rhs;
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Point3<T>,
|
|
|
|
|
Output = Point3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
&self * &rhs; );
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion × Unit<Vector>
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: &'b Unit<Vector<T, U3, SB>>,
|
|
|
|
|
Output = Unit<Vector3<T>> => U3, U4;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
Unit::new_unchecked(self * rhs.as_ref());
|
|
|
|
|
'a, 'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: &'a UnitDualQuaternion<T>, rhs: Unit<Vector<T, U3, SB>>,
|
|
|
|
|
Output = Unit<Vector3<T>> => U3, U4;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
Unit::new_unchecked(self * rhs.into_inner());
|
|
|
|
|
'a);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Unit<Vector<T, U3, SB>>,
|
|
|
|
|
Output = Unit<Vector3<T>> => U3, U4;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
Unit::new_unchecked(self * rhs.as_ref());
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
Mul, mul;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
(U4, U1), (U3, U1) for SB: Storage<T, U3> ;
|
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Unit<Vector<T, U3, SB>>,
|
|
|
|
|
Output = Unit<Vector3<T>> => U3, U4;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
Unit::new_unchecked(self * rhs.into_inner()); );
|
|
|
|
|
|
|
|
|
|
macro_rules! left_scalar_mul_impl(
|
|
|
|
|
($($T: ty),* $(,)*) => {$(
|
|
|
|
|
impl Mul<DualQuaternion<$T>> for $T {
|
|
|
|
|
type Output = DualQuaternion<$T>;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn mul(self, right: DualQuaternion<$T>) -> Self::Output {
|
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self * right.real,
|
|
|
|
|
self * right.dual
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'b> Mul<&'b DualQuaternion<$T>> for $T {
|
|
|
|
|
type Output = DualQuaternion<$T>;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn mul(self, right: &'b DualQuaternion<$T>) -> Self::Output {
|
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self * &right.real,
|
|
|
|
|
self * &right.dual
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)*}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
left_scalar_mul_impl!(f32, f64);
|
|
|
|
|
|
|
|
|
|
macro_rules! dual_quaternion_op_impl(
|
|
|
|
|
($OpAssign: ident, $op_assign: ident;
|
|
|
|
|
($LhsRDim: ident, $LhsCDim: ident), ($RhsRDim: ident, $RhsCDim: ident);
|
|
|
|
|
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty $(=> $VDimA: ty, $VDimB: ty)*;
|
|
|
|
|
$action: expr; $($lives: tt),*) => {
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<$($lives ,)* T: SimdRealField> $OpAssign<$Rhs> for $Lhs
|
2021-04-12 16:32:17 +08:00
|
|
|
|
where T::Element: SimdRealField {
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn $op_assign(&mut $lhs, $rhs: $Rhs) {
|
|
|
|
|
$action
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// DualQuaternion += DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
AddAssign, add_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
self.real += &rhs.real;
|
|
|
|
|
self.dual += &rhs.dual;
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
AddAssign, add_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
self.real += rhs.real;
|
|
|
|
|
self.dual += rhs.dual;
|
|
|
|
|
};);
|
|
|
|
|
|
|
|
|
|
// DualQuaternion -= DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
SubAssign, sub_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
self.real -= &rhs.real;
|
|
|
|
|
self.dual -= &rhs.dual;
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
SubAssign, sub_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
self.real -= rhs.real;
|
|
|
|
|
self.dual -= rhs.dual;
|
|
|
|
|
};);
|
|
|
|
|
|
|
|
|
|
// DualQuaternion ×= DualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * rhs;
|
|
|
|
|
self.real.coords.copy_from(&res.real.coords);
|
|
|
|
|
self.dual.coords.copy_from(&res.dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: DualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
*self *= &rhs;);
|
|
|
|
|
|
|
|
|
|
// DualQuaternion ×= UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * rhs;
|
|
|
|
|
self.real.coords.copy_from(&res.real.coords);
|
|
|
|
|
self.dual.coords.copy_from(&res.dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
*self *= &rhs; );
|
|
|
|
|
|
2021-01-29 08:27:40 +08:00
|
|
|
|
// DualQuaternion ÷= UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self / rhs;
|
|
|
|
|
self.real.coords.copy_from(&res.real.coords);
|
|
|
|
|
self.dual.coords.copy_from(&res.dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: DualQuaternion<T>, rhs: UnitDualQuaternion<T>;
|
2021-01-29 08:27:40 +08:00
|
|
|
|
*self /= &rhs; );
|
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
// UnitDualQuaternion ×= UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * rhs;
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
*self *= &rhs; );
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ÷= UnitDualQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self / rhs;
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitDualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
*self /= &rhs; );
|
|
|
|
|
|
2021-01-29 07:45:34 +08:00
|
|
|
|
// UnitDualQuaternion ×= UnitQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitQuaternion<T>;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * UnitDualQuaternion::from_rotation(rhs);
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
*self *= *rhs; 'b);
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ÷= UnitQuaternion
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>;
|
2021-01-29 07:50:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_op_assign_impl)]
|
2021-01-29 07:45:34 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * UnitDualQuaternion::from_rotation(rhs.inverse());
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: UnitQuaternion<T>;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
*self /= &rhs; );
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ×= Translation3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Translation3<T>;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * UnitDualQuaternion::from_parts(rhs, UnitQuaternion::identity());
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>;
|
2021-06-18 15:45:37 +08:00
|
|
|
|
*self *= *rhs; 'b);
|
2021-01-29 07:45:34 +08:00
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ÷= Translation3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>;
|
2021-01-29 07:50:34 +08:00
|
|
|
|
#[allow(clippy::suspicious_op_assign_impl)]
|
2021-01-29 07:45:34 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * UnitDualQuaternion::from_parts(rhs.inverse(), UnitQuaternion::identity());
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U4, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Translation3<T>;
|
2021-01-29 07:45:34 +08:00
|
|
|
|
*self /= &rhs; );
|
|
|
|
|
|
2021-01-29 06:25:32 +08:00
|
|
|
|
// UnitDualQuaternion ×= Isometry3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Isometry3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self * rhs;
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
MulAssign, mul_assign;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Isometry3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
*self *= &rhs; );
|
|
|
|
|
|
|
|
|
|
// UnitDualQuaternion ÷= Isometry3
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: &'b Isometry3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
{
|
|
|
|
|
let res = &*self / rhs;
|
|
|
|
|
self.as_mut_unchecked().real.coords.copy_from(&res.as_ref().real.coords);
|
|
|
|
|
self.as_mut_unchecked().dual.coords.copy_from(&res.as_ref().dual.coords);
|
|
|
|
|
};
|
|
|
|
|
'b);
|
|
|
|
|
|
|
|
|
|
dual_quaternion_op_impl!(
|
|
|
|
|
DivAssign, div_assign;
|
|
|
|
|
(U4, U1), (U3, U1);
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: UnitDualQuaternion<T>, rhs: Isometry3<T> => U3, U1;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
*self /= &rhs; );
|
|
|
|
|
|
|
|
|
|
macro_rules! scalar_op_impl(
|
|
|
|
|
($($Op: ident, $op: ident, $OpAssign: ident, $op_assign: ident);* $(;)*) => {$(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<T: SimdRealField> $Op<T> for DualQuaternion<T>
|
|
|
|
|
where T::Element: SimdRealField {
|
|
|
|
|
type Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $op(self, n: T) -> Self::Output {
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self.real.$op(n),
|
|
|
|
|
self.dual.$op(n)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<'a, T: SimdRealField> $Op<T> for &'a DualQuaternion<T>
|
|
|
|
|
where T::Element: SimdRealField {
|
|
|
|
|
type Output = DualQuaternion<T>;
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $op(self, n: T) -> Self::Output {
|
2021-01-29 06:25:32 +08:00
|
|
|
|
DualQuaternion::from_real_and_dual(
|
|
|
|
|
self.real.$op(n),
|
|
|
|
|
self.dual.$op(n)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<T: SimdRealField> $OpAssign<T> for DualQuaternion<T>
|
|
|
|
|
where T::Element: SimdRealField {
|
2021-01-29 06:25:32 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $op_assign(&mut self, n: T) {
|
2021-01-29 06:25:32 +08:00
|
|
|
|
self.real.$op_assign(n);
|
|
|
|
|
self.dual.$op_assign(n);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)*}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
scalar_op_impl!(
|
|
|
|
|
Mul, mul, MulAssign, mul_assign;
|
|
|
|
|
Div, div, DivAssign, div_assign;
|
|
|
|
|
);
|