3#include "egg/math/Math.hh"
4#include "egg/math/Vector.hh"
14 constexpr Quatf() : w(std::numeric_limits<f32>::signaling_NaN()) {}
16 constexpr Quatf() =
default;
20 constexpr Quatf(f32 w_, f32 x_, f32 y_, f32 z_) : v(x_, y_, z_), w(w_) {}
21 constexpr ~Quatf() =
default;
30 [[nodiscard]]
constexpr Quatf operator+(
const Quatf &rhs)
const {
31 return Quatf(w + rhs.w, v + rhs.v);
34 constexpr Quatf &operator+=(
const Quatf &rhs) {
35 return *
this = *
this + rhs;
38 [[nodiscard]]
constexpr Quatf operator*(
const Vector3f &vec)
const {
41 return Quatf(-v.
dot(vec), cross + scale);
44 [[nodiscard]]
constexpr Quatf operator*(f32 scalar)
const {
45 return Quatf(w * scalar, v * scalar);
48 constexpr Quatf &operator*=(f32 scalar) {
49 return *
this = *
this * scalar;
55 f32 _w = w * rhs.w - v.x * rhs.v.x - v.y * rhs.v.y - v.z * rhs.v.z;
56 f32 _x = v.y * rhs.v.z + (v.x * rhs.w + w * rhs.v.x) - v.z * rhs.v.y;
57 f32 _y = v.z * rhs.v.x + (v.y * rhs.w + w * rhs.v.y) - v.x * rhs.v.z;
58 f32 _z = v.x * rhs.v.y + (v.z * rhs.w + w * rhs.v.z) - v.y * rhs.v.x;
60 return Quatf(_w, _x, _y, _z);
64 return *
this = *
this * q;
67 [[nodiscard]]
constexpr bool operator==(
const Quatf &rhs)
const {
68 return w == rhs.w && v == rhs.v;
71 [[nodiscard]]
constexpr bool operator!=(
const Quatf &rhs)
const {
72 return !(*
this == rhs);
76 [[nodiscard]]
explicit operator std::string()
const {
77 return std::format(
"[0x{:08X}, 0x{:08X}, 0x{:08X}, 0x{:08X}] | [{}, {}, {}, {}]", f2u(v.x),
78 f2u(v.y), f2u(v.z), f2u(w), v.x, v.y, v.z, w);
84 *
this = FromRPY(rpy.x, rpy.y, rpy.z);
88 constexpr void setRPY(f32 r, f32 p, f32 y) {
96 w = cy * cp * cr + sy * sp * sr;
97 v.x = cy * cp * sr - sy * sp * cr;
98 v.y = cy * sp * cr + sy * cp * sr;
99 v.z = sy * cp * cr - cy * sp * sr;
105 f32 len =
squaredNorm() > std::numeric_limits<f32>::epsilon() ? norm() : 0.0f;
108 f32 inv = 1.0f / len;
117 f32 t0 = std::max(0.0f, (from.
dot(to) + 1) * 2.0f);
118 t0 = Mathf::sqrt(t0);
120 if (t0 <= std::numeric_limits<f32>::epsilon()) {
121 *
this = Quatf::ident;
123 const f32 inv = 1.0f / t0;
125 v = from.cross(to) * inv;
138 Quatf res = *
this * vec;
141 ret.v.x = (res.v.y * conj.v.z + (res.v.x * conj.w + res.w * conj.v.x)) - res.v.z * conj.v.y;
142 ret.v.y = (res.v.z * conj.v.x + (res.v.y * conj.w + res.w * conj.v.y)) - res.v.x * conj.v.z;
143 ret.v.z = (res.v.x * conj.v.y + (res.v.z * conj.w + res.w * conj.v.z)) - res.v.y * conj.v.x;
152 Quatf res = conj * vec;
155 ret.v.x = (res.v.y * v.z + (res.v.x * w + res.w * v.x)) - res.v.z * v.y;
156 ret.v.y = (res.v.z * v.x + (res.v.y * w + res.w * v.y)) - res.v.x * v.z;
157 ret.v.z = (res.v.x * v.y + (res.v.z * w + res.w * v.z)) - res.v.y * v.x;
166 f32 dot_ = std::max(-1.0f, std::min(1.0f,
dot(q1)));
167 bool bDot = dot_ < 0.0f;
168 dot_ = Mathf::abs(dot_);
170 f32 acos = Mathf::acos(dot_);
174 if (Mathf::abs(
sin) < 0.00001f) {
177 f32 invSin = 1.0f /
sin;
187 return Quatf(s * w + t * q1.w, s * v + t * q1.v);
196 [[nodiscard]]
constexpr f32 norm()
const {
202 [[nodiscard]]
constexpr f32
dot(
const Quatf &q)
const {
203 return w * q.w + v.
dot(q.v);
209 const f32 half_angle = angle * 0.5f;
217 [[nodiscard]]
constexpr Quatf multSwap(
const Vector3f &vec)
const {
218 f32 _w = -(v.
dot(vec));
219 f32 _x = (w * vec.x + v.y * vec.z) - v.z * vec.y;
220 f32 _y = (w * vec.y + v.z * vec.x) - v.x * vec.z;
221 f32 _z = (w * vec.z + v.x * vec.y) - v.y * vec.x;
223 return Quatf(_w, _x, _y, _z);
226 [[nodiscard]]
constexpr Quatf multSwap(
const Quatf &q)
const {
227 f32 _w = ((w * q.w - v.x * q.v.x) - v.y * q.v.y) - v.z * q.v.z;
228 f32 _x = (v.y * q.v.z + (v.x * q.w + w * q.v.x)) - v.z * q.v.y;
229 f32 _y = (v.z * q.v.x + (v.y * q.w + w * q.v.y)) - v.x * q.v.z;
230 f32 _z = (v.x * q.v.y + (v.z * q.w + w * q.v.z)) - v.y * q.v.x;
232 return Quatf(_w, _x, _y, _z);
235 void read(Stream &stream) {
237 w = stream.read_f32();
240 [[nodiscard]]
static constexpr Quatf FromRPY(
const EGG::Vector3f &rpy) {
256 static const Quatf ident;
259inline constexpr Quatf Quatf::ident = Quatf(1.0f, Vector3f::zero);
static constexpr f32 cos(f32 x)
static constexpr f32 sin(f32 x)
A quaternion, used to represent 3D rotation.
constexpr Vector3f rotateVector(const Vector3f &vec) const
Rotates a vector based on the quat.
constexpr void setRPY(const Vector3f &rpy)
Sets roll, pitch, and yaw.
constexpr Quatf conjugate() const
Computes .
constexpr void normalise()
Scales the quaternion to a unit length.
constexpr void makeVectorRotation(const Vector3f &from, const Vector3f &to)
Captures rotation between two vectors.
constexpr f32 dot(const Quatf &q) const
Computes .
constexpr Quatf operator*(const Quatf &rhs) const
constexpr void setRPY(f32 r, f32 p, f32 y)
Helper function to avoid unnecessary Vector3f construction.
constexpr f32 squaredNorm() const
Computes .
constexpr Quatf slerpTo(const Quatf &q1, f32 t) const
Performs spherical linear interpolation.
static constexpr Quatf FromRPY(f32 r, f32 p, f32 y)
Helper function to avoid unnecessary Vector3f construction.
constexpr Vector3f rotateVectorInv(const Vector3f &vec) const
Rotates a vector on the inverse quat.
constexpr void setAxisRotation(f32 angle, const EGG::Vector3f &axis)
Set the quat given angle and axis.
constexpr f32 squaredLength() const
The dot product between the vector and itself.
void read(Stream &stream)
Initializes a Vector3f by reading 12 bytes from the stream.
constexpr f32 dot(const Vector3f &rhs) const
The dot product between two vectors.