Momentum Scripting v1
Loading...
Searching...
No Matches
Quat.h
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material without having a written signed agreement with Algoryx Simulation AB.
9
10Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
11from using this software, unless otherwise stated in written agreements with
12Algoryx Simulation AB.
13*/
14
15
16
17#ifndef MOMENTUM_QUAT_H
18#define MOMENTUM_QUAT_H
19
20#include "momentum_namespace.h"
21#include "momentum_math.h"
22
23#include "Vec3.h"
24#include "Vec4.h"
25#include "EulerConvention.h"
26
27#include <agx/Quat.h>
28#include <agx/agx.h>
29
30#ifdef _MSC_VER
31# pragma warning(push)
32# pragma warning(disable: 6385) // Disable warning C6385: Reading invalid data
33#endif
34
35
36namespace MOMENTUM_NAMESPACE
37{
38 class EulerAngles;
39
40 class AffineMatrix4x4;
41
42
54 class MOMENTUM_EXPORT Quat
55 {
56 public:
57#ifndef SWIG
59 operator agx::Quat() const
60 {
61 return agx::Quat(this->x(), this->y(), this->z(), this->w());
62 }
63
64 Quat(const agx::Quat q)
65 {
66 set(q.x(), q.y(), q.z(), q.w());
67 }
69
70#endif
71
72
74 Quat();
75
77 Quat(double x, double y, double z, double w);
78
80 explicit Quat(const Vec4& v);
81
83 Quat(double angle, const Vec3& axis);
84
88 Quat(double angle1, const Vec3& axis1,
89 double angle2, const Vec3& axis2,
90 double angle3, const Vec3& axis3);
91
95 Quat(const Vec3& from, const Vec3& to);
96
100 explicit Quat(const EulerAngles& euler);
101
102
104 Quat(const Quat& copy);
105
109 explicit Quat(const AffineMatrix4x4& matrix);
110
111#ifndef SWIG
113 Quat operator = (const Quat& v);
114#endif
119 bool operator == (const Quat& v) const;
120
124 bool operator != (const Quat& v) const;
125
126 /* ----------------------------------
127 Methods to access data members
128 ---------------------------------- */
129
131 Vec4 asVec4() const;
132
134 Vec3 asVec3() const;
135
137 void set(double x, double y, double z, double w);
138
140 void set(const Vec4& v);
141
142
147 Vec3 getAsEulerAngles(EulerConvention::Convention convention = EulerConvention::Convention::DEFAULT_CONVENTION) const;
148
153 AffineMatrix4x4 get(const AffineMatrix4x4& matrix) const;
154
155
160 std::pair<double,Vec3> getAsAngleAndVector() const;
161
162
167 Quat set(const EulerAngles& euler);
168
173 Quat set(const AffineMatrix4x4& matrix);
174
175#ifndef SWIG
177 double& operator [] (int i);
178
180 double operator [] (int i) const;
181#endif
183 double setX(double val);
184
186 double setY(double val);
187
189 double setZ(double val);
190
192 double setW(double val);
193
195 double x() const;
196
198 double y() const;
199
201 double z() const;
202
204 double w() const;
205
209 bool zeroRotation() const;
210
211
212 /* -------------------------------------------------------------
213 BASIC ARITHMETIC METHODS
214 Implemented in terms of Vec4s. Some Vec4 operators, e.g.
215 operator* are not appropriate for quaternions (as
216 mathematical objects) so they are implemented differently.
217 Also define methods for conjugate and the multiplicative inverse.
218 ------------------------------------------------------------- */
220 const Quat operator * (double rhs) const;
221
223 Quat operator *= (double rhs);
224
229 const Quat operator*(const Quat& rhs) const;
230
235 Quat operator*=(const Quat& rhs);
236
241 const Quat leftMult(const Quat& rhs) const;
242
247 const Quat rightMult(const Quat& rhs) const;
248
249
251 Quat operator / (double rhs) const;
252
254 Quat operator /= (double rhs);
255
257 const Quat operator/(const Quat& denom) const;
258
260 Quat operator/=(const Quat& denom);
261
263 const Quat operator + (const Quat& rhs) const;
264
266 Quat operator += (const Quat& rhs);
267
269 const Quat operator - (const Quat& rhs) const;
270
272 Quat operator -= (const Quat& rhs);
273
278 const Quat operator - () const;
279
281 double length() const;
282
284 double length2() const;
285
287 Quat conj() const;
288
290 Quat inverse() const;
291
295 void setRotate(double angle, double x, double y, double z);
296
300 void setRotate(double angle, const Vec3& vec);
301
307 void setRotate(double angle1, const Vec3& axis1,
308 double angle2, const Vec3& axis2,
309 double angle3, const Vec3& axis3);
310
318 void setRotate(const Vec3& from, const Vec3& to);
319
323 static Quat rotate(double angle, double x, double y, double z);
324
328 static Quat rotate(double angle, const Vec3& vec);
329
335 static Quat rotate(double angle1, const Vec3& axis1,
336 double angle2, const Vec3& axis2,
337 double angle3, const Vec3& axis3);
338
342 static Quat rotate(const Vec3& from, const Vec3& to);
343
347 std::pair<double, Vec3> getRotate() const;
348
353 void slerp(double t, const Quat& from, const Quat& to);
354
358 Vec3 operator* (const Vec3& v) const;
359
364 double normalize();
365
367 protected:
368 double m_data[4];
370 };
371
372#ifndef SWIG
373 /* Implementation */
374 inline Quat::Quat()
375 {
376 m_data[0] = 0.0;
377 m_data[1] = 0.0;
378 m_data[2] = 0.0;
379 m_data[3] = 1.0;
380 }
381
382 inline Quat::Quat(double x, double y, double z, double w)
383 {
384 m_data[0] = x;
385 m_data[1] = y;
386 m_data[2] = z;
387 m_data[3] = w;
388 }
389
390 inline Quat::Quat(const Vec4& v)
391 {
392 m_data[0] = v.x();
393 m_data[1] = v.y();
394 m_data[2] = v.z();
395 m_data[3] = v.w();
396 }
397
398 inline Quat::Quat(double angle, const Vec3& axis)
399 {
400 setRotate(angle, axis);
401 }
402
403 inline Quat::Quat(double angle1, const Vec3& axis1,
404 double angle2, const Vec3& axis2,
405 double angle3, const Vec3& axis3)
406 {
407 setRotate(angle1, axis1, angle2, axis2, angle3, axis3);
408 }
409
410 inline Quat::Quat(const Vec3& from, const Vec3& to)
411 {
412 setRotate(from, to);
413 }
414
415 inline Quat::Quat(const EulerAngles& euler)
416 {
417 set(euler);
418 }
419
420
421 inline Quat::Quat(const Quat& copy)
422 {
423 m_data[0] = copy.m_data[0];
424 m_data[1] = copy.m_data[1];
425 m_data[2] = copy.m_data[2];
426 m_data[3] = copy.m_data[3];
427 }
428
429 inline Quat::Quat(const AffineMatrix4x4& matrix)
430 {
431 set(matrix);
432 }
433
434
435 inline Quat Quat::operator = (const Quat& v)
436 {
437 m_data[0] = v.m_data[0];
438 m_data[1] = v.m_data[1];
439 m_data[2] = v.m_data[2];
440 m_data[3] = v.m_data[3];
441 return *this;
442 }
443
444 inline bool Quat::operator == (const Quat& v) const
445 {
446 return m_data[0] == v.m_data[0] && m_data[1] == v.m_data[1] && m_data[2] == v.m_data[2] && m_data[3] == v.m_data[3];
447 }
448
449 inline bool Quat::operator != (const Quat& v) const
450 {
451 return m_data[0] != v.m_data[0] || m_data[1] != v.m_data[1] || m_data[2] != v.m_data[2] || m_data[3] != v.m_data[3];
452 }
453
454 inline Vec4 Quat::asVec4() const
455 {
456 return Vec4(m_data[0], m_data[1], m_data[2], m_data[3]);
457 }
458
459 inline Vec3 Quat::asVec3() const
460 {
461 return Vec3(m_data[0], m_data[1], m_data[2]);
462 }
463
464 inline void Quat::set(double x, double y, double z, double w)
465 {
466 m_data[0] = x;
467 m_data[1] = y;
468 m_data[2] = z;
469 m_data[3] = w;
470 }
471
472 inline void Quat::set(const Vec4& v)
473 {
474 m_data[0] = v.x();
475 m_data[1] = v.y();
476 m_data[2] = v.z();
477 m_data[3] = v.w();
478 }
479
480 inline double Quat::operator [] (int i) const
481 {
482 agxAssert(i < 4);
483 return m_data[i];
484 }
485
486 inline double& Quat::operator [] (int i)
487 {
488 agxAssert(i < 4);
489 return m_data[i];
490 }
491
492 inline double Quat::setX(double val)
493 {
494 m_data[0] = val;
495 return m_data[0];
496 }
497
498 inline double Quat::setY(double val)
499 {
500 m_data[1] = val;
501 return m_data[1];
502 }
503
504 inline double Quat::setZ(double val)
505 {
506 m_data[2] = val;
507 return m_data[2];
508 }
509
510 inline double Quat::setW(double val)
511 {
512 m_data[3] = val;
513 return m_data[3];
514 }
515
516 inline double Quat::x() const
517 {
518 return m_data[0];
519 }
520
521 inline double Quat::y() const
522 {
523 return m_data[1];
524 }
525
526 inline double Quat::z() const
527 {
528 return m_data[2];
529 }
530
531 inline double Quat::w() const
532 {
533 return m_data[3];
534 }
535
536 inline bool Quat::zeroRotation() const
537 {
538 return m_data[0] == 0.0 && m_data[1] == 0.0 && m_data[2] == 0.0 && m_data[3] == 1.0;
539 }
540
541
542 inline const Quat Quat::operator * (double rhs) const
543 {
544 return Quat(m_data[0] * rhs, m_data[1] * rhs, m_data[2] * rhs, m_data[3] * rhs);
545 }
546
547 inline Quat Quat::operator *= (double rhs)
548 {
549 m_data[0] *= rhs;
550 m_data[1] *= rhs;
551 m_data[2] *= rhs;
552 m_data[3] *= rhs;
553 return *this; // enable nesting
554 }
555
556 inline const Quat Quat::operator*(const Quat& rhs) const
557 {
558 return Quat(rhs.m_data[3] * m_data[0] + rhs.m_data[0] * m_data[3] + rhs.m_data[1] * m_data[2] - rhs.m_data[2] * m_data[1],
559 rhs.m_data[3] * m_data[1] - rhs.m_data[0] * m_data[2] + rhs.m_data[1] * m_data[3] + rhs.m_data[2] * m_data[0],
560 rhs.m_data[3] * m_data[2] + rhs.m_data[0] * m_data[1] - rhs.m_data[1] * m_data[0] + rhs.m_data[2] * m_data[3],
561 rhs.m_data[3] * m_data[3] - rhs.m_data[0] * m_data[0] - rhs.m_data[1] * m_data[1] - rhs.m_data[2] * m_data[2]);
562 }
563
564 inline Quat Quat::operator*=(const Quat& rhs)
565 {
566 double x = rhs.m_data[3] * m_data[0] + rhs.m_data[0] * m_data[3] + rhs.m_data[1] * m_data[2] - rhs.m_data[2] * m_data[1];
567 double y = rhs.m_data[3] * m_data[1] - rhs.m_data[0] * m_data[2] + rhs.m_data[1] * m_data[3] + rhs.m_data[2] * m_data[0];
568 double z = rhs.m_data[3] * m_data[2] + rhs.m_data[0] * m_data[1] - rhs.m_data[1] * m_data[0] + rhs.m_data[2] * m_data[3];
569 m_data[3] = rhs.m_data[3] * m_data[3] - rhs.m_data[0] * m_data[0] - rhs.m_data[1] * m_data[1] - rhs.m_data[2] * m_data[2];
570
571 m_data[2] = z;
572 m_data[1] = y;
573 m_data[0] = x;
574
575 return (*this); // enable nesting
576 }
577
578 inline const Quat Quat::leftMult(const Quat& rhs) const
579 {
580 return (*this) * rhs;
581 }
582
583 inline const Quat Quat::rightMult(const Quat& rhs) const
584 {
585 return rhs * (*this);
586 }
587
588
589 inline Quat Quat::operator / (double rhs) const
590 {
591 double div = double(1) / rhs;
592 return Quat(m_data[0] * div, m_data[1] * div, m_data[2] * div, m_data[3] * div);
593 }
594
595 inline Quat Quat::operator /= (double rhs)
596 {
597 double div = double(1) / rhs;
598 m_data[0] *= div;
599 m_data[1] *= div;
600 m_data[2] *= div;
601 m_data[3] *= div;
602 return *this;
603 }
604
605 inline const Quat Quat::operator/(const Quat& denom) const
606 {
607 return ((*this) * denom.inverse());
608 }
609
610 inline Quat Quat::operator/=(const Quat& denom)
611 {
612 (*this) = (*this) * denom.inverse();
613 return (*this); // enable nesting
614 }
615
616 inline const Quat Quat::operator + (const Quat& rhs) const
617 {
618 return Quat(m_data[0] + rhs.m_data[0], m_data[1] + rhs.m_data[1],
619 m_data[2] + rhs.m_data[2], m_data[3] + rhs.m_data[3]);
620 }
621
622 inline Quat Quat::operator += (const Quat& rhs)
623 {
624 m_data[0] += rhs.m_data[0];
625 m_data[1] += rhs.m_data[1];
626 m_data[2] += rhs.m_data[2];
627 m_data[3] += rhs.m_data[3];
628 return *this; // enable nesting
629 }
630
631 inline const Quat Quat::operator - (const Quat& rhs) const
632 {
633 return Quat(m_data[0] - rhs.m_data[0], m_data[1] - rhs.m_data[1],
634 m_data[2] - rhs.m_data[2], m_data[3] - rhs.m_data[3]);
635 }
636
637 inline Quat Quat::operator -= (const Quat& rhs)
638 {
639 m_data[0] -= rhs.m_data[0];
640 m_data[1] -= rhs.m_data[1];
641 m_data[2] -= rhs.m_data[2];
642 m_data[3] -= rhs.m_data[3];
643 return *this; // enable nesting
644 }
645
646 inline const Quat Quat::operator - () const
647 {
648 return Quat(-m_data[0], -m_data[1], -m_data[2], -m_data[3]);
649 }
650
651 inline double Quat::length() const
652 {
653 return std::sqrt(m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2] + m_data[3] * m_data[3]);
654 }
655
656 inline double Quat::length2() const
657 {
658 return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2] + m_data[3] * m_data[3];
659 }
660
661 inline Quat Quat::conj() const
662 {
663 return Quat(-m_data[0], -m_data[1], -m_data[2], m_data[3]);
664 }
665
666 inline Quat Quat::inverse() const
667 {
668 return conj() / length2();
669 }
670
671 inline Quat Quat::rotate(double angle, double x, double y, double z)
672 {
673 return rotate(angle, Vec3(x, y, z));
674 }
675
676 inline Quat Quat::rotate(double angle, const Vec3& vec)
677 {
678 Quat q;
679 q.setRotate(angle, vec);
680 return q;
681 }
682
683 inline Quat Quat::rotate(double angle1, const Vec3& axis1,
684 double angle2, const Vec3& axis2,
685 double angle3, const Vec3& axis3)
686 {
687 Quat q;
688 q.setRotate(angle1, axis1, angle2, axis2, angle3, axis3);
689 return q;
690 }
691
692 inline Quat Quat::rotate(const Vec3& from, const Vec3& to)
693 {
694 Quat q;
695 q.setRotate(from, to);
696 return q;
697 }
698
699 inline Vec3 Quat::operator* (const Vec3& v) const
700 {
701 // nVidia SDK implementation
702 Vec3 uv, uuv;
703 Vec3 qvec(m_data[0], m_data[1], m_data[2]);
704 uv = qvec ^ v;
705 uuv = qvec ^ uv;
706 uv *= (2.0f * m_data[3]);
707 uuv *= 2.0f;
708 return v + uv + uuv;
709 }
710
711 inline double Quat::normalize()
712 {
713 double norm = this->length();
714 if (norm > 0.0) {
715 double inv = double(1) / norm;
716 m_data[0] *= inv;
717 m_data[1] *= inv;
718 m_data[2] *= inv;
719 m_data[3] *= inv;
720 }
721 return(norm);
722 }
723
724 template <typename T>
725 inline std::ostream& operator << (std::ostream& output, const Quat& quat)
726 {
727 output << quat[0] << " "
728 << quat[1] << " "
729 << quat[2] << " "
730 << quat[3];
731 return output; // to enable cascading
732 }
733#endif //"#ifndef SWIG"
734
735 inline bool equivalent( const Quat& a, const Quat& b, double epsilon = double( MOMENTUM_EQUIVALENT_EPSILON ) )
736 {
737 return
738 agx::equivalent( a[ 0 ], b[ 0 ], epsilon ) &&
739 agx::equivalent( a[ 1 ], b[ 1 ], epsilon ) &&
740 agx::equivalent( a[ 2 ], b[ 2 ], epsilon ) &&
741 agx::equivalent( a[ 3 ], b[ 3 ], epsilon );
742 }
743}
744
745#ifdef _MSC_VER
746# pragma warning(pop)
747#endif
748
749#endif /* MOMENTUM_QuatEMPLATE_H */
Matrix class for rigid transformations (translation, rotation).
Definition: AffineMatrix4x4.h:51
This class provides conversion services between Euler angles in any of the 24 conventions and corresp...
Definition: EulerAngles.h:64
Convention
Definition: EulerConvention.h:32
The object holding quaternions and providing operations on these.
Definition: Quat.h:55
void set(double x, double y, double z, double w)
Set the 4 elements of the quaternion as 4 scalars.
Definition: Quat.h:464
double & operator[](int i)
Definition: Quat.h:486
bool operator==(const Quat &v) const
Test for equality.
Definition: Quat.h:444
Vec4 asVec4() const
Definition: Quat.h:454
Quat()
Default constructor. Create a Quaternion with an identity rotation.
Definition: Quat.h:374
double setW(double val)
Definition: Quat.h:510
double length() const
Definition: Quat.h:651
Quat operator*=(double rhs)
Unary multiply by scalar rhs.
Definition: Quat.h:547
const Quat operator*(double rhs) const
Multiply by scalar rhs.
Definition: Quat.h:542
Quat conj() const
Definition: Quat.h:661
const Quat operator+(const Quat &rhs) const
Binary addition.
Definition: Quat.h:616
std::pair< double, Vec3 > getRotate() const
Get the angle and vector represented by the quaternion.
void setRotate(const Vec3 &from, const Vec3 &to)
Make a rotation Quat which will rotate from to to Generally take a dot product to get the angle betwe...
bool operator!=(const Quat &v) const
Definition: Quat.h:449
Quat operator/=(double rhs)
Unary divide by scalar rhs.
Definition: Quat.h:595
Quat operator+=(const Quat &rhs)
Unary addition.
Definition: Quat.h:622
void setRotate(double angle1, const Vec3 &axis1, double angle2, const Vec3 &axis2, double angle3, const Vec3 &axis3)
Set the rotation of this Quaternion as a concatenation of the three angle/axis rotations:
void setRotate(double angle, double x, double y, double z)
Set the rotation of the Quaternion as a rotation angle radians around the vector (x,...
Quat operator/(double rhs) const
Divide by scalar rhs.
Definition: Quat.h:589
double z() const
Definition: Quat.h:526
double length2() const
Definition: Quat.h:656
void slerp(double t, const Quat &from, const Quat &to)
Spherical Linear Interpolation.
double normalize()
Normalize the quat so that it has unit length.
Definition: Quat.h:711
void setRotate(double angle, const Vec3 &vec)
Set the rotation of this Quaternion as a rotation angle radians around the vector vec.
double w() const
Definition: Quat.h:531
Quat inverse() const
Multiplicative inverse method: q^(-1) = q^*‍/(q.q^*)
Definition: Quat.h:666
std::pair< double, Vec3 > getAsAngleAndVector() const
Convert a Quaternion to an axis and angle representation.
Quat set(const EulerAngles &euler)
Set this quaternion with the rotation described by the EulerAngles representation.
AffineMatrix4x4 get(const AffineMatrix4x4 &matrix) const
Set the Rotational part of matrix from this quaternion.
Quat set(const AffineMatrix4x4 &matrix)
Set this quaternion with the rotational part of matrix.
const Quat rightMult(const Quat &rhs) const
Binary RIGHT multiplication: q = p * rhs ; results in q = p quatmultiply rhs ;.
Definition: Quat.h:583
Vec3 getAsEulerAngles(EulerConvention::Convention convention=EulerConvention::Convention::DEFAULT_CONVENTION) const
Convert to Euler anglers.
static Quat rotate(double angle, double x, double y, double z)
Static method which constructs and returns a Quaternion from a rotation given as angle radians around...
Definition: Quat.h:671
double setX(double val)
Definition: Quat.h:492
const Quat operator-() const
Negation operator - returns the negative of the quaternion.
Definition: Quat.h:646
bool zeroRotation() const
Definition: Quat.h:536
double x() const
Definition: Quat.h:516
Quat operator=(const Quat &v)
Assignment operator.
Definition: Quat.h:435
Quat operator-=(const Quat &rhs)
Unary subtraction.
Definition: Quat.h:637
Vec3 asVec3() const
Definition: Quat.h:459
double setZ(double val)
Definition: Quat.h:504
double y() const
Definition: Quat.h:521
const Quat leftMult(const Quat &rhs) const
Binary left multiplication: q = p * rhs; results in the OTHER WAY AROUND: q = rhs quatmultiply p;.
Definition: Quat.h:578
double setY(double val)
Definition: Quat.h:498
A 3 dimensional vector which can be used to define a point or a vector and contains basic arithmetic.
Definition: Vec3.h:40
A 4 dimensional vector and contains basic arithmetic.
Definition: Vec4.h:33
double z() const
Definition: Vec4.h:466
double w() const
Definition: Vec4.h:472
double y() const
Definition: Vec4.h:461
double x() const
Definition: Vec4.h:455
Namespace for Momentum Scripting API.
Definition: AffineMatrix4x4.h:29
const double MOMENTUM_EQUIVALENT_EPSILON
Definition: momentum_math.h:30
std::ostream & operator<<(std::ostream &os, const EulerAngles &e)
Definition: EulerAngles.h:358
Vec3 operator*(const Vec3 &v, const Matrix3x3 &m)
Definition: Matrix3x3.h:746
bool equivalent(const Matrix3x3 &a, const Matrix3x3 &b, double epsilon=1e-6)
Definition: Matrix3x3.h:905