183 lines
5.9 KiBLFS
C++
183 lines
5.9 KiBLFS
C++
/**
|
|
* @file
|
|
*
|
|
* @author Max Lammers <max@senseglove.com>
|
|
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
*
|
|
* @section LICENSE
|
|
*
|
|
* Copyright (c) 2020 - 2023 SenseGlove
|
|
*
|
|
* @section DESCRIPTION
|
|
*
|
|
* A Quaternion is a representation of a rotation in 3D space without the
|
|
* problem of Gimbal Lock that exists in Euler representations.
|
|
*/
|
|
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "Platform.hpp"
|
|
|
|
namespace SGCore
|
|
{
|
|
namespace Kinematics
|
|
{
|
|
/// <summary> A rotation in 3D space that can be applied to a 3D vector or converted into Euler Angles. </summary>
|
|
class SGCORE_API Quat;
|
|
|
|
class Vect3D;
|
|
}// namespace Kinematics
|
|
}// namespace SGCore
|
|
|
|
/// <summary> A rotation in 3D space that can be applied to a 3D vector or converted into Euler Angles. </summary>
|
|
class SGCORE_API SGCore::Kinematics::Quat
|
|
{
|
|
public:
|
|
///<summary> Quaternion representing no rotation (0.0f, 0.0f, 0.0f, 1.0f) </summary>
|
|
static const Quat& Identity();
|
|
|
|
///<summary> Parse a Quaternion from a string. </summary>
|
|
static bool Deserialize(const std::string& str, Quat& out_result, char delimiter = ',');
|
|
|
|
///<summary> Create a new Quaternion Rotation from its euler angle representation. </summary>
|
|
static Quat FromEuler(float xAngle, float yAngle, float zAngle);
|
|
|
|
///<summary> Create a new Quaternion Rotation from its euler angle representation. </summary>
|
|
static Quat FromEuler(const Vect3D& euler);
|
|
|
|
///<summary> Create a new Quaternion Rotation from an angle-axis representation. </summary>
|
|
static Quat FromAngleAxis(float angle, float xAxis, float yAxis, float zAxis);
|
|
|
|
///<summary> Create a new Quaternion Rotation from an angle-axis representation. </summary>
|
|
static Quat FromAngleAxis(float angle, const Vect3D& axis);
|
|
|
|
/// <summary> Returns the inverse if q (a.k.a. a rotation in the other direction) </summary>
|
|
static Quat Invert(const Quat& quat);// -x-y-z w
|
|
|
|
/// <summary> Normalizes a quaternion to have a length of 1. </summary>
|
|
/// <returns></returns>
|
|
static Quat Normalize(const Quat& quat);
|
|
|
|
private:
|
|
struct Impl;
|
|
std::unique_ptr<Impl> Pimpl;
|
|
|
|
public:
|
|
/// <summary> Create a new Quaternion rotation of 0, 0, 0, 1. </summary>
|
|
Quat();
|
|
|
|
/// <summary> Create a new Quaternion rotation. </summary>
|
|
Quat(float x, float y, float z, float w);
|
|
|
|
/**
|
|
* The copy constructor.
|
|
*/
|
|
Quat(const Quat& rhs);
|
|
|
|
/**
|
|
* The move constructor.
|
|
*/
|
|
Quat(Quat&& rhs) noexcept;
|
|
|
|
/// <summary> Default Destructor. </summary>
|
|
virtual ~Quat();
|
|
|
|
public:
|
|
/**
|
|
* The copy assignment operator.
|
|
*/
|
|
Quat& operator=(const Quat& rhs);
|
|
|
|
/**
|
|
* The move assignment operator.
|
|
*/
|
|
Quat& operator=(Quat&& rhs) noexcept;
|
|
|
|
public:
|
|
/// <summary>
|
|
/// Add two quaternions together Using a Hamilton product.
|
|
/// NOTE: Q2 is applies first, followed by Q1, as per multiplication order of quaternions!
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// A rotation by Q1 followed by one of Q2 requires to operation Q2*Q1, using the Hamilton Multiplication.
|
|
/// https://en.wikipedia.org/wiki/Quaternion
|
|
/// </remarks>
|
|
// multiply this quaternion by another Quat - by quaternion law, that is the first rotation, followed by this.
|
|
Quat operator*(const Quat& quat) const;
|
|
|
|
//multiply this quaternion with a Vect3D, a.k.a. rotate it.
|
|
Vect3D operator*(const Vect3D& vect3D) const;
|
|
|
|
public:
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
float GetX() const;
|
|
void SetX(float x);
|
|
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
float GetY() const;
|
|
void SetY(float y);
|
|
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
float GetZ() const;
|
|
void SetZ(float z);
|
|
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
float GetW() const;
|
|
void SetW(float w);
|
|
|
|
public:
|
|
/// <summary> Retrieve this Quaternion's euler angle notation. </summary>
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
Vect3D ToEuler() const;
|
|
|
|
/// <summary> Rotate Vect3D by this quaternion rotation. </summary>
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
Vect3D Rotate(const Vect3D& vect3D) const;
|
|
|
|
/// <summary> Check if two quaternions have equal values. </summary>
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
bool Equals(const Quat& quat) const;
|
|
|
|
///<summary> Check if this Quaternion is the identity quaternion (meaning it does not rotate anything.) </summary>
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
bool IsIdentity() const;
|
|
|
|
/// <summary> Returns the magnitude of this Quaternion. Used in normalization. </summary>
|
|
/// <returns></returns>
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
float Magnitude() const;
|
|
|
|
/// <summary> Create a string representation of the Quaternion rotation. </summary>
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
std::string ToString() const;
|
|
|
|
public:
|
|
#if !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN )
|
|
[[nodiscard]]
|
|
#endif /* !defined ( SENSEGLOVE_UNREAL_ENGINE_PLUGIN ) */
|
|
std::string Serialize(const char delimiter = ',') const;
|
|
}; |