./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
7 / 13
53.8%
Branches:
2 / 4
50.0%
Functions:
2 / 3
66.7%

libs/base/src/eu/base/quat.h
Line Branch Exec Source
1 #pragma once
2
3 #include "eu/base/vec3.h"
4 #include "eu/base/numeric.h"
5 #include "eu/base/axisangle.h"
6 #include "eu/base/angle.h"
7 #include "eu/base/mat4.h"
8
9
10 namespace eu
11 {
12 /** \addtogroup math
13 * @{
14 */
15
16
17 /// A quaternion representing a rotation in 3d.
18 struct Q
19 {
20 float w;
21 float x;
22 float y;
23 float z;
24
25 3224 constexpr Q(float aw, const v3& v)
26 3224 : w(aw)
27 3224 , x(v.x)
28 3224 , y(v.y)
29 3224 , z(v.z)
30 {
31 3224 }
32
33 ✗ constexpr Q(const float* arr)
34 ✗ : w(arr[0])
35 ✗ , x(arr[1])
36 ✗ , y(arr[2])
37 ✗ , z(arr[3])
38 {
39 ✗ }
40
41 /// Create a quaternion from an axis angle
42 [[nodiscard]] static Q from(const AA& aa);
43
44 /// Create a quaternion from a yaw-pitch-roll
45 [[nodiscard]] static Q from(const Ypr& ypr);
46 [[nodiscard]] static Q from_fast(const Ypr& ypr);
47
48 [[nodiscard]] static Q from_rotation_matrix(const m4& m);
49
50 /// Create a quaternion going from `from` to `to`.
51 [[nodiscard]] static Q from_to(const Q& from, const Q& to);
52
53 /// Creates a look-at quaternion from 2 positions.
54 /// Standing at `from` and up is `up`, the result will be a quaternion looking at `to`
55 [[nodiscard]] static std::optional<Q> look_at(const v3& from, const v3& to, const n3& up);
56
57 /// Creates a look-at quaternion looking in a direction.
58 [[nodiscard]] static Q look_in_direction(const n3& dir, const n3& up);
59
60 /// Normalize the quaternion.
61 /// If it can't be normalized, it is set to the identity.
62 void normalize();
63
64 /// Return the passed rotation composed after the current rotation.
65 [[nodiscard]] Q then_get_rotated(const Q& q) const;
66
67 /// Rotate a unit vector according to the quaternion
68 [[nodiscard]] n3 get_rotated(const n3& v) const;
69
70 /// Gets the negated quaternion.
71 /// The negated represents the same rotation
72 [[nodiscard]] Q get_negated() const;
73
74 /// Get the `[x,y,z]` part as a regular 3d vector.
75 [[nodiscard]] v3 get_vec_part() const;
76
77 /// Returns the conjugate of the quaternion.
78 [[nodiscard]] Q get_conjugate() const;
79
80 /// Gets the inverse rotation.
81 /// Implemented as a conjugate with assert that the quaternion is normalized.
82 /// @see \ref get_conjugate()
83 [[nodiscard]] Q get_inverse() const;
84
85 /// Gets the length of the quaternion.
86 /// Since the quaternion should be a unit, this should always be `1`
87 [[nodiscard]] float get_length() const;
88
89 /// Return a normalized quaternion
90 /// If it can't be normalized, the identity is returned
91 [[nodiscard]] Q get_normalized() const;
92
93 /// Get the local in vector.
94 [[nodiscard]] n3 get_local_in() const;
95
96 /// Get the local out vector.
97 [[nodiscard]] n3 get_local_out() const;
98
99 /// Get the local right vector.
100 [[nodiscard]] n3 get_local_right() const;
101
102 /// Get the local left vector.
103 [[nodiscard]] n3 get_local_left() const;
104
105 /// Get the local up vector.
106 [[nodiscard]] n3 get_local_up() const;
107
108 /// Get the local down vector.
109 [[nodiscard]] n3 get_local_down() const;
110
111 void operator*=(float rhs);
112 void operator*=(const Q& rhs);
113
114 /// Normalized lerp between 2 quaternions
115 /// This will result in a non-linear rotation
116 /// @see \ref slerp()
117 static Q nlerp(const Q& f, float scale, const Q& t);
118
119 /// Spherical lerp between 2 quaternions.
120 /// Will take the longer route sometimes but is technically faster.
121 /// @see \ref nlerp()
122 static Q slerp_fast(const Q& qa, float t, const Q& qb);
123
124 /// Shortest spherical lerp between 2 quaternions.
125 /// Has extra logic to take the shortest route.
126 /// @see \ref slerp_fast()
127 /// @see \ref nlerp()
128 static Q slerp(const Q& from, float scale, const Q& to);
129 };
130
131 /// The identity quaternion.
132 constexpr Q q_identity = Q(1, v3(0, 0, 0));
133
134 float dot(const Q& lhs, const Q& rhs);
135
136 /// Converts a quaternion to string, prefer fmt.
137 std::string string_from(const Q& v);
138
139 Q operator*(const Q& lhs, const Q& rhs);
140 Q operator*(float scale, const Q& q);
141 Q operator*(const Q& q, float scale);
142
143 /** @}*/
144 ADD_CATCH_FORMATTER_DEF(Q)
145 }
146
147
2/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 11 not taken.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 9 not taken.
1 ADD_DEFAULT_FORMATTER(eu::Q, std::string, eu::string_from);
148
149