Files
polypartiCL/include/Quaternion.hpp
T
Alex Lardner d7890c9808 init commit
2026-07-04 19:08:19 -07:00

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_