From 8dc5ef8f240ec69e6bd4e51a2860c51b6f9a16cf Mon Sep 17 00:00:00 2001 From: Slendi Date: Sun, 11 Jan 2026 09:35:27 +0200 Subject: [PATCH] Add helper Quaternion methods Signed-off-by: Slendi --- include/smath.hpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/smath.hpp b/include/smath.hpp index e472509..5bda624 100644 --- a/include/smath.hpp +++ b/include/smath.hpp @@ -626,6 +626,8 @@ template constexpr auto turns(T value) return static_cast(value); } } +template +requires std::is_arithmetic_v struct Mat; template struct Quaternion : Vec<4, T> { using Base = Vec<4, T>; @@ -660,6 +662,42 @@ template struct Quaternion : Vec<4, T> { return r; } + + [[nodiscard]] constexpr auto as_matrix() const noexcept -> Mat<4, 4, T> + { + auto const xx = x() * x(); + auto const yy = y() * y(); + auto const zz = z() * z(); + auto const xy = x() * y(); + auto const xz = x() * z(); + auto const yz = y() * z(); + auto const wx = w() * x(); + auto const wy = w() * y(); + auto const wz = w() * z(); + + return Mat<4, 4, T> { + Vec<4, T> { 1 - 2 * (yy + zz), 2 * (xy + wz), 2 * (xz - wy), 0 }, + Vec<4, T> { 2 * (xy - wz), 1 - 2 * (xx + zz), 2 * (yz + wx), 0 }, + Vec<4, T> { 2 * (xz + wy), 2 * (yz - wx), 1 - 2 * (xx + yy), 0 }, + Vec<4, T> { 0, 0, 0, 1 }, + }; + } + + [[nodiscard]] static constexpr auto from_axis_angle( + Vec<3, T> const &axis, T const angle) noexcept -> Quaternion + { + auto const normalized_axis { axis.normalized_safe() }; + auto const half_angle { angle / static_cast(2) }; + auto const sine { std::sin(half_angle) }; + auto const cosine { std::cos(half_angle) }; + + return Quaternion { + normalized_axis.x() * sine, + normalized_axis.y() * sine, + normalized_axis.z() * sine, + cosine, + }; + } }; template