297 lines
8.4 KiB
C++
297 lines
8.4 KiB
C++
#ifndef RAYLIB_CPP_INCLUDE_QUATERNION_HPP_
|
|
#define RAYLIB_CPP_INCLUDE_QUATERNION_HPP_
|
|
|
|
#ifndef RAYLIB_CPP_NO_MATH
|
|
#include <cmath>
|
|
#include <utility>
|
|
#endif
|
|
|
|
#include <string>
|
|
|
|
#include "./raylib-cpp-utils.hpp"
|
|
#include "./raylib.hpp"
|
|
#include "./raymath.hpp"
|
|
|
|
namespace raylib {
|
|
class Vector4 : public ::Vector4 {};
|
|
|
|
/**
|
|
* Quaternion type
|
|
*/
|
|
class Quaternion : public ::Quaternion {
|
|
public:
|
|
constexpr Quaternion(const ::Quaternion& quat) : ::Quaternion{quat.x, quat.y, quat.z, quat.w} {}
|
|
explicit constexpr Quaternion(const raylib::Vector4 vec4) : ::Quaternion{vec4.x, vec4.y, vec4.z, vec4.w} {}
|
|
|
|
explicit constexpr Quaternion(const float x = 0, const float y = 0, const float z = 0, const float w = 1) : ::Quaternion{x, y, z, w} {}
|
|
|
|
GETTERSETTER(float, X, x)
|
|
GETTERSETTER(float, Y, y)
|
|
GETTERSETTER(float, Z, z)
|
|
GETTERSETTER(float, W, w)
|
|
|
|
Quaternion& operator=(const ::Quaternion& quaternion) {
|
|
set(quaternion);
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
* An exact value by value equality comparison.
|
|
* Due to floating point inaccuracies consider using Equals instead.
|
|
*/
|
|
constexpr bool operator==(const ::Quaternion& other) const {
|
|
return x == other.x && y == other.y && z == other.z && w == other.w;
|
|
}
|
|
|
|
/*
|
|
* An exact value by value inequality comparison.
|
|
* Due to floating point inaccuracies consider using Equals instead.
|
|
*/
|
|
constexpr bool operator!=(const ::Quaternion& other) const { return !(*this == other); }
|
|
|
|
RLCPP_NODISCARD std::string ToString() const { return ::TextFormat("Quaternion(%f, %f, %f, %f)", x, y, z, w); }
|
|
|
|
operator std::string() const { return ToString(); }
|
|
|
|
#ifndef RAYLIB_CPP_NO_MATH
|
|
/**
|
|
* Add two quaternions
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Add(const ::Quaternion& quaternion) const { return ::QuaternionAdd(*this, quaternion); }
|
|
|
|
/**
|
|
* Add two quaternions
|
|
*/
|
|
Quaternion operator+(const ::Quaternion& quaternion) const { return ::QuaternionAdd(*this, quaternion); }
|
|
|
|
Quaternion& operator+=(const ::Quaternion& quaternion) {
|
|
set(::QuaternionAdd(*this, quaternion));
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Add quaternion and float value
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Add(const float value) const {
|
|
return ::QuaternionAddValue(*this, value);
|
|
}
|
|
|
|
/**
|
|
* Add quaternion and float value
|
|
*/
|
|
Quaternion operator+(const float value) const {
|
|
return ::QuaternionAddValue(*this, value);
|
|
}
|
|
|
|
/**
|
|
* Add quaternion and float value
|
|
*/
|
|
Quaternion& operator+=(const float value) {
|
|
set(::QuaternionAddValue(*this, value));
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Add quaternion and float value
|
|
*/
|
|
friend Quaternion operator+(const float lhs, const Quaternion& rhs) { return rhs + lhs; }
|
|
|
|
/**
|
|
* Subtract two quaternions.
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Subtract(const ::Quaternion& quaternion) const { return ::QuaternionSubtract(*this, quaternion); }
|
|
|
|
/**
|
|
* Subtract two quaternions.
|
|
*/
|
|
Quaternion operator-(const ::Quaternion& quaternion) const { return ::QuaternionSubtract(*this, quaternion); }
|
|
|
|
Quaternion& operator-=(const ::Quaternion& quaternion) {
|
|
set(::QuaternionSubtract(*this, quaternion));
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Subtract quaternion by float value
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Subtract(const float value) const {
|
|
return ::QuaternionSubtractValue(*this, value);
|
|
}
|
|
|
|
/**
|
|
* Get identity quaternion
|
|
*/
|
|
static RLCPP_NODISCARD Quaternion Identity() {
|
|
return ::QuaternionIdentity();
|
|
}
|
|
|
|
RLCPP_NODISCARD float Length() const { return ::QuaternionLength(*this); }
|
|
|
|
RLCPP_NODISCARD Quaternion Normalize() const { return ::QuaternionNormalize(*this); }
|
|
|
|
RLCPP_NODISCARD Quaternion Invert() const { return ::QuaternionInvert(*this); }
|
|
|
|
/**
|
|
* Multiply quaternion by quaternion
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Multiply(const ::Quaternion& other) const { return ::QuaternionMultiply(*this, other); }
|
|
|
|
/**
|
|
* Multiply quaternion by quaternion
|
|
*/
|
|
Quaternion operator*(const ::Quaternion& other) const { return ::QuaternionMultiply(*this, other); }
|
|
|
|
/**
|
|
* Multiply quaternion by quaternion
|
|
*/
|
|
Quaternion& operator*=(const ::Quaternion& other) {
|
|
set(::QuaternionMultiply(*this, other));
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Scale quaternion components by value (multiply)
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Scale(const float scale) const { return ::QuaternionScale(*this, scale); }
|
|
|
|
/**
|
|
* Divide quaternion by quaternion
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Divide(const ::Quaternion& quaternion) const { return ::QuaternionDivide(*this, quaternion); }
|
|
|
|
/**
|
|
* Divide quaternion by quaternion
|
|
*/
|
|
Quaternion operator/(const ::Quaternion& quaternion) const { return ::QuaternionDivide(*this, quaternion); }
|
|
|
|
/**
|
|
* Divide quaternion by quaternion
|
|
*/
|
|
Quaternion& operator/=(const ::Quaternion& quaternion) {
|
|
set(::QuaternionDivide(*this, quaternion));
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Divide quaternion components by value
|
|
*/
|
|
RLCPP_NODISCARD constexpr Quaternion Divide(const float div) const { return ::Quaternion{x / div, y / div, z / div, w / div}; }
|
|
|
|
RLCPP_NODISCARD Quaternion Lerp(const ::Quaternion& v2, const float amount) const
|
|
{
|
|
return ::QuaternionLerp(*this, v2, amount);
|
|
}
|
|
|
|
/**
|
|
* Calculate normalized linear interpolation between two quaternions
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Nlerp(const ::Quaternion& v2, const float amount) const {
|
|
return ::QuaternionNlerp(*this, v2, amount);
|
|
}
|
|
|
|
/**
|
|
* Calculates spherical linear interpolation between two quaternions
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Slerp(const ::Quaternion& v2, const float amount) const {
|
|
return ::QuaternionSlerp(*this, v2, amount);
|
|
}
|
|
|
|
/**
|
|
* Calculate quaternion cubic spline interpolation using Cubic Hermite Spline
|
|
*/
|
|
RLCPP_NODISCARD Quaternion CubicHermiteSpline(
|
|
const ::Quaternion& outTangent1,
|
|
const ::Quaternion& q2,
|
|
const ::Quaternion& inTangent2,
|
|
const float t
|
|
) const {
|
|
return ::QuaternionCubicHermiteSpline(*this, outTangent1, q2, inTangent2, t);
|
|
}
|
|
|
|
/**
|
|
* Calculate quaternion based on the rotation from one vector to another
|
|
*/
|
|
static RLCPP_NODISCARD Quaternion FromVector3ToVector3(const ::Vector3& from, const ::Vector3& to) {
|
|
return ::QuaternionFromVector3ToVector3(from, to);
|
|
}
|
|
|
|
/**
|
|
* Get a quaternion for a given rotation matrix
|
|
*/
|
|
static RLCPP_NODISCARD Quaternion FromMatrix(const ::Matrix& mat) {
|
|
return ::QuaternionFromMatrix(mat);
|
|
}
|
|
|
|
/**
|
|
* Get a matrix for this quaternion
|
|
*/
|
|
RLCPP_NODISCARD ::Matrix ToMatrix() const {
|
|
return ::QuaternionToMatrix(*this);
|
|
}
|
|
|
|
/**
|
|
* Get rotation quaternion for an angle and axis
|
|
* NOTE: Angle must be provided in radians
|
|
*/
|
|
static RLCPP_NODISCARD Quaternion FromAxisAngle(const ::Vector3& axis, const float angle) {
|
|
return ::QuaternionFromAxisAngle(axis, angle);
|
|
}
|
|
|
|
/**
|
|
* Get the rotation angle and axis for this quaternion
|
|
*/
|
|
void ToAxisAngle(::Vector3* outAxis, float* outAngle) const {
|
|
::QuaternionToAxisAngle(*this, outAxis, outAngle);
|
|
}
|
|
|
|
/**
|
|
* Get the quaternion equivalent to Euler angles
|
|
* NOTE: Rotation order is ZYX
|
|
*/
|
|
static RLCPP_NODISCARD Quaternion FromEuler(const float pitch, const float yaw, const float roll) {
|
|
return ::QuaternionFromEuler(pitch, yaw, roll);
|
|
}
|
|
|
|
/**
|
|
* Get the Euler angles equivalent to quaternion
|
|
* NOTE: Angles are returned in radians
|
|
*/
|
|
RLCPP_NODISCARD ::Vector3 ToEuler() const {
|
|
return ::QuaternionToEuler(*this);
|
|
}
|
|
|
|
/**
|
|
* Transform quaternion given transformation matrix
|
|
*/
|
|
RLCPP_NODISCARD Quaternion Transform(const ::Matrix& mat) const {
|
|
return ::QuaternionTransform(*this, mat);
|
|
}
|
|
|
|
/*
|
|
* Check whether two given quaternions are almost equal
|
|
*/
|
|
RLCPP_NODISCARD bool Equals(const ::Quaternion& other) const {
|
|
return static_cast<bool>(::QuaternionEquals(*this, other));
|
|
}
|
|
#endif
|
|
protected:
|
|
void set(const ::Quaternion& quat) {
|
|
x = quat.x;
|
|
y = quat.y;
|
|
z = quat.z;
|
|
w = quat.w;
|
|
}
|
|
};
|
|
|
|
} // namespace raylib
|
|
|
|
using RQuaternion = raylib::Quaternion;
|
|
|
|
#endif // RAYLIB_CPP_INCLUDE_QUATERNION_HPP_
|
|
|