1#ifndef LIBSBX_MATH_QUATERNION_HPP_
2#define LIBSBX_MATH_QUATERNION_HPP_
9#include <yaml-cpp/yaml.h>
11#include <fmt/format.h>
13#include <libsbx/math/concepts.hpp>
14#include <libsbx/math/constants.hpp>
15#include <libsbx/math/algorithm.hpp>
16#include <libsbx/math/vector3.hpp>
17#include <libsbx/math/vector4.hpp>
18#include <libsbx/math/matrix4x4.hpp>
19#include <libsbx/math/angle.hpp>
23template<
floating_po
int Type>
26 template<
floating_po
int Other>
29 template<
floating_po
int Other>
32 template<
floating_po
int Other>
35 template<
floating_po
int Other>
40 using value_type = Type;
41 using reference = value_type&;
42 using const_reference =
const value_type&;
43 using size_type = std::size_t;
44 using length_type = std::float_t;
49 inline static constexpr basic_quaternion identity{vector_type::zero, value_type{1}};
51 template<
floating_po
int Other = value_type>
54 template<
floating_po
int Complex = value_type,
floating_po
int Scalar = value_type>
57 template<
floating_po
int Other = value_type>
60 template<
floating_po
int Other = value_type>
63 template<
floating_po
int Complex = value_type,
floating_po
int Scalar = value_type>
66 template<
floating_po
int Other = value_type>
69 template<
floating_po
int Other = value_type>
70 [[nodiscard]]
static constexpr auto wxyz(Other w, Other x, Other y, Other z)
noexcept ->
basic_quaternion {
77 if(length <=
static_cast<value_type
>(0)) {
78 return basic_quaternion{
static_cast<value_type
>(0),
static_cast<value_type
>(0),
static_cast<value_type
>(0),
static_cast<value_type
>(1)};
81 const auto one_over_length =
static_cast<value_type
>(1) / length;
86 return lhs.x() * rhs.x() + lhs.y() * rhs.y() + lhs.z() * rhs.z() + lhs.w() * rhs.w();
90 return start * (1.0f - t) + end * t;
103 utility::assert_that(a >= 0.0f && a <= 1.0f,
"Interpolation factor out of bounds in quaternion slerp");
107 auto cos_theta = dot(x, y);
111 if(cos_theta <
static_cast<value_type
>(0)) {
113 cos_theta = -cos_theta;
117 if(cos_theta >
static_cast<value_type
>(1) - math::epsilon_v<value_type>) {
119 return basic_quaternion::wxyz(
120 math::mix(x.w(), z.w(), a),
121 math::mix(x.x(), z.x(), a),
122 math::mix(x.y(), z.y(), a),
123 math::mix(x.z(), z.z(), a)
127 const auto angle = std::acos(cos_theta);
128 return (std::sin((
static_cast<value_type
>(1) - a) *
angle) * x + std::sin(a *
angle) * z) / std::sin(
angle);
132 [[nodiscard]]
constexpr operator matrix_type() const noexcept;
134 [[nodiscard]] constexpr auto to_matrix() const noexcept -> matrix_type;
136 template<floating_point Other = value_type>
139 template<floating_point Other = value_type>
142 template<floating_point Other = value_type>
145 template<floating_point Other = value_type>
148 template<floating_point Other = value_type>
151 [[nodiscard]] constexpr auto x() noexcept -> reference;
153 [[nodiscard]] constexpr auto x() const noexcept -> const_reference;
155 [[nodiscard]] constexpr auto y() noexcept -> reference;
157 [[nodiscard]] constexpr auto y() const noexcept -> const_reference;
159 [[nodiscard]] constexpr auto z() noexcept -> reference;
161 [[nodiscard]] constexpr auto z() const noexcept -> const_reference;
163 [[nodiscard]] constexpr auto w() noexcept -> reference;
165 [[nodiscard]] constexpr auto w() const noexcept -> const_reference;
167 [[nodiscard]] constexpr auto complex() noexcept -> vector_type&;
169 [[nodiscard]] constexpr auto complex() const noexcept -> const vector_type&;
171 [[nodiscard]] constexpr auto scalar() noexcept -> reference;
173 [[nodiscard]] constexpr auto scalar() const noexcept -> const_reference;
175 [[nodiscard]] constexpr auto length_squared() const noexcept -> length_type;
177 [[nodiscard]] constexpr auto length() const noexcept -> length_type;
183 vector_type _complex;
188template<floating_point Lhs, floating_point Rhs>
191template<floating_point Lhs, floating_point Rhs>
194template<floating_point Lhs, floating_point Rhs>
197template<floating_point Type>
200template<floating_point Lhs, floating_point Rhs>
203template<floating_point Lhs, floating_point Rhs>
206template<floating_point Lhs, floating_point Rhs>
209template<floating_point Lhs, floating_point Rhs>
220template<sbx::math::floating_point Type>
221struct std::hash<sbx::math::basic_quaternion<Type>> {
227template<sbx::math::
floating_po
int Type>
228struct YAML::convert<sbx::math::basic_quaternion<Type>> {
236template<sbx::math::
floating_po
int Type>
237struct fmt::formatter<sbx::math::basic_quaternion<Type>> {
239 template<
typename ParseContext>
240 constexpr auto parse(ParseContext& context) ->
decltype(context.begin());
242 template<
typename FormatContext>
247#include <libsbx/math/quaternion.ipp>
Definition: angle.hpp:271
Definition: matrix4x4.hpp:25
Definition: quaternion.hpp:24
static constexpr auto slerp(const basic_quaternion &x, basic_quaternion y, const value_type a) noexcept -> basic_quaternion
Spherical linear interpolation between two quaternions.
Definition: quaternion.hpp:102
Definition: vector3.hpp:22