Radium Engine  1.5.20
Loading...
Searching...
No Matches
DualQuaternion.hpp
1#pragma once
2
3#include <Core/Math/LinearAlgebra.hpp> // Quaternion operators
4#include <Core/RaCore.hpp>
5#include <Core/Types.hpp>
6
7namespace Ra {
8namespace Core {
14
17
19{
20
21 public:
23 inline DualQuaternion() {}
24
26 inline DualQuaternion( const Quaternion& q0, const Quaternion& qe ) : m_q0( q0 ), m_qe( qe ) {}
27
30 explicit inline DualQuaternion( const Core::Transform& tr );
31
33 DualQuaternion( const DualQuaternion& other ) = default;
34 DualQuaternion& operator=( const DualQuaternion& ) = default;
35
37
38 inline const Quaternion& getQ0() const;
39 inline void setQ0( const Quaternion& q0 );
40 inline const Quaternion& getQe() const;
41 inline void setQe( const Quaternion& qe );
42
44
45 inline DualQuaternion operator+( const DualQuaternion& other ) const;
46 inline DualQuaternion operator*( Scalar scalar ) const;
47
48 inline DualQuaternion& operator+=( const DualQuaternion& other );
49 inline DualQuaternion& operator*=( Scalar scalar );
50
52
55 inline void setFromTransform( const Transform& t );
56
58 inline Transform getTransform() const;
59
62 inline void normalize();
63
66 inline Vector3 transform( const Vector3& p ) const;
67
69 inline Vector3 rotate( const Vector3& p ) const;
70
72 inline Vector3 translate( const Vector3& p ) const;
73
74 private:
76 Quaternion m_q0;
78 Quaternion m_qe;
79};
80
82inline DualQuaternion operator*( Scalar scalar, const DualQuaternion& dq );
83
84inline const Quaternion& DualQuaternion::getQ0() const {
85 return m_q0;
86}
87
88inline void DualQuaternion::setQ0( const Quaternion& q0 ) {
89 m_q0 = q0;
90}
91
92inline const Quaternion& DualQuaternion::getQe() const {
93 return m_qe;
94}
95
96inline void DualQuaternion::setQe( const Quaternion& qe ) {
97 m_qe = qe;
98}
99
101 return DualQuaternion( m_q0 + other.m_q0, m_qe + other.m_qe );
102}
103
104inline DualQuaternion DualQuaternion::operator*( Scalar scalar ) const {
105 return DualQuaternion( scalar * m_q0, scalar * m_qe );
106}
107
108inline DualQuaternion& DualQuaternion::operator+=( const DualQuaternion& other ) {
109 *this = *this + other;
110 return *this;
111}
112
113inline DualQuaternion& DualQuaternion::operator*=( Scalar scalar ) {
114 *this = *this * scalar;
115 return *this;
116}
117
119 const Scalar norm = m_q0.norm();
120 CORE_ASSERT( norm != 0, "Normalizing a null quaternion." );
121 m_q0 = m_q0 / norm;
122 m_qe = m_qe / norm;
123}
124
125inline Vector3 DualQuaternion::transform( const Vector3& p ) const {
126 CORE_ASSERT( Ra::Core::Math::areApproxEqual( m_q0.norm(), 1_ra ),
127 "Dual quaternion not normalized" );
128 return translate( rotate( p ) );
129}
130
131inline Vector3 DualQuaternion::rotate( const Vector3& p ) const {
132 CORE_ASSERT( Ra::Core::Math::areApproxEqual( m_q0.norm(), 1_ra ),
133 "Dual quaternion not normalized" );
134 return m_q0.toRotationMatrix() * p;
135}
136
137inline Vector3 DualQuaternion::translate( const Vector3& p ) const {
138 Vector3 v0 = m_q0.vec();
139 Vector3 ve = m_qe.vec();
140 return p + ( ( ve * m_q0.w() - v0 * m_qe.w() + v0.cross( ve ) ) * 2_ra );
141}
142
143inline DualQuaternion::DualQuaternion( const Core::Transform& tr ) {
144 setFromTransform( tr );
145}
146
147inline Transform DualQuaternion::getTransform() const {
148 // Assume the dual quat is normalized.
149 CORE_ASSERT( Ra::Core::Math::areApproxEqual( m_q0.norm(), 1_ra ),
150 "Dual quaternion not normalized" );
151
152 Transform result;
153 result.linear() = m_q0.toRotationMatrix();
154 result.translation() = ( 2_ra * m_q0 * m_qe.conjugate() ).vec();
155 return result;
156}
157
158inline void DualQuaternion::setFromTransform( const Transform& t ) {
159 m_q0 = Quaternion( t.rotation() );
160 Core::Vector4 trans = Core::Vector4::Zero();
161 trans.head<3>() = t.translation();
162 m_qe = 0.5f * Quaternion( trans ) * m_q0;
163}
164
165inline DualQuaternion operator*( Scalar scalar, const DualQuaternion& dq ) {
166 return dq * scalar;
167}
168
169} // namespace Core
170} // namespace Ra
void setFromTransform(const Transform &t)
Other methods.
Vector3 transform(const Vector3 &p) const
DualQuaternion(const DualQuaternion &other)=default
Default copy constructor and assignment operator.
Transform getTransform() const
Return the corresponding rigid transform. Assume a unit dual quaternion.
DualQuaternion operator+(const DualQuaternion &other) const
Operators.
DualQuaternion()
Construct an uninitialized dual quaternion.
Vector3 translate(const Vector3 &p) const
Apply only the translational part of the dual quaternion to the given vector.
const Quaternion & getQ0() const
Getters and setters.
Vector3 rotate(const Vector3 &p) const
Apply only the rotational part of the dual quaternion to the given vector.
DualQuaternion(const Quaternion &q0, const Quaternion &qe)
Construct a dual-quaternion from two quaternions.
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type areApproxEqual(T x, T y, T espilonBoostFactor=T(10))
Compare two numbers such that |x-y| < espilon*epsilonBoostFactor.
Definition Math.hpp:42
DualQuaternion operator*(Scalar scalar, const DualQuaternion &dq)
Pre-multiplication of dual quaternion.
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3