Eule/Eule/Quaternion.h

105 lines
3.1 KiB
C++

#pragma once
#include "Vector3.h"
#include "Vector4.h"
#include "Matrix4x4.h"
#include <mutex>
namespace Eule
{
/** 3D rotation representation
*/
class Quaternion
{
public:
Quaternion();
//! Constructs by these raw values
explicit Quaternion(const Vector4d values);
//! Copies this existing Quaternion
Quaternion(const Quaternion& q);
//! Creates an quaternion from euler angles
Quaternion(const Vector3d eulerAngles);
~Quaternion();
//! Copies
Quaternion operator= (const Quaternion& q);
//! Multiplies (applies)
Quaternion operator* (const Quaternion& q) const;
//! Divides (applies)
Quaternion operator/ (Quaternion& q) const;
//! Also multiplies
Quaternion& operator*= (const Quaternion& q);
//! Also divides
Quaternion& operator/= (const Quaternion& q);
//! Will transform a 3d point around its origin
Vector3d operator* (const Vector3d& p) const;
bool operator== (const Quaternion& q) const;
bool operator!= (const Quaternion& q) const;
Quaternion Inverse() const;
Quaternion Conjugate() const;
Quaternion UnitQuaternion() const;
//! Will rotate a vector by this quaternion
Vector3d RotateVector(const Vector3d& vec) const;
//! Will return euler angles representing this Quaternion's rotation
Vector3d ToEulerAngles() const;
//! Will return a rotation matrix representing this Quaternions rotation
Matrix4x4 ToRotationMatrix() const;
//! Will return the raw four-dimensional values
Vector4d GetRawValues() const;
//! Will return the value between two Quaternion's as another Quaternion
Quaternion AngleBetween(const Quaternion& other) const;
//! Will set the raw four-dimensional values
void SetRawValues(const Vector4d values);
//! Will return the lerp result between two quaternions
Quaternion Lerp(const Quaternion& other, double t) const;
friend std::ostream& operator<< (std::ostream& os, const Quaternion& q);
friend std::wostream& operator<< (std::wostream& os, const Quaternion& q);
private:
//! Scales
Quaternion operator* (const double scale) const;
Quaternion& operator*= (const double scale);
//! Quaternion values
Vector4d v;
//! Will force a regenartion of the euler and matrix caches on further converter calls
void InvalidateCache();
// Caches for conversions
mutable bool isCacheUpToDate_euler = false;
mutable Vector3d cache_euler;
mutable bool isCacheUpToDate_matrix = false;
mutable Matrix4x4 cache_matrix;
mutable bool isCacheUpToDate_inverse = false;
mutable Vector4d cache_inverse;
// Mutexes for thread-safe caching
mutable std::mutex lock_eulerCache;
mutable std::mutex lock_matrixCache;
mutable std::mutex lock_inverseCache;
};
}