Fixed bug in Quaternion that didn't allow for operator/ with a const-qualified operand b

This commit is contained in:
Leonetienne 2022-02-11 14:48:13 +01:00
parent b8b3005cb2
commit f2519fd085
2 changed files with 320 additions and 322 deletions

View File

@ -10,28 +10,28 @@
#include "gcccompat.h" #include "gcccompat.h"
#endif #endif
using namespace Eule; namespace Eule {
Quaternion::Quaternion() Quaternion::Quaternion()
{ {
v = Vector4d(0, 0, 0, 1); v = Vector4d(0, 0, 0, 1);
return; return;
} }
Quaternion::Quaternion(const Vector4d values) Quaternion::Quaternion(const Vector4d values)
{ {
v = values; v = values;
return; return;
} }
Quaternion::Quaternion(const Quaternion& q) Quaternion::Quaternion(const Quaternion& q)
{ {
v = q.v; v = q.v;
return; return;
} }
Quaternion::Quaternion(const Vector3d eulerAngles) Quaternion::Quaternion(const Vector3d eulerAngles)
{ {
Vector3d eulerRad = eulerAngles * Deg2Rad; Vector3d eulerRad = eulerAngles * Deg2Rad;
#ifndef _EULE_NO_INTRINSICS_ #ifndef _EULE_NO_INTRINSICS_
@ -96,44 +96,44 @@ Quaternion::Quaternion(const Vector3d eulerAngles)
#endif #endif
return; return;
} }
Quaternion::~Quaternion() Quaternion::~Quaternion()
{ {
return; return;
} }
Quaternion Quaternion::operator= (const Quaternion& q) Quaternion Quaternion::operator= (const Quaternion& q)
{ {
InvalidateCache(); InvalidateCache();
v = q.v; v = q.v;
return (*this); return (*this);
} }
Quaternion Quaternion::operator* (const Quaternion& q) const Quaternion Quaternion::operator* (const Quaternion& q) const
{ {
return Quaternion(Vector4d( return Quaternion(Vector4d(
v.w * q.v.x + v.x * q.v.w + v.y * q.v.z - v.z * q.v.y, v.w * q.v.x + v.x * q.v.w + v.y * q.v.z - v.z * q.v.y,
v.w * q.v.y + v.y * q.v.w + v.z * q.v.x - v.x * q.v.z, v.w * q.v.y + v.y * q.v.w + v.z * q.v.x - v.x * q.v.z,
v.w * q.v.z + v.z * q.v.w + v.x * q.v.y - v.y * q.v.x, v.w * q.v.z + v.z * q.v.w + v.x * q.v.y - v.y * q.v.x,
v.w * q.v.w - v.x * q.v.x - v.y * q.v.y - v.z * q.v.z v.w * q.v.w - v.x * q.v.x - v.y * q.v.y - v.z * q.v.z
)); ));
} }
Quaternion Quaternion::operator*(const double scale) const Quaternion Quaternion::operator*(const double scale) const
{ {
return Quaternion(v * scale); return Quaternion(v * scale);
} }
Quaternion Quaternion::operator/ (Quaternion& q) const Quaternion Quaternion::operator/ (const Quaternion& q) const
{ {
return ((*this) * (q.Inverse())); return ((*this) * (q.Inverse()));
} }
Quaternion& Quaternion::operator*= (const Quaternion& q) Quaternion& Quaternion::operator*= (const Quaternion& q)
{ {
InvalidateCache(); InvalidateCache();
Vector4d bufr = v; Vector4d bufr = v;
@ -143,41 +143,41 @@ Quaternion& Quaternion::operator*= (const Quaternion& q)
v.w = bufr.w * q.v.w - bufr.x * q.v.x - bufr.y * q.v.y - bufr.z * q.v.z; // w v.w = bufr.w * q.v.w - bufr.x * q.v.x - bufr.y * q.v.y - bufr.z * q.v.z; // w
return (*this); return (*this);
} }
Quaternion& Quaternion::operator*=(const double scale) Quaternion& Quaternion::operator*=(const double scale)
{ {
InvalidateCache(); InvalidateCache();
v *= scale; v *= scale;
return (*this); return (*this);
} }
Quaternion& Quaternion::operator/= (const Quaternion& q) Quaternion& Quaternion::operator/= (const Quaternion& q)
{ {
InvalidateCache(); InvalidateCache();
(*this) = (*this) * q.Inverse(); (*this) = (*this) * q.Inverse();
return (*this); return (*this);
} }
Vector3d Quaternion::operator*(const Vector3d& p) const Vector3d Quaternion::operator*(const Vector3d& p) const
{ {
return RotateVector(p); return RotateVector(p);
} }
bool Quaternion::operator== (const Quaternion& q) const bool Quaternion::operator== (const Quaternion& q) const
{ {
return (v.Similar(q.v)) || (v.Similar(q.v * -1)); return (v.Similar(q.v)) || (v.Similar(q.v * -1));
} }
bool Quaternion::operator!= (const Quaternion& q) const bool Quaternion::operator!= (const Quaternion& q) const
{ {
return (!v.Similar(q.v)) && (!v.Similar(q.v * -1)); return (!v.Similar(q.v)) && (!v.Similar(q.v * -1));
} }
Quaternion Quaternion::Inverse() const Quaternion Quaternion::Inverse() const
{ {
const std::lock_guard<std::mutex> lock(lock_inverseCache); const std::lock_guard<std::mutex> lock(lock_inverseCache);
if (!isCacheUpToDate_inverse) if (!isCacheUpToDate_inverse)
@ -188,20 +188,20 @@ Quaternion Quaternion::Inverse() const
} }
return Quaternion(cache_inverse); return Quaternion(cache_inverse);
} }
Quaternion Quaternion::Conjugate() const Quaternion Quaternion::Conjugate() const
{ {
return Quaternion(Vector4d(-v.x, -v.y, -v.z, v.w)); return Quaternion(Vector4d(-v.x, -v.y, -v.z, v.w));
} }
Quaternion Quaternion::UnitQuaternion() const Quaternion Quaternion::UnitQuaternion() const
{ {
return (*this) * (1.0 / v.Magnitude()); return (*this) * (1.0 / v.Magnitude());
} }
Vector3d Quaternion::RotateVector(const Vector3d& vec) const Vector3d Quaternion::RotateVector(const Vector3d& vec) const
{ {
Quaternion pure(Vector4d(vec.x, vec.y, vec.z, 0)); Quaternion pure(Vector4d(vec.x, vec.y, vec.z, 0));
//Quaternion f = Conjugate() * pure * (*this); //Quaternion f = Conjugate() * pure * (*this);
@ -216,10 +216,10 @@ Vector3d Quaternion::RotateVector(const Vector3d& vec) const
toRet.z = f.v.z; toRet.z = f.v.z;
return toRet; return toRet;
} }
Vector3d Quaternion::ToEulerAngles() const Vector3d Quaternion::ToEulerAngles() const
{ {
const std::lock_guard<std::mutex> lock(lock_eulerCache); const std::lock_guard<std::mutex> lock(lock_eulerCache);
if (!isCacheUpToDate_euler) if (!isCacheUpToDate_euler)
@ -249,10 +249,10 @@ Vector3d Quaternion::ToEulerAngles() const
} }
return cache_euler; return cache_euler;
} }
Matrix4x4 Quaternion::ToRotationMatrix() const Matrix4x4 Quaternion::ToRotationMatrix() const
{ {
const std::lock_guard<std::mutex> lock(lock_matrixCache); const std::lock_guard<std::mutex> lock(lock_matrixCache);
if (!isCacheUpToDate_matrix) if (!isCacheUpToDate_matrix)
@ -295,43 +295,41 @@ Matrix4x4 Quaternion::ToRotationMatrix() const
} }
return cache_matrix; return cache_matrix;
} }
Vector4d Quaternion::GetRawValues() const Vector4d Quaternion::GetRawValues() const
{ {
return v; return v;
} }
Quaternion Quaternion::AngleBetween(const Quaternion& other) const Quaternion Quaternion::AngleBetween(const Quaternion& other) const
{ {
return other * Conjugate(); return other * Conjugate();
} }
void Quaternion::SetRawValues(const Vector4d values) void Quaternion::SetRawValues(const Vector4d values)
{ {
InvalidateCache(); InvalidateCache();
v = values; v = values;
return; return;
} }
Quaternion Quaternion::Lerp(const Quaternion& other, double t) const Quaternion Quaternion::Lerp(const Quaternion& other, double t) const
{ {
return Quaternion(v.Lerp(other.v, t)).UnitQuaternion(); return Quaternion(v.Lerp(other.v, t)).UnitQuaternion();
} }
void Quaternion::InvalidateCache() void Quaternion::InvalidateCache()
{ {
isCacheUpToDate_euler = false; isCacheUpToDate_euler = false;
isCacheUpToDate_matrix = false; isCacheUpToDate_matrix = false;
isCacheUpToDate_inverse = false; isCacheUpToDate_inverse = false;
return; return;
} }
namespace Eule
{
std::ostream& operator<< (std::ostream& os, const Quaternion& q) std::ostream& operator<< (std::ostream& os, const Quaternion& q)
{ {
os << "[" << q.v << "]"; os << "[" << q.v << "]";

View File

@ -31,7 +31,7 @@ namespace Eule
Quaternion operator* (const Quaternion& q) const; Quaternion operator* (const Quaternion& q) const;
//! Divides (applies) //! Divides (applies)
Quaternion operator/ (Quaternion& q) const; Quaternion operator/ (const Quaternion& q) const;
//! Also multiplies //! Also multiplies
Quaternion& operator*= (const Quaternion& q); Quaternion& operator*= (const Quaternion& q);