7 template <std::
floating_po
int T>
13 template <std::
floating_po
int T>
14 template <std::
floating_po
int U>
19 template <std::
floating_po
int T>
24 template <std::
floating_po
int T>
25 template <std::
floating_po
int U>
27 const U halfPitch = pitch * U{0.5};
28 const U halfYaw = yaw * U{0.5};
29 const U halfRoll = roll * U{0.5};
31 const U sp = std::sin(halfPitch);
32 const U cp = std::cos(halfPitch);
33 const U sy = std::sin(halfYaw);
34 const U cy = std::cos(halfYaw);
35 const U sr = std::sin(halfRoll);
36 const U cr = std::cos(halfRoll);
38 return Quaternion(
static_cast<T
>(sp * cy * cr - cp * sy * sr),
static_cast<T
>(cp * sy * cr + sp * cy * sr),
39 static_cast<T
>(cp * cy * sr - sp * sy * cr),
static_cast<T
>(cp * cy * cr + sp * sy * sr));
42 template <std::
floating_po
int T>
43 template <std::
floating_po
int U>
45 const U halfAngle = angleRadians * U{0.5};
46 const U s = std::sin(halfAngle);
47 const U c = std::cos(halfAngle);
50 const U lengthSquared = normalizedAxis[0] * normalizedAxis[0] + normalizedAxis[1] * normalizedAxis[1] +
51 normalizedAxis[2] * normalizedAxis[2];
53 if (lengthSquared > U{0}) {
54 const U invLength = U{1} / std::sqrt(lengthSquared);
55 normalizedAxis *= invLength;
58 return Quaternion(
static_cast<T
>(normalizedAxis[0] * s),
static_cast<T
>(normalizedAxis[1] * s),
59 static_cast<T
>(normalizedAxis[2] * s),
static_cast<T
>(c));
62 template <std::
floating_po
int T>
67 template <std::
floating_po
int T>
72 template <std::
floating_po
int T>
77 template <std::
floating_po
int T>
82 template <std::
floating_po
int T>
87 template <std::
floating_po
int T>
92 template <std::
floating_po
int T>
97 template <std::
floating_po
int T>
102 template <std::
floating_po
int T>
107 template <std::
floating_po
int T>
112 template <std::
floating_po
int T>
117 template <std::
floating_po
int T>
118 template <std::
floating_po
int U>
120 return m_x == other.
X() && m_y == other.
Y() && m_z == other.
Z() && m_w == other.
W();
123 template <std::
floating_po
int T>
124 template <std::
floating_po
int U>
126 m_x +=
static_cast<T
>(other.
X());
127 m_y +=
static_cast<T
>(other.
Y());
128 m_z +=
static_cast<T
>(other.
Z());
129 m_w +=
static_cast<T
>(other.
W());
134 template <std::
floating_po
int T>
135 template <std::
floating_po
int U>
137 m_x -=
static_cast<T
>(other.
X());
138 m_y -=
static_cast<T
>(other.
Y());
139 m_z -=
static_cast<T
>(other.
Z());
140 m_w -=
static_cast<T
>(other.
W());
145 template <std::
floating_po
int T>
146 template <std::
floating_po
int U>
148 const T x = m_w *
static_cast<T
>(other.
X()) + m_x *
static_cast<T
>(other.
W()) +
149 m_y *
static_cast<T
>(other.
Z()) - m_z *
static_cast<T
>(other.
Y());
150 const T y = m_w *
static_cast<T
>(other.
Y()) - m_x *
static_cast<T
>(other.
Z()) +
151 m_y *
static_cast<T
>(other.
W()) + m_z *
static_cast<T
>(other.
X());
152 const T z = m_w *
static_cast<T
>(other.
Z()) + m_x *
static_cast<T
>(other.
Y()) -
153 m_y *
static_cast<T
>(other.
X()) + m_z *
static_cast<T
>(other.
W());
154 const T w = m_w *
static_cast<T
>(other.
W()) - m_x *
static_cast<T
>(other.
X()) -
155 m_y *
static_cast<T
>(other.
Y()) - m_z *
static_cast<T
>(other.
Z());
165 template <std::
floating_po
int T>
166 template <std::
floating_po
int U>
168 m_x *=
static_cast<T
>(scalar);
169 m_y *=
static_cast<T
>(scalar);
170 m_z *=
static_cast<T
>(scalar);
171 m_w *=
static_cast<T
>(scalar);
176 template <std::
floating_po
int T>
177 template <std::
floating_po
int U>
179 m_x /=
static_cast<T
>(scalar);
180 m_y /=
static_cast<T
>(scalar);
181 m_z /=
static_cast<T
>(scalar);
182 m_w /=
static_cast<T
>(scalar);
187 template <std::
floating_po
int T>
192 template <std::
floating_po
int T>
197 template <std::
floating_po
int T>
199 return m_x * m_x + m_y * m_y + m_z * m_z + m_w * m_w;
202 template <std::
floating_po
int T>
207 template <std::
floating_po
int T>
209 const T length =
Length();
211 if (length <= T{0}) {
215 const T invLength = T{1} / length;
216 return Quaternion(m_x * invLength, m_y * invLength, m_z * invLength, m_w * invLength);
219 template <std::
floating_po
int T>
224 template <std::
floating_po
int T>
229 template <std::
floating_po
int T>
233 if (lengthSquared <= T{0}) {
240 template <std::
floating_po
int T>
242 const Vec3<T> q{m_x, m_y, m_z};
244 const Vec3<T> cross1{q[1] * v[2] - q[2] * v[1], q[2] * v[0] - q[0] * v[2], q[0] * v[1] - q[1] * v[0]};
246 const Vec3<T> cross2{q[1] * cross1[2] - q[2] * cross1[1], q[2] * cross1[0] - q[0] * cross1[2],
247 q[0] * cross1[1] - q[1] * cross1[0]};
249 return v + (cross1 * (T{2} * m_w)) + (cross2 * T{2});
252 template <std::
floating_po
int T>
257 template <std::
floating_po
int T>
259 const T sinPitch = T{2} * (m_w * m_x + m_y * m_z);
260 const T cosPitch = T{1} - T{2} * (m_x * m_x + m_y * m_y);
262 return std::atan2(sinPitch, cosPitch);
265 template <std::
floating_po
int T>
267 const T sinYaw = T{2} * (m_w * m_y - m_z * m_x);
269 if (std::abs(sinYaw) >= T{1}) {
270 return std::copysign(std::numbers::pi_v<T> / T{2}, sinYaw);
273 return std::asin(sinYaw);
276 template <std::
floating_po
int T>
278 const T sinRoll = T{2} * (m_w * m_z + m_x * m_y);
279 const T cosRoll = T{1} - T{2} * (m_y * m_y + m_z * m_z);
281 return std::atan2(sinRoll, cosRoll);
284 template <std::
floating_po
int T, std::
floating_po
int U>
286 using R = std::common_type_t<T, U>;
289 static_cast<R
>(a.X()) +
static_cast<R
>(b.X()),
static_cast<R
>(a.Y()) +
static_cast<R
>(b.Y()),
290 static_cast<R
>(a.Z()) +
static_cast<R
>(b.Z()),
static_cast<R
>(a.W()) +
static_cast<R
>(b.W()));
293 template <std::
floating_po
int T, std::
floating_po
int U>
295 using R = std::common_type_t<T, U>;
298 static_cast<R
>(a.X()) -
static_cast<R
>(b.X()),
static_cast<R
>(a.Y()) -
static_cast<R
>(b.Y()),
299 static_cast<R
>(a.Z()) -
static_cast<R
>(b.Z()),
static_cast<R
>(a.W()) -
static_cast<R
>(b.W()));
302 template <std::
floating_po
int T, std::
floating_po
int U>
304 using R = std::common_type_t<T, U>;
307 static_cast<R
>(a.W()));
310 static_cast<R
>(b.W()));
315 template <std::
floating_po
int T, std::
floating_po
int U>
317 using R = std::common_type_t<T, U>;
320 static_cast<R
>(q.X()) *
static_cast<R
>(scalar),
static_cast<R
>(q.Y()) *
static_cast<R
>(scalar),
321 static_cast<R
>(q.Z()) *
static_cast<R
>(scalar),
static_cast<R
>(q.W()) *
static_cast<R
>(scalar));
324 template <std::
floating_po
int T, std::
floating_po
int U>
329 template <std::
floating_po
int T, std::
floating_po
int U>
331 using R = std::common_type_t<T, U>;
334 static_cast<R
>(q.X()) /
static_cast<R
>(scalar),
static_cast<R
>(q.Y()) /
static_cast<R
>(scalar),
335 static_cast<R
>(q.Z()) /
static_cast<R
>(scalar),
static_cast<R
>(q.W()) /
static_cast<R
>(scalar));
338 template <std::
floating_po
int T, std::
floating_po
int U>
340 using R = std::common_type_t<T, U>;
342 const Quaternion<R> qr(
static_cast<R
>(q.X()),
static_cast<R
>(q.Y()),
static_cast<R
>(q.Z()),
343 static_cast<R
>(q.W()));
344 const Vec3<R> vr{
static_cast<R
>(v[0]),
static_cast<R
>(v[1]),
static_cast<R
>(v[2])};
349 template <std::
floating_po
int T>
351 return a.
X() * b.
X() + a.
Y() * b.
Y() + a.
Z() * b.
Z() + a.
W() * b.
W();
354 template <std::
floating_po
int T>
356 return (a * (T{1} - t) + b * t).Normalized();
359 template <std::
floating_po
int T>
362 T cosOmega =
Dot(a, b);
364 if (cosOmega < T{0}) {
365 cosOmega = -cosOmega;
369 constexpr T kEpsilon =
static_cast<T
>(1e-6);
371 if (cosOmega > T{1} - kEpsilon) {
372 return Lerp(a, end, t);
375 const T omega = std::acos(cosOmega);
376 const T sinOmega = std::sin(omega);
378 const T scaleA = std::sin((T{1} - t) * omega) / sinOmega;
379 const T scaleB = std::sin(t * omega) / sinOmega;
381 return (a * scaleA) + (end * scaleB);
386template <std::
floating_po
int T>
387struct std::formatter<
Nexus::Quaternion<T>> {
390 constexpr auto parse(std::format_parse_context& ctx) {
395 auto out = ctx.out();
396 out = std::format_to(out,
"(");
398 out = std::format_to(out,
", ");
400 out = std::format_to(out,
", ");
402 out = std::format_to(out,
", ");
404 return std::format_to(out,
")");
Definition Quaternion.cppm:18
static constexpr Quaternion FromAxisAngle(const Vec3< U > &axis, U angleRadians)
constexpr Quaternion()=default
constexpr T & Y()
Definition Quaternion.inl:73
constexpr T Yaw() const
Definition Quaternion.inl:266
constexpr Vec3< T > ToEuler() const
Definition Quaternion.inl:253
constexpr T & X()
Definition Quaternion.inl:63
constexpr Quaternion & operator*=(const Quaternion< U > &other)
constexpr void Normalize()
Definition Quaternion.inl:220
constexpr T & Z()
Definition Quaternion.inl:83
constexpr Quaternion Normalized() const
Definition Quaternion.inl:208
constexpr Quaternion Inverse() const
Definition Quaternion.inl:230
constexpr Quaternion operator+() const
Definition Quaternion.inl:188
constexpr T * Data()
Definition Quaternion.inl:103
constexpr T LengthSquared() const
Definition Quaternion.inl:198
constexpr Quaternion Conjugate() const
Definition Quaternion.inl:225
constexpr Quaternion & operator+=(const Quaternion< U > &other)
constexpr T Roll() const
Definition Quaternion.inl:277
static constexpr Quaternion Identity()
Definition Quaternion.inl:20
constexpr T Pitch() const
Definition Quaternion.inl:258
constexpr T & W()
Definition Quaternion.inl:93
constexpr Quaternion operator-() const
Definition Quaternion.inl:193
constexpr Vec3< T > RotateVector(const Vec3< T > &v) const
Definition Quaternion.inl:241
constexpr Quaternion & operator-=(const Quaternion< U > &other)
static constexpr size_type Size()
Definition Quaternion.inl:113
constexpr T Length() const
Definition Quaternion.inl:203
static constexpr Quaternion FromEuler(U pitch, U yaw, U roll)
constexpr bool operator==(const Quaternion< U > &other) const
Definition Quaternion.inl:119
constexpr Quaternion & operator/=(U scalar)
Definition Config.cppm:11
Vec< T, 3 > Vec3
Definition Vec.cppm:93
constexpr auto operator+(const Mat< T, RowCount, ColCount, Layout > &a, const Mat< U, RowCount, ColCount, Layout > &b) -> MatCommon< T, U, RowCount, ColCount, Layout >
Definition Mat.inl:289
std::size_t usize
Definition Types.cppm:25
constexpr auto operator*(const Mat< T, RowCount, ColCount, Layout > &mat, U scalar) -> MatCommon< T, U, RowCount, ColCount, Layout >
Definition Mat.inl:321
constexpr T Dot(const Quaternion< T > &a, const Quaternion< T > &b)
Definition Quaternion.inl:350
constexpr auto operator/(const Mat< T, RowCount, ColCount, Layout > &mat, U scalar) -> MatCommon< T, U, RowCount, ColCount, Layout >
Definition Mat.inl:343
constexpr auto operator-(const Mat< T, RowCount, ColCount, Layout > &a, const Mat< U, RowCount, ColCount, Layout > &b) -> MatCommon< T, U, RowCount, ColCount, Layout >
Definition Mat.inl:305
constexpr Quaternion< T > Lerp(const Quaternion< T > &a, const Quaternion< T > &b, T t)
Definition Quaternion.inl:355
constexpr Quaternion< T > Slerp(const Quaternion< T > &a, const Quaternion< T > &b, T t)
Definition Quaternion.inl:360
Quaternion< std::common_type_t< T, U > > QuaternionCommon
Definition Quaternion.cppm:102