GCC Code Coverage Report


libs/base/src/base/
File: quat.h
Date: 2025-03-19 20:55:25
Lines:
7/7
100.0%
Functions:
2/2
100.0%
Branches:
1/2
50.0%

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