SH4ZAM! 0.1.0
Fast math library for the Sega Dreamcast's SH4 CPU
Loading...
Searching...
No Matches
shz_quat.hpp
Go to the documentation of this file.
1/*! \file
2 \brief C++ routines for operating upon quaternions.
3 \ingroup quat
4
5 \todo
6 - overload arithmetic operators
7
8 \author 2025 Falco Girgis
9 \copyright MIT License
10*/
11
12#ifndef SHZ_QUAT_HPP
13#define SHZ_QUAT_HPP
14
15#include <compare>
16#include <tuple>
17
18#include "shz_quat.h"
19#include "shz_vector.hpp"
20
21namespace shz {
22
23 /*! C++ structure representing a quaternion.
24
25 A quaternion represents a rotation about an arbitrary axis in 3D space.
26
27 \warning
28 The SH4ZAM internal quaternion representatino puts the W or angle component
29 first, followed by the X, Y, Z components for the axis!
30
31 \note
32 shz::quat is the C++ extension of shz_quat_t, which adds member functions,
33 convenience operators, and still retains backwards compatibility with the
34 C API.
35
36 \sa shz_quat_t, shz::mat4x4, shz::vec3
37 */
38 struct quat: public shz_quat_t {
39 //! Minimum epsilon for bothering to interpolate in shz::quat::slerp().
41
42 //! Default constructor: does nothing.
43 quat() noexcept = default;
44
45 //! Value constructor: initializes a quaternion with the given values for each component.
46 SHZ_FORCE_INLINE quat(float w, float x, float y, float z) noexcept:
47 shz_quat_t({w, x, y, z}) {}
48
49 //! C Converting constructor: constructs a C++ shz::quat from a C shz_quat_t.
50 SHZ_FORCE_INLINE quat(shz_quat_t q) noexcept:
51 shz_quat_t(q) {}
52
53 //! Returns an identity quaternion.
54 SHZ_FORCE_INLINE static quat identity() noexcept {
56 }
57
58 //! C++ convenience wrapper for shz_quat_From_angles_xyz().
59 SHZ_FORCE_INLINE static quat from_angles_xyz(float x, float y, float z) noexcept {
61 }
62
63 //! initializes a quaternion which is a rotation in \p angle degrees about the given \p axis.
64 SHZ_FORCE_INLINE static quat from_axis_angle(vec3 axis, float angle) noexcept {
65 return shz_quat_from_axis_angle(axis, angle);
66 }
67
68 //! Creates a quaternion looking in the given direction with the given reference direction.
69 SHZ_FORCE_INLINE static quat from_look_axis(vec3 forward, vec3 up) noexcept {
70 return shz_quat_from_look_axis(forward, up);
71 }
72
73 //! Returns the quaternion representing the rotation from the \p start to the \p end axes.
74 SHZ_FORCE_INLINE static quat from_rotated_axis(vec3 start, vec3 end) noexcept {
75 return shz_quat_from_rotated_axis(start, end);
76 }
77
78 //! Returns the quaternion that is linearly interpolating \p q to \p p, by a t factor of `0.0f-1.0f`.
79 SHZ_FORCE_INLINE static quat lerp(quat q, quat p, float t) noexcept {
80 return shz_quat_lerp(q, p, t);
81 }
82
83 //! Equivalent to lerp(), except that the resulting quaternion is normalized.
84 SHZ_FORCE_INLINE static quat nlerp(quat q, quat p, float t) noexcept {
85 return shz_quat_nlerp(q, p, t);
86 }
87
88 /*! Returns the quaternion that is spherically linearly interpolating \p q to \p p, by a \p t factor of `0.0f-1.0f`.
89
90 \warning The returned quaternion is not guaranteed to be normalized due to floating-point error.
91 Callers should normalize the result before reuse, especially when performing repeated interpolations.
92 */
93 SHZ_FORCE_INLINE static quat slerp(quat q, quat p, float t) noexcept {
94 return shz_quat_slerp(q, p, t);
95 }
96
97#ifdef SHZ_CPP23
98 //! Overloaded subscript operator for indexing into the quaternion like an array.
99 SHZ_FORCE_INLINE auto&& operator[](this auto&& self, size_t index) noexcept {
100 return std::forward<decltype(self)>(self).e[index];
101 }
102
103 //! Returns an iterator to the first element within the quaternion -- For STL support.
104 SHZ_FORCE_INLINE auto begin(this auto&& self) noexcept {
105 return &self[0];
106 }
107
108 //! Returns an iterator to the end of the quaternion -- For STL support.
109 SHZ_FORCE_INLINE auto end(this auto&& self) noexcept {
110 return &self[4];
111 }
112
113 //! Overloaded space-ship operator for auto-generating lexicographical comparison operators.
114 friend auto operator<=>(quat lhs, quat rhs) noexcept {
116 rhs.begin(), rhs.end());
117 }
118
119 //! Returns true if \p lhs is lexicographically less than \p rhs.
120 friend auto operator<(quat lhs, quat rhs) noexcept {
122 }
123#endif
124 //! Overloaded comparison operator, checks for quaternion equality.
125 friend auto operator==(quat lhs, quat rhs) noexcept {
126 return shz_quat_equal(lhs, rhs);
127 }
128
129 //! Returns the angle of rotation represented by the given quaternion.
130 SHZ_FORCE_INLINE float angle() const noexcept {
131 return shz_quat_angle(*this);
132 }
133
134 //! Returns the axis of rotation represented by the given quaternion.
135 SHZ_FORCE_INLINE vec3 axis() const noexcept {
136 return shz_quat_axis(*this);
137 }
138
139 //! Returns the angle of rotation about the X axis represented by the given quaternion.
140 SHZ_FORCE_INLINE float angle_x() const noexcept {
141 return shz_quat_angle_x(*this);
142 }
143
144 //! Returns the angle of rotation about the Y axis represented by the given quaternion.
145 SHZ_FORCE_INLINE float angle_y() const noexcept {
146 return shz_quat_angle_y(*this);
147 }
148
149 //! Returns the angle of rotation about the Z axis represented by the given quaternion.
150 SHZ_FORCE_INLINE float angle_z() const noexcept {
151 return shz_quat_angle_z(*this);
152 }
153
154 SHZ_FORCE_INLINE vec3 to_angles_xyz() const noexcept {
155 return shz_quat_to_angles_xyz(*this);
156 }
157
158 //! Returns both the axis and angle of rotation through the pointer arguments.
159 SHZ_FORCE_INLINE void to_axis_angle(shz_vec3_t* axis, float* angle) const noexcept {
160 shz_quat_to_axis_angle(*this, axis, angle);
161 }
162
163 //! Returns both the axis and angle of rotation as a std::pair.
164 SHZ_FORCE_INLINE auto to_axis_angle() const noexcept -> std::pair<vec3, float> {
165 std::pair<vec3, float> aa;
166 shz_quat_to_axis_angle(*this, &std::get<0>(aa), &std::get<1>(aa));
167 return aa;
168 }
169
170 //! Returns the magnitude of the quaternion squared.
171 SHZ_FORCE_INLINE float magnitude_sqr() const noexcept {
172 return shz_quat_magnitude_sqr(*this);
173 }
174
175 //! Returns the magnitude of the quaternion.
176 SHZ_FORCE_INLINE float magnitude() const noexcept {
177 return shz_quat_magnitude(*this);
178 }
179
180 //! Returns the inverse of the magnitude of the quaternion.
181 SHZ_FORCE_INLINE float magnitude_inv() const noexcept {
182 return shz_quat_magnitude_inv(*this);
183 }
184
185 //! Normalizes the given quaternion.
186 SHZ_FORCE_INLINE void normalize() noexcept {
187 *this = shz_quat_normalize(*this);
188 }
189
190 //! Returns the given quaternion as a unit quaternion.
191 SHZ_FORCE_INLINE quat normalized() const noexcept {
192 return shz_quat_normalize(*this);
193 }
194
195 //! Safely normalizes the given quaternion by protecting against division-by-zero.
196 SHZ_FORCE_INLINE void normalize_safe() noexcept {
197 *this = shz_quat_normalize_safe(*this);
198 }
199
200 //! Returns a safely normalized quaternion from the given quaternion, protecting against division-by-zero.
201 SHZ_FORCE_INLINE quat normalized_safe() const noexcept {
202 return shz_quat_normalize_safe(*this);
203 }
204
205 //! Conjugates the given quaternion.
206 SHZ_FORCE_INLINE void conjugate() noexcept {
207 *this = shz_quat_conjugate(*this);
208 }
209
210 //! Returns a quaternion that is the conjugate of the given quaternion.
211 SHZ_FORCE_INLINE quat conjugated() const noexcept {
212 return shz_quat_conjugate(*this);
213 }
214
215 //! Inverts the given quaternion.
216 SHZ_FORCE_INLINE void invert() noexcept {
217 *this = shz_quat_inv(*this);
218 }
219
220 //! Returns the inverse of the given quaternion.
221 SHZ_FORCE_INLINE quat inverse() const noexcept {
222 return shz_quat_inv(*this);
223 }
224
225 //! Returns a new quaternion from adding the given quaterion to \p rhs.
226 SHZ_FORCE_INLINE quat add(quat rhs) const noexcept {
227 return shz_quat_add(*this, rhs);
228 }
229
230 //! Returns a new quaternion from scaling the given quaterion by \p s.
231 SHZ_FORCE_INLINE quat scale(float s) const noexcept {
232 return shz_quat_scale(*this, s);
233 }
234
235 //! Returns the dot product between the given quaternion and another.
236 SHZ_FORCE_INLINE float dot(quat other) const noexcept {
237 return shz_quat_dot(*this, other);
238 }
239
240 //! Returns the dot product of the given quaternion against two others.
241 SHZ_FORCE_INLINE vec2 dot(quat q1, quat q2) const noexcept {
242 return shz_quat_dot2(*this, q1, q2);
243 }
244
245 //! Returns the dot product of the given quaternion against three others.
246 SHZ_FORCE_INLINE vec3 dot(quat q1, quat q2, quat q3) const noexcept {
247 return shz_quat_dot3(*this, q1, q2, q3);
248 }
249
250 //! Returns a new quaterion from multiplying the given quaternion by another.
251 SHZ_FORCE_INLINE quat mult(quat rhs) const noexcept {
252 return shz_quat_mult(*this, rhs);
253 }
254
255 //! Returns a new shz::vec3 from transforming \p in by the given quaternion.
256 SHZ_FORCE_INLINE vec3 transform(vec3 in) const noexcept {
257 return shz_quat_transform_vec3(*this, in);
258 }
259 };
260
261 //! Alternate C++ alias for quat, for those who like POSIX style.
262 using quat_t = quat;
263}
264
265#endif
Namespace enclosing the SH4ZAM C++ API.
Definition shz_cdefs.hpp:21
float shz_quat_magnitude_sqr(shz_quat_t quat) SHZ_NOEXCEPT
Returns the squared magnitude of the given quaternion.
float shz_quat_magnitude(shz_quat_t quat) SHZ_NOEXCEPT
Returns the magnitude of the given quaternion.
shz_vec3_t shz_quat_axis(shz_quat_t q) SHZ_NOEXCEPT
Returns the axis of rotation from the given quaternion.
shz_quat_t shz_quat_inv(shz_quat_t quat) SHZ_NOEXCEPT
Returns the inverse of the given quaternion.
shz_quat_t shz_quat_nlerp(shz_quat_t a, shz_quat_t b, float t) SHZ_NOEXCEPT
Equivalent to shz_quat_lerp(), except that the resulting quaternion is normalized.
shz_quat_t shz_quat_scale(shz_quat_t q, float f) SHZ_NOEXCEPT
Scales the components of the given quaternion by the given factor.
bool shz_quat_equal(shz_quat_t a, shz_quat_t b) SHZ_NOEXCEPT
Returns true if the two given quaternions are considered equal based on either absolute or relative t...
#define SHZ_QUAT_SLERP_PHI_EPSILON
Minimum epsilon below which shz_quat_slerp() performs no interpolation.
Definition shz_quat.h:30
shz_quat_t shz_quat_add(shz_quat_t q, shz_quat_t p) SHZ_NOEXCEPT
Returns the quaternion produced from adding each component of the given quaternions.
float shz_quat_magnitude_inv(shz_quat_t quat) SHZ_NOEXCEPT
Returns the inverse magnitude of the given quaternion.
float shz_quat_angle(shz_quat_t q) SHZ_NOEXCEPT
Returns the angle of rotation from the given quaternion.
shz_quat_t shz_quat_slerp(shz_quat_t q, shz_quat_t p, float t) SHZ_NOEXCEPT
Returns the quaternion that is spherically linearly interpolating a to b, by a t factor of 0....
shz_quat_t shz_quat_normalize_safe(shz_quat_t quat) SHZ_NOEXCEPT
SAFELY returns the normalized form of the given quaternion.
shz_quat_t shz_quat_lerp(shz_quat_t a, shz_quat_t b, float t) SHZ_NOEXCEPT
Returns the quaternion that is linearly interpolating a to b, by a t factor of 0.0f-1....
shz_vec3_t shz_quat_to_angles_xyz(shz_quat_t q) SHZ_NOEXCEPT
Returns the roll, pitch, and yaw angles of rotation represented by the given quaternion.
shz_vec2_t shz_quat_dot2(shz_quat_t l, shz_quat_t r1, shz_quat_t r2) SHZ_NOEXCEPT
Returns the two dot products taken between the l quaternion and the r1 and r2 quaternions.
shz_quat_t shz_quat_normalize(shz_quat_t quat) SHZ_NOEXCEPT
Returns the normalized form of the given quaternion.
float shz_quat_dot(shz_quat_t q1, shz_quat_t q2) SHZ_NOEXCEPT
Returns the dot product of the two quaternions.
shz_quat_t shz_quat_identity(void) SHZ_NOEXCEPT
Initializes and returns an identity quaternion.
void shz_quat_to_axis_angle(shz_quat_t q, shz_vec3_t *vec, float *angle) SHZ_NOEXCEPT
Returns both the axis and angle of rotation simultaneously (faster if both are needed) from the given...
shz_vec3_t shz_quat_dot3(shz_quat_t l, shz_quat_t r1, shz_quat_t r2, shz_quat_t r3) SHZ_NOEXCEPT
Returns the two dot products taken between the l quaternion and the r1, r2, and r3 quaternions.
shz_quat_t shz_quat_from_angles_xyz(float xangle, float yangle, float zangle) SHZ_NOEXCEPT
Initializes and returns a quaternion with the given X-Y-Z rotations in radians.
shz_quat_t shz_quat_conjugate(shz_quat_t quat) SHZ_NOEXCEPT
Returns the conjugate of the given quaternion.
shz_quat_t shz_quat_mult(shz_quat_t q1, shz_quat_t q2) SHZ_NOEXCEPT
Multiplies the two quaternions, returning the result as a new quaternion.
C++ structure representing a quaternion.
Definition shz_quat.hpp:38
static quat nlerp(quat q, quat p, float t) noexcept
Equivalent to lerp(), except that the resulting quaternion is normalized.
Definition shz_quat.hpp:84
float angle() const noexcept
Returns the angle of rotation represented by the given quaternion.
Definition shz_quat.hpp:130
static quat identity() noexcept
Returns an identity quaternion.
Definition shz_quat.hpp:54
quat normalized_safe() const noexcept
Returns a safely normalized quaternion from the given quaternion, protecting against division-by-zero...
Definition shz_quat.hpp:201
quat scale(float s) const noexcept
Returns a new quaternion from scaling the given quaterion by s.
Definition shz_quat.hpp:231
quat mult(quat rhs) const noexcept
Returns a new quaterion from multiplying the given quaternion by another.
Definition shz_quat.hpp:251
quat(shz_quat_t q) noexcept
C Converting constructor: constructs a C++ shz::quat from a C shz_quat_t.
Definition shz_quat.hpp:50
quat add(quat rhs) const noexcept
Returns a new quaternion from adding the given quaterion to rhs.
Definition shz_quat.hpp:226
vec3 axis() const noexcept
Returns the axis of rotation represented by the given quaternion.
Definition shz_quat.hpp:135
float magnitude_inv() const noexcept
Returns the inverse of the magnitude of the quaternion.
Definition shz_quat.hpp:181
static quat from_rotated_axis(vec3 start, vec3 end) noexcept
Returns the quaternion representing the rotation from the start to the end axes.
Definition shz_quat.hpp:74
vec3 transform(vec3 in) const noexcept
Returns a new shz::vec3 from transforming in by the given quaternion.
Definition shz_quat.hpp:256
auto to_axis_angle() const noexcept -> std::pair< vec3, float >
Returns both the axis and angle of rotation as a std::pair.
Definition shz_quat.hpp:164
void conjugate() noexcept
Conjugates the given quaternion.
Definition shz_quat.hpp:206
static constexpr float slerp_phi_epsilon
Minimum epsilon for bothering to interpolate in shz::quat::slerp().
Definition shz_quat.hpp:40
float dot(quat other) const noexcept
Returns the dot product between the given quaternion and another.
Definition shz_quat.hpp:236
static quat from_axis_angle(vec3 axis, float angle) noexcept
initializes a quaternion which is a rotation in angle degrees about the given axis.
Definition shz_quat.hpp:64
float angle_y() const noexcept
Returns the angle of rotation about the Y axis represented by the given quaternion.
Definition shz_quat.hpp:145
static quat slerp(quat q, quat p, float t) noexcept
Returns the quaternion that is spherically linearly interpolating q to p, by a t factor of 0....
Definition shz_quat.hpp:93
vec3 dot(quat q1, quat q2, quat q3) const noexcept
Returns the dot product of the given quaternion against three others.
Definition shz_quat.hpp:246
void invert() noexcept
Inverts the given quaternion.
Definition shz_quat.hpp:216
void normalize() noexcept
Normalizes the given quaternion.
Definition shz_quat.hpp:186
quat conjugated() const noexcept
Returns a quaternion that is the conjugate of the given quaternion.
Definition shz_quat.hpp:211
static quat lerp(quat q, quat p, float t) noexcept
Returns the quaternion that is linearly interpolating q to p, by a t factor of 0.0f-1....
Definition shz_quat.hpp:79
float magnitude() const noexcept
Returns the magnitude of the quaternion.
Definition shz_quat.hpp:176
quat() noexcept=default
Default constructor: does nothing.
quat normalized() const noexcept
Returns the given quaternion as a unit quaternion.
Definition shz_quat.hpp:191
friend auto operator==(quat lhs, quat rhs) noexcept
Overloaded comparison operator, checks for quaternion equality.
Definition shz_quat.hpp:125
float angle_x() const noexcept
Returns the angle of rotation about the X axis represented by the given quaternion.
Definition shz_quat.hpp:140
float magnitude_sqr() const noexcept
Returns the magnitude of the quaternion squared.
Definition shz_quat.hpp:171
static quat from_angles_xyz(float x, float y, float z) noexcept
C++ convenience wrapper for shz_quat_From_angles_xyz().
Definition shz_quat.hpp:59
quat inverse() const noexcept
Returns the inverse of the given quaternion.
Definition shz_quat.hpp:221
quat(float w, float x, float y, float z) noexcept
Value constructor: initializes a quaternion with the given values for each component.
Definition shz_quat.hpp:46
void normalize_safe() noexcept
Safely normalizes the given quaternion by protecting against division-by-zero.
Definition shz_quat.hpp:196
static quat from_look_axis(vec3 forward, vec3 up) noexcept
Creates a quaternion looking in the given direction with the given reference direction.
Definition shz_quat.hpp:69
void to_axis_angle(shz_vec3_t *axis, float *angle) const noexcept
Returns both the axis and angle of rotation through the pointer arguments.
Definition shz_quat.hpp:159
vec2 dot(quat q1, quat q2) const noexcept
Returns the dot product of the given quaternion against two others.
Definition shz_quat.hpp:241
float angle_z() const noexcept
Returns the angle of rotation about the Z axis represented by the given quaternion.
Definition shz_quat.hpp:150
2D Vector type
3D Vector type