TrueReality  v0.1.1912
Quat.cpp
Go to the documentation of this file.
1 /*
2 * True Reality Open Source Game and Simulation Engine
3 * Copyright © 2021 Acid Rain Studios LLC
4 *
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 3.0 of the License, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * @author Maxim Serebrennik
20 */
21 #include <trBase/Quat.h>
22 
23 #include <trBase/Matrixf.h>
24 #include <trBase/Matrixd.h>
25 
26 namespace trBase
27 {
30  :mQuat()
31  {}
32 
34  Quat::Quat(const Quat& q)
35  :mQuat(q.X(), q.Y(), q.Z(), q.W())
36  {
37  }
38 
40  Quat::Quat(const osg::Quat& q)
41  :mQuat(q.x(), q.y(), q.z(), q.w())
42  {
43  }
44 
47  :mQuat(x, y, z, w)
48  {
49  }
50 
52  Quat::Quat(const Vec4f& v)
53  :mQuat(v)
54  {
55  }
56 
58  Quat::Quat(const Vec4d& v)
59  :mQuat(v)
60  {
61  }
62 
64  Quat::Quat(value_type angle, const Vec3f& axis)
65  :mQuat(angle, axis)
66  {
67  }
68 
70  Quat::Quat(value_type angle, const Vec3d& axis)
71  :mQuat(angle, axis)
72  {
73  }
74 
76  Quat::Quat(value_type angle1, const Vec3f& axis1, value_type angle2, const Vec3f& axis2, value_type angle3, const Vec3f& axis3)
77  :mQuat(angle1, axis1, angle2, axis2, angle3, axis3)
78  {
79  }
80 
82  Quat::Quat(value_type angle1, const Vec3d& axis1, value_type angle2, const Vec3d& axis2, value_type angle3, const Vec3d& axis3)
83  :mQuat(angle1, axis1, angle2, axis2, angle3, axis3)
84  {
85  }
86 
88  osg::Quat& Quat::GetOSGQuat()
89  {
90  return mQuat;
91  }
92 
94  const osg::Quat& Quat::GetOSGQuat() const
95  {
96  return mQuat;
97  }
98 
101  {
102  return Vec4d(mQuat._v[0], mQuat._v[1], mQuat._v[2], mQuat._v[3]);
103  }
104 
107  {
108  return Vec3d(mQuat._v[0], mQuat._v[1], mQuat._v[2]);
109  }
110 
112  void Quat::Set(const Quat& q)
113  {
114  mQuat._v[0] = q.X();
115  mQuat._v[1] = q.Y();
116  mQuat._v[2] = q.Z();
117  mQuat._v[3] = q.W();
118  }
119 
121  void Quat::Set(const osg::Quat& q)
122  {
123  mQuat._v[0] = q.x();
124  mQuat._v[1] = q.y();
125  mQuat._v[2] = q.z();
126  mQuat._v[3] = q.w();
127  }
128 
131  {
132  mQuat._v[0] = x;
133  mQuat._v[1] = y;
134  mQuat._v[2] = z;
135  mQuat._v[3] = w;
136  }
137 
139  void Quat::Set(const Vec4f& v)
140  {
141  mQuat._v[0] = v.X();
142  mQuat._v[1] = v.Y();
143  mQuat._v[2] = v.Z();
144  mQuat._v[3] = v.W();
145  }
146 
148  void Quat::Set(const Vec4d& v)
149  {
150  mQuat._v[0] = v.X();
151  mQuat._v[1] = v.Y();
152  mQuat._v[2] = v.Z();
153  mQuat._v[3] = v.W();
154  }
155 
157  void Quat::Set(const Matrixf& matrix)
158  {
159  mQuat.set(matrix);
160  }
161 
163  void Quat::Set(const Matrixd& matrix)
164  {
165  mQuat.set(matrix);
166  }
167 
169  void Quat::Get(Matrixf& matrix) const
170  {
171  mQuat.get(matrix);
172  }
173 
175  void Quat::Get(Matrixd& matrix) const
176  {
177  mQuat.get(matrix);
178  }
179 
181  void Quat::Set(const osg::Matrixf& matrix)
182  {
183  mQuat.set(matrix);
184  }
185 
187  void Quat::Set(const osg::Matrixd& matrix)
188  {
189  mQuat.set(matrix);
190  }
191 
193  void Quat::Get(osg::Matrixf& matrix) const
194  {
195  mQuat.get(matrix);
196  }
197 
199  void Quat::Get(osg::Matrixd& matrix) const
200  {
201  mQuat.get(matrix);
202  }
203 
205  bool Quat::IsZeroRotation() const
206  {
207  return mQuat._v[0] == 0.0 && mQuat._v[1] == 0.0 && mQuat._v[2] == 0.0 && mQuat._v[3] == 1.0;
208  }
209 
212  {
213  return sqrt(mQuat._v[0] * mQuat._v[0] + mQuat._v[1] * mQuat._v[1] + mQuat._v[2] * mQuat._v[2] + mQuat._v[3] * mQuat._v[3]);
214  }
215 
218  {
219  return mQuat._v[0] * mQuat._v[0] + mQuat._v[1] * mQuat._v[1] + mQuat._v[2] * mQuat._v[2] + mQuat._v[3] * mQuat._v[3];
220  }
221 
224  {
225  return Quat(-mQuat._v[0], -mQuat._v[1], -mQuat._v[2], mQuat._v[3]);
226  }
227 
230  {
231  return Conj() / Length2();
232  }
233 
236  {
237  mQuat.makeRotate(angle, x, y, z);
238  }
239 
241  void Quat::MakeRotate(value_type angle, const Vec3f& vec)
242  {
243  mQuat.makeRotate(angle, vec);
244  }
245 
247  void Quat::MakeRotate(value_type angle, const Vec3d& vec)
248  {
249  mQuat.makeRotate(angle, vec);
250  }
251 
253  void Quat::MakeRotate(value_type angle1, const Vec3f& axis1, value_type angle2, const Vec3f& axis2, value_type angle3, const Vec3f& axis3)
254  {
255  mQuat.makeRotate(angle1, axis1, angle2, axis2, angle3, axis3);
256  }
257 
259  void Quat::MakeRotate(value_type angle1, const Vec3d& axis1, value_type angle2, const Vec3d& axis2, value_type angle3, const Vec3d& axis3)
260  {
261  mQuat.makeRotate(angle1, axis1, angle2, axis2, angle3, axis3);
262  }
263 
265  void Quat::MakeRotate(const Vec3f& vec1, const Vec3f& vec2)
266  {
267  mQuat.makeRotate(vec1, vec2);
268  }
269 
271  void Quat::MakeRotate(const Vec3d& vec1, const Vec3d& vec2)
272  {
273  mQuat.makeRotate(vec1, vec2);
274  }
275 
278  {
279  mQuat.getRotate(angle, x, y, z);
280  }
281 
283  void Quat::GetRotate(value_type& angle, Vec3f& vec) const
284  {
285  mQuat.getRotate(angle, vec);
286  }
287 
289  void Quat::GetRotate(value_type& angle, Vec3d& vec) const
290  {
291  mQuat.getRotate(angle, vec);
292  }
293 
295  void Quat::Clear()
296  {
297  mQuat.set(0.0, 0.0, 0.0, 1.0);
298  }
299 
301  void Quat::Slerp(value_type t, const Quat& from, const Quat& to)
302  {
303  mQuat.slerp(t, from, to);
304  }
305 
308  {
309  return mQuat._v[0];
310  }
311 
314  {
315  return mQuat._v[1];
316  }
317 
320  {
321  return mQuat._v[2];
322  }
323 
326  {
327  return mQuat._v[3];
328  }
329 
332  {
333  return mQuat._v[0];
334  }
335 
338  {
339  return mQuat._v[1];
340  }
341 
344  {
345  return mQuat._v[2];
346  }
347 
350  {
351  return mQuat._v[3];
352  }
353 
356  {
357  return mQuat._v[i];
358  }
359 
362  {
363  return mQuat._v[i];
364  }
365 
368  {
369  mQuat._v[0] = v[0]; mQuat._v[1] = v[1]; mQuat._v[2] = v[2]; mQuat._v[3] = v[3];
370  return *this;
371  }
372 
374  bool Quat::operator == (const Quat& v) const
375  {
376  return mQuat._v[0] == v[0] && mQuat._v[1] == v[1] && mQuat._v[2] == v[2] && mQuat._v[3] == v[3];
377  }
378 
380  bool Quat::operator != (const Quat& v) const
381  {
382  return mQuat._v[0] != v[0] || mQuat._v[1] != v[1] || mQuat._v[2] != v[2] || mQuat._v[3] != v[3];
383  }
384 
386  bool Quat::operator < (const Quat& v) const
387  {
388  if (mQuat._v[0]<v[0]) return true;
389  else if (mQuat._v[0]>v[0]) return false;
390  else if (mQuat._v[1]<v[1]) return true;
391  else if (mQuat._v[1]>v[1]) return false;
392  else if (mQuat._v[2]<v[2]) return true;
393  else if (mQuat._v[2]>v[2]) return false;
394  else return (mQuat._v[3]<v[3]);
395  }
396 
398  bool Quat::operator > (const Quat& v) const
399  {
400  if (mQuat._v[0]>v[0]) return true;
401  else if (mQuat._v[0]<v[0]) return false;
402  else if (mQuat._v[1]>v[1]) return true;
403  else if (mQuat._v[1]<v[1]) return false;
404  else if (mQuat._v[2]>v[2]) return true;
405  else if (mQuat._v[2]<v[2]) return false;
406  else return (mQuat._v[3]>v[3]);
407  }
408 
411  {
412  return Quat(mQuat._v[0] * rhs, mQuat._v[1] * rhs, mQuat._v[2] * rhs, mQuat._v[3] * rhs);
413  }
414 
416  Vec3f Quat::operator* (const Vec3f& v) const
417  {
418  // nVidia SDK implementation
419  Vec3f uv, uuv;
420  Vec3f qvec(mQuat._v[0], mQuat._v[1], mQuat._v[2]);
421  uv = qvec ^ v;
422  uuv = qvec ^ uv;
423  uv *= (2.0f * mQuat._v[3]);
424  uuv *= 2.0f;
425  return v + uv + uuv;
426  }
427 
429  Vec3d Quat::operator* (const Vec3d& v) const
430  {
431  // nVidia SDK implementation
432  Vec3d uv, uuv;
433  Vec3d qvec(mQuat._v[0], mQuat._v[1], mQuat._v[2]);
434  uv = qvec ^ v;
435  uuv = qvec ^ uv;
436  uv *= (2.0f * mQuat._v[3]);
437  uuv *= 2.0f;
438  return v + uv + uuv;
439  }
440 
443  {
444  mQuat._v[0] *= rhs;
445  mQuat._v[1] *= rhs;
446  mQuat._v[2] *= rhs;
447  mQuat._v[3] *= rhs;
448  return *this; // enable nesting
449  }
450 
452  const Quat Quat::operator*(const Quat& rhs) const
453  {
454  return Quat(rhs[3] * mQuat._v[0] + rhs[0] * mQuat._v[3] + rhs[1] * mQuat._v[2] - rhs[2] * mQuat._v[1],
455  rhs[3] * mQuat._v[1] - rhs[0] * mQuat._v[2] + rhs[1] * mQuat._v[3] + rhs[2] * mQuat._v[0],
456  rhs[3] * mQuat._v[2] + rhs[0] * mQuat._v[1] - rhs[1] * mQuat._v[0] + rhs[2] * mQuat._v[3],
457  rhs[3] * mQuat._v[3] - rhs[0] * mQuat._v[0] - rhs[1] * mQuat._v[1] - rhs[2] * mQuat._v[2]);
458  }
459 
462  {
463  value_type x = rhs[3] * mQuat._v[0] + rhs[0] * mQuat._v[3] + rhs[1] * mQuat._v[2] - rhs[2] * mQuat._v[1];
464  value_type y = rhs[3] * mQuat._v[1] - rhs[0] * mQuat._v[2] + rhs[1] * mQuat._v[3] + rhs[2] * mQuat._v[0];
465  value_type z = rhs[3] * mQuat._v[2] + rhs[0] * mQuat._v[1] - rhs[1] * mQuat._v[0] + rhs[2] * mQuat._v[3];
466  mQuat._v[3] = rhs[3] * mQuat._v[3] - rhs[0] * mQuat._v[0] - rhs[1] * mQuat._v[1] - rhs[2] * mQuat._v[2];
467 
468  mQuat._v[2] = z;
469  mQuat._v[1] = y;
470  mQuat._v[0] = x;
471 
472  return (*this); // enable nesting
473  }
474 
477  {
478  value_type div = 1.0 / rhs;
479  return Quat(mQuat._v[0] * div, mQuat._v[1] * div, mQuat._v[2] * div, mQuat._v[3] * div);
480  }
481 
484  {
485  value_type div = 1.0 / rhs;
486  mQuat._v[0] *= div;
487  mQuat._v[1] *= div;
488  mQuat._v[2] *= div;
489  mQuat._v[3] *= div;
490  return *this;
491  }
492 
494  const Quat Quat::operator/(const Quat& denom) const
495  {
496  return ((*this) * denom.Inverse());
497  }
498 
500  Quat& Quat::operator/=(const Quat& denom)
501  {
502  (*this) = (*this) * denom.Inverse();
503  return (*this); // enable nesting
504  }
505 
507  const Quat Quat::operator + (const Quat& rhs) const
508  {
509  return Quat(mQuat._v[0] + rhs[0], mQuat._v[1] + rhs[1],
510  mQuat._v[2] + rhs[2], mQuat._v[3] + rhs[3]);
511  }
512 
515  {
516  mQuat._v[0] += rhs[0];
517  mQuat._v[1] += rhs[1];
518  mQuat._v[2] += rhs[2];
519  mQuat._v[3] += rhs[3];
520  return *this; // enable nesting
521  }
522 
524  const Quat Quat::operator - (const Quat& rhs) const
525  {
526  return Quat(mQuat._v[0] - rhs[0], mQuat._v[1] - rhs[1],
527  mQuat._v[2] - rhs[2], mQuat._v[3] - rhs[3]);
528  }
529 
532  {
533  mQuat._v[0] -= rhs[0];
534  mQuat._v[1] -= rhs[1];
535  mQuat._v[2] -= rhs[2];
536  mQuat._v[3] -= rhs[3];
537  return *this; // enable nesting
538  }
539 
541  const Quat Quat::operator - () const
542  {
543  return Quat(-mQuat._v[0], -mQuat._v[1], -mQuat._v[2], -mQuat._v[3]);
544  }
545 
547  Quat::operator osg::Quat() const
548  {
549  return mQuat;
550  }
551 
553  Quat::operator osg::Quat&()
554  {
555  return mQuat;
556  }
557 
559  Quat::operator const osg::Quat&() const
560  {
561  return mQuat;
562  }
563 
565  Quat::operator osg::Quat*()
566  {
567  return &mQuat;
568  }
569 
571  std::string Quat::ToString(int precision)
572  {
573  return std::string("[" + trUtil::StringUtils::ToString<value_type>(mQuat._v[0], precision) + "][" + trUtil::StringUtils::ToString<value_type>(mQuat._v[1], precision) +
574  "][" + trUtil::StringUtils::ToString<value_type>(mQuat._v[2], precision) + "][" + trUtil::StringUtils::ToString<value_type>(mQuat._v[3], precision) + "]");
575  }
576 
578  std::ostream& operator << (std::ostream& ios, const Quat& q)
579  {
580  ios << "[" << q.X() << "][" << q.Y() << "][" << q.Z() << "][" << q.W() << "]";
581  return ios;
582  }
583 }
value_type Length2() const
(Length*Length) of the quaternion = vec .
Definition: Quat.cpp:217
Quat operator/(value_type rhs) const
Divide by scalar.
Definition: Quat.cpp:476
Quat()
Default constructor.
Definition: Quat.cpp:29
Vec4d AsVec4() const
Converts this object to a vector 4.
Definition: Quat.cpp:100
Quat & operator/=(value_type rhs)
Unary divide by scalar.
Definition: Quat.cpp:483
value_type & W()
Returns the W component of the vector.
value_type & Z()
Returns the Z component of the vector.
General purpose 3D float Vector.
Definition: Vec4f.h:47
const Quat operator-() const
Negation operator - returns the negative of the quaternion.
Definition: Quat.cpp:541
bool operator!=(const Quat &v) const
Not equals operator.
Definition: Quat.cpp:380
TR_BASE_EXPORT std::ostream & operator<<(std::ostream &ios, const Matrixd &q)
Stream insertion operator.
trBase::Quat Conj() const
Conjugate.
Definition: Quat.cpp:223
value_type & Z()
Returns the Z component of the vector.
bool operator<(const Quat &v) const
Less than operator.
Definition: Quat.cpp:386
void Set(const Quat &q)
Sets the given q.
Definition: Quat.cpp:112
A float Matrix class to be used for generic matrix operations.
Definition: Matrixd.h:40
General purpose 3D double Vector.
Definition: Vec3d.h:47
Vec3d AsVec3() const
Converts this object to a vector 3.
Definition: Quat.cpp:106
Quat & operator*=(value_type rhs)
Unary multiply by scalar.
Definition: Quat.cpp:442
General purpose 3D double Vector.
Definition: Vec4d.h:47
value_type & Z()
Returns the Z component of the quaternion/.
Definition: Quat.cpp:319
value_type & W()
Returns the W component of the quaternion/.
Definition: Quat.cpp:325
Quat & operator=(const Quat &v)
Set operator.
Definition: Quat.cpp:367
Represents a quaternion, that is used for angular calculations and transformations.
Definition: Quat.h:44
value_type & operator[](int i)
Index operator.
Definition: Quat.cpp:355
A float Matrix class to be used for generic matrix operations.
Definition: Matrixf.h:41
void GetRotate(value_type &angle, value_type &x, value_type &y, value_type &z) const
Return the angle and vector components represented by the quaternion.
Definition: Quat.cpp:277
osg::Quat mQuat
Definition: Quat.h:595
void Slerp(value_type t, const Quat &from, const Quat &to)
Spherical Linear Interpolation.
Definition: Quat.cpp:301
value_type & Y()
Returns the Y component of the vector.
bool operator==(const Quat &v) const
Equals operator.
Definition: Quat.cpp:374
value_type & X()
Returns the X component of the quaternion/.
Definition: Quat.cpp:307
Quat & operator+=(const Quat &rhs)
Unary addition.
Definition: Quat.cpp:514
value_type & W()
Returns the W component of the vector.
value_type Length() const
Length of the quaternion = sqrt( vec .
Definition: Quat.cpp:211
const Quat operator+(const Quat &rhs) const
Binary addition.
Definition: Quat.cpp:507
value_type & Y()
Returns the Y component of the quaternion/.
Definition: Quat.cpp:313
osg::Quat & GetOSGQuat()
Returns a reference to the internal OSG Quat.
Definition: Quat.cpp:88
const Quat operator*(value_type rhs) const
Multiply by scalar.
Definition: Quat.cpp:410
void MakeRotate(value_type angle, value_type x, value_type y, value_type z)
Set a quaternion which will perform a rotation of an angle around the axis given by the vector(x...
Definition: Quat.cpp:235
double value_type
Definition: Quat.h:48
void Clear()
Clears this object to its blank/initial state.
Definition: Quat.cpp:295
const trBase::Quat Inverse() const
Multiplicative inverse method: q^(-1) = q^* /(q.q^*)
Definition: Quat.cpp:229
value_type & X()
Returns the X component of the vector.
bool operator>(const Quat &v) const
Greater than operator.
Definition: Quat.cpp:398
Quat & operator-=(const Quat &rhs)
Unary subtraction.
Definition: Quat.cpp:531
value_type & X()
Returns the X component of the vector.
std::string ToString(int precision=-1)
Convert this object into a string representation.
Definition: Quat.cpp:571
value_type & Y()
Returns the Y component of the vector.
void Get(Matrixf &matrix) const
Sets the quaternion from the given matrix.
Definition: Quat.cpp:169
bool IsZeroRotation() const
return true if the Quat represents a zero rotation, and therefore can be ignored in computations...
Definition: Quat.cpp:205
General purpose 3D float Vector.
Definition: Vec3f.h:47