Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cQuaternion.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_cQuaternion_H
7 #define _INC_cQuaternion_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 
12 #include "cVector.h"
14 
15 namespace GrayLib
16 {
17  UNITTEST2_PREDEF(cQuaternion);
18  class cMatrix4x4f;
19 
20  template<typename TYPE = DVALUEDEF_t>
21  class GRAYLIB_LINK cQuaternionT : public cVecT4<TYPE>
22  {
25  public:
26  // typedef TYPE DVALUE_t;
28 
29  cQuaternionT() noexcept
30  {}
31  cQuaternionT(TYPE _x, TYPE _y, TYPE _z, TYPE _w) noexcept
32  : SUPER_t(_x, _y, _z, _w)
33  {
34  }
35  cQuaternionT(const SUPER_t& q) noexcept
36  : SUPER_t(q)
37  {
38  }
39 
40  bool isIdentity() const noexcept
41  {
43  if (this->x == 0 && this->y == 0 && this->z == 0 && this->w == 1)
44  return true;
45  return false;
46  }
47 
48  bool IsNearQ(const SUPER_t& q, TYPE fDist = k_FLT_MIN2) const
49  {
51  ASSERT(fDist >= 0);
52  if (!CalcI::IsNear(CalcI::Abs(this->x), CalcI::Abs(q.x), fDist))
53  return false;
54  if (!CalcI::IsNear(CalcI::Abs(this->y), CalcI::Abs(q.y), fDist))
55  return false;
56  if (!CalcI::IsNear(CalcI::Abs(this->z), CalcI::Abs(q.z), fDist))
57  return false;
58  if (!CalcI::IsNear(CalcI::Abs(this->w), CalcI::Abs(q.w), fDist))
59  return false;
60  return true;
61  }
62 
63  private:
64  void SetZero()
65  {
67  }
68  bool isZero() const
69  {
71  return false;
72  }
73  };
74 
75  class GRAYLIB_LINK cQuaternionf : public cQuaternionT<float>
76  {
82 
83  public:
86  static const cQuaternionf k_Identity;
87 
88  public:
89  cQuaternionf() noexcept
90  {}
92  : SUPER_t(_x, _y, _z, _w)
93  {
94  }
96  : SUPER_t(q)
97  {
98  }
100  {
101  InitRotationMatrix(rm);
102  }
103  cQuaternionf(const cVector3f& vAxis, RADIANf_t fAngle)
104  {
106  InitRotationAxis(vAxis, fAngle);
107  }
108 
109 #if defined(USE_DXM) || defined(USE_DX) // ASSUME DVALUE_t = float !!!
110  // Cast directly to the DirectX equivalent type. D3DXQUATERNION, FXMVECTOR
111  cQuaternionf(const XMFLOAT4& v)
112  : SUPER_t(*(const SUPER_t*)&v)
113  {}
114  inline operator XMFLOAT4* ()
115  {
116  return (XMFLOAT4*)this;
117  }
118  inline operator const XMFLOAT4* () const
119  {
120  return (const XMFLOAT4*)this;
121  }
122 #endif
123 
124 #ifdef USE_DXM
125  inline void Set(const XMVECTOR& v)
126  {
127  ::XMStoreFloat4((XMFLOAT4*)this, v);
128  }
129  inline operator XMVECTOR () const
130  {
131  return ::XMLoadFloat4((const XMFLOAT4*)this);
132  }
133 #endif
134 
135  THIS_t GetMulQ(const THIS_t& q) const
136  {
138  THIS_t qRet;
139  qRet.InitMulQ(*this, q);
140  return qRet;
141  }
142  THIS_t operator*(const THIS_t& q) const
143  {
144  return GetMulQ(q);
145  }
146 
147  RADIANf_t get_EulerY() const;
148  cVector3f get_EulerV() const;
149 
150  // setters.
151 
153  {
155  *this = k_Identity;
156  }
157  void InitSlerp(const THIS_t& q1, const THIS_t& q2, DVALUE_t t)
158  {
161  ASSERT(this != &q1);
162  ASSERT(this != &q2);
163 #ifdef USE_DXM
164  Set(::XMQuaternionSlerp((XMVECTOR)q1, (XMVECTOR)q2, t));
165 #else
166  DVALUE_t t2 = (1.0f - t);
167  DVALUE_t epsilon = 1.0f;
168  DVALUE_t dot = q1.GetDot(q2);
169  if (dot < 0.0f)
170  epsilon = -1.0f;
171  t *= epsilon;
172  this->x = t2 * q1.x + t * q2.x;
173  this->y = t2 * q1.y + t * q2.y;
174  this->z = t2 * q1.z + t * q2.z;
175  this->w = t2 * q1.w + t * q2.w;
176 #endif
177  }
178  void InitRotationAxis(const cVector3f& vNorm, RADIANf_t fAngle)
179  {
183 #ifdef USE_DXM
184  Set(::XMQuaternionRotationAxis((XMVECTOR)vNorm, fAngle));
185 #else
186  float s, c;
187  Calc::SinCos(fAngle / 2.0f, s, c);
188  this->x = s * vNorm.x;
189  this->y = s * vNorm.y;
190  this->z = s * vNorm.z;
191  this->w = c;
192 #endif
193  }
194  void InitAngle(const cVector3f& v, RADIANf_t fAngle)
195  {
199  InitRotationAxis(v.get_Normalized(), fAngle);
200  }
201 
202  void InitMulQ(const THIS_t& q1, const THIS_t& q2)
203  {
205  ASSERT(this != &q1);
206  ASSERT(this != &q2);
207 #ifdef USE_DXM
208  Set(::XMQuaternionMultiply((XMVECTOR)q1, (XMVECTOR)q2));
209 #else
210  this->x = q2.w * q1.x + q2.x * q1.w + q2.y * q1.z - q2.z * q1.y;
211  this->y = q2.w * q1.y - q2.x * q1.z + q2.y * q1.w + q2.z * q1.x;
212  this->z = q2.w * q1.z + q2.x * q1.y - q2.y * q1.x + q2.z * q1.w;
213  this->w = q2.w * q1.w - q2.x * q1.x - q2.y * q1.y - q2.z * q1.z;
214 #endif
215  }
216 
217  void InitRotationMatrix(const cMatrix4x4f& rm);
218  void InitEulerV(const cVector3f& v); // y=yaw=heading,x=pitch,z=roll=bank radians
219 
220  void AlignToNormal( /* const*/ cVector3f& vNorm);
221  void SetToAngleBetween(const cVector3f& v1, const cVector3f& v2);
222  void SetEulerY(RADIANf_t fAngleY, bool bMoveNormalized);
223 
224  UNITTEST_FRIEND(cQuaternion);
225  };
226 
227 
228 #ifdef GRAY_DLL // force implementation/instantiate for DLL/SO.
229  template class GRAYLIB_LINK cQuaternionT<float>;
230  template class GRAYLIB_LINK cQuaternionT<double>;
231 #endif
232 
233 }
234 #endif // _INC_cQuaternion_H
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
#define TYPE
Definition: StrT.cpp:38
#define ASSERT(exp)
Definition: cDebugAssert.h:87
Definition: cMatrix.h:194
Definition: cQuaternion.h:22
cVecT4< TYPE > SUPER_t
Definition: cQuaternion.h:27
cQuaternionT() noexcept
Definition: cQuaternion.h:29
bool isIdentity() const noexcept
Definition: cQuaternion.h:40
cQuaternionT(TYPE _x, TYPE _y, TYPE _z, TYPE _w) noexcept
Definition: cQuaternion.h:31
bool IsNearQ(const SUPER_t &q, TYPE fDist=k_FLT_MIN2) const
Definition: cQuaternion.h:48
cQuaternionT(const SUPER_t &q) noexcept
Definition: cQuaternion.h:35
Definition: cQuaternion.h:76
void InitRotationAxis(const cVector3f &vNorm, RADIANf_t fAngle)
Definition: cQuaternion.h:178
cQuaternionf() noexcept
Definition: cQuaternion.h:89
void InitSlerp(const THIS_t &q1, const THIS_t &q2, DVALUE_t t)
Definition: cQuaternion.h:157
cQuaternionf(DVALUE_t _x, DVALUE_t _y, DVALUE_t _z, DVALUE_t _w)
Definition: cQuaternion.h:91
cQuaternionf THIS_t
Definition: cQuaternion.h:85
cQuaternionf(const SUPER_t &q)
Definition: cQuaternion.h:95
cQuaternionf(const cVector3f &vAxis, RADIANf_t fAngle)
Definition: cQuaternion.h:103
THIS_t operator*(const THIS_t &q) const
Definition: cQuaternion.h:142
void InitAngle(const cVector3f &v, RADIANf_t fAngle)
Definition: cQuaternion.h:194
void InitIdentity()
Definition: cQuaternion.h:152
cQuaternionf(const cMatrix4x4f &rm)
Definition: cQuaternion.h:99
UNITTEST_FRIEND(cQuaternion)
cQuaternionT< float > SUPER_t
Definition: cQuaternion.h:84
void InitMulQ(const THIS_t &q1, const THIS_t &q2)
Definition: cQuaternion.h:202
THIS_t GetMulQ(const THIS_t &q) const
Definition: cQuaternion.h:135
static const cQuaternionf k_Identity
Definition: cQuaternion.h:86
TYPE y
Definition: cVecT.h:545
TYPE z
Definition: cVecT.h:545
TYPE x
Definition: cVecT.h:545
Definition: cVecT.h:663
TYPE z
Definition: cVecT.h:676
TYPE x
Definition: cVecT.h:676
TYPE w
Definition: cVecT.h:676
TYPE y
Definition: cVecT.h:676
float DVALUE_t
Dimension value type.
Definition: cVecT.h:48
_TYPE_C get_Normalized() const
Definition: cVecT.h:283
TYPE GetDot(const THIS_t &v2) const
Definition: cVecT.h:255
Definition: cVector.h:94
Definition: cMesh.h:22
UNITTEST2_PREDEF(cQuadtree)
float RADIANf_t
type is float radians
Definition: Calc.h:27
static TYPE Abs(TYPE a) noexcept
similar to ABS(n) macro. Does nothing for unsigned types.
static bool IsNear(TYPE n1, TYPE n2, TYPE nDiff=(TYPE) k_FLT_MIN2) noexcept
Definition: Calc.h:135
static void SinCos(TYPE a, TYPE &s, TYPE &c)
get both sin and cos at one time. a = Euler angle in radians
Definition: MathDX.h:106