19#ifndef FENNEC_MATH_EXT_QUATERNION_H
20#define FENNEC_MATH_EXT_QUATERNION_H
23#include <fennec/math/vector_base.h>
28template<
typename ScalarT>
struct quaternion;
30template<
typename genType>
using qua = quaternion<genType>;
32using quat = qua<float>;
33using dquat = qua<double>;
37template<
typename genType>
38constexpr genType
dot(
const qua<genType>& x,
const qua<genType>& y) {
39 return x.w*
y.w + x.x*
y.x + x.y*
y.y + x.z*
y.z;
47template<
typename genType>
48constexpr genType sqnorm(
const qua<genType>& q) {
56template<
typename genType>
57constexpr genType norm(
const qua<genType>& q) {
65template<
typename genType>
66constexpr qua<genType> unit(
const qua<genType>& q) {
67 genType n = fennec::norm(q);
68 return q * (genType(1) / n);
75template<
typename genType>
76constexpr qua<genType> reciprocal(
const qua<genType>& q) {
77 return ~q / fennec::sqnorm(q);
81template<
typename ScalarT>
82struct quaternion : detail::vector_base_type<ScalarT, 4>
87 using base_type = detail::vector_base_type<ScalarT, 4>;
88 using scalar_t = ScalarT;
89 using quat_t = quaternion;
90 using vec3_t = vec<scalar_t, 3>;
91 using vec4_t = vec<scalar_t, 4>;
93 using base_type::data;
94 using base_type::x, base_type::y, base_type::z, base_type::w;
101 constexpr quaternion() {
102 data = { 0, 0, 0, 1 };
111 constexpr quaternion(scalar_t w, scalar_t x, scalar_t y, scalar_t z) {
112 data = { x,
y, z, w };
119 constexpr quaternion(scalar_t s, vec3_t v) {
120 data = { v.x, v.y, v.z, s };
126 constexpr quaternion(
const vec4_t& v) {
133 template<
typename DataT,
size_t...IndicesV>
requires(
sizeof...(IndicesV) == 4)
134 constexpr quaternion(
const detail::swizzle_storage<DataT, scalar_t, IndicesV...>& s) {
144 constexpr quaternion(
const quaternion& q) {
151 constexpr quaternion(quaternion&& q)
noexcept {
161 constexpr quat_t& operator=(
const quat_t& q) {
169 constexpr quat_t& operator=(quat_t&& q)
noexcept {
182 constexpr friend bool operator==(
const quat_t& lhs,
const quat_t& rhs) {
183 return lhs.data == rhs.data;
191 constexpr friend bool operator!=(
const quat_t& lhs,
const quat_t& rhs) {
192 return lhs.data != rhs.data;
202 constexpr friend quat_t operator-(
const quat_t& rhs) {
203 return quat_t(-rhs.w, -rhs.x, -rhs.y, -rhs.z);
210 constexpr friend quat_t operator~(
const quat_t& rhs) {
211 return quat_t(rhs.w, -rhs.x, -rhs.y, -rhs.z);
222 constexpr friend quat_t operator*(
const quat_t& lhs, scalar_t rhs) {
223 return quat_t(lhs.w * rhs, lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
231 constexpr friend quat_t operator*(scalar_t lhs,
const quat_t& rhs) {
232 return quat_t(lhs * rhs.w, lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
240 constexpr friend quat_t operator/(
const quat_t& lhs, scalar_t rhs) {
241 return quat_t(lhs.w / rhs, lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);
249 constexpr friend quat_t operator/(scalar_t lhs,
const quat_t& rhs) {
250 return quat_t(lhs / rhs.w, lhs / rhs.x, lhs / rhs.y, lhs / rhs.z);
261 constexpr friend quat_t& operator*=(quat_t& lhs, scalar_t rhs) {
274 constexpr friend quat_t& operator/=(
const quat_t& lhs, scalar_t rhs) {
285 constexpr friend vec3_t operator*(
const quat_t& q,
const vec3_t& v) {
286 const vec3_t u = q.xyz;
289 return v + (uv*q.w + uuv) * scalar_t(2);
292 constexpr friend vec3_t operator*(
const vec3_t& v,
const quat_t& q) {
293 return fennec::reciprocal(q) * v;
296 constexpr friend vec4_t operator*(
const quat_t& q,
const vec4_t& v) {
297 return vec4_t(q * v.xyz, v.w);
300 constexpr friend vec4_t operator*(
const vec4_t& v,
const quat_t& q) {
301 return fennec::reciprocal(q) * v;
307 constexpr friend quat_t operator+(
const quat_t& lhs,
const quat_t& rhs) {
316 constexpr friend quat_t operator-(
const quat_t& lhs,
const quat_t& rhs) {
325 constexpr friend quat_t operator*(
const quat_t& lhs,
const quat_t& rhs) {
327 lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z * rhs.z,
328 lhs.w*rhs.x + lhs.x*rhs.w + lhs.y*rhs.z - lhs.z * rhs.y,
329 lhs.w*rhs.y - lhs.x*rhs.z + lhs.y*rhs.w + lhs.z * rhs.x,
330 lhs.w*rhs.z - lhs.x*rhs.y - lhs.y*rhs.x + lhs.z * rhs.w
337 constexpr friend quat_t& operator+=(quat_t& lhs,
const quat_t& rhs) {
345 constexpr friend quat_t& operator-=(quat_t& lhs,
const quat_t& rhs) {
353 constexpr friend quat_t& operator*=(quat_t& lhs,
const quat_t& rhs) {
354 return lhs = lhs * rhs;
constexpr genType sqrt(genType x)
Returns .
Definition exponential.h:178
constexpr genType dot(const vector< genType, i... > &x, const vector< genType, i... > &y)
Returns the dot product of and , i.e., .
Definition geometric.h:133
constexpr vector< genType, i... > cross(const vector< genType, i... > &x, const vector< genType, i... > &y)
Returns the cross product of and , i.e., .
Definition geometric.h:211
constexpr genType y()
Definition constants.h:672