./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
6 / 6
100.0%
Branches:
2 / 4
50.0%
Functions:
3 / 3
100.0%

libs/base/src/eu/base/mat4.h
Line Branch Exec Source
1 #pragma once
2
3 #include "eu/base/vec3.h"
4 #include "eu/base/vec4.h"
5 #include "eu/base/angle.h"
6 #include "eu/base/axisangle.h"
7
8
9 namespace eu
10 {
11 /** \addtogroup math
12 * @{
13 */
14
15 struct Q;
16
17 struct Rui
18 {
19 float right = 0;
20 float up = 0;
21 float in = 0;
22 };
23
24 /// 4x4 matrix
25 struct m4
26 {
27 /// Create a new matrix from column major format.
28 [[nodiscard]] static m4 from_col_major(
29 float t00, float t01, float t02, float t03,
30 float t10, float t11, float t12, float t13,
31 float t20, float t21, float t22, float t23,
32 float t30, float t31, float t32, float t33);
33
34 /// Create a new matrix from row major format.
35 34 [[nodiscard]] constexpr static m4 from_row_major(
36 float t00, float t10, float t20, float t30,
37 float t01, float t11, float t21, float t31,
38 float t02, float t12, float t22, float t32,
39 float t03, float t13, float t23, float t33)
40 {
41 return {
42 t00, t01, t02, t03,
43 t10, t11, t12, t13,
44 t20, t21, t22, t23,
45 34 t30, t31, t32, t33};
46 }
47
48 /// Create a matrix from the major, aka the diagonal.
49 /// @see from_scalar
50 [[nodiscard]] static m4 from_major(const v4 &major);
51
52 /// Create a matrix from a single scalar.
53 /// @see from_major
54 [[nodiscard]] constexpr static m4 from_scalar(float scalar)
55 {
56 const float z = 0;
57 return from_row_major(
58 scalar, z, z, z,
59 z, scalar, z, z,
60 z, z, scalar, z,
61 z, z, z, scalar);
62 }
63
64 [[nodiscard]] static m4 from_basis(const n3& a, const n3& b, const n3& c);
65 [[nodiscard]] static m4 from_scale(const v3& s);
66
67 /// Create a translation matrix.
68 [[nodiscard]] static m4 from_translation(const v3 &v);
69
70 /// Create a rotation matrix, around the X axis.
71 [[nodiscard]] static m4 from_rot_x(const An &a);
72
73 /// Create a rotation matrix, around the Y axis.
74 [[nodiscard]] static m4 from_rot_y(const An &a);
75
76 /// Create a rotation matrix, around the Z axis.
77 [[nodiscard]] static m4 from_rot_z(const An &a);
78
79 /// Create a rotation matrix, from an axis angle.
80 [[nodiscard]] static m4 from(const AA &aa);
81
82 /// Create a rotation matrix, from a quaternion.
83 [[nodiscard]] static m4 from(const Q& q);
84
85 /// Create an orthographic projection matrix.
86 /// Also known as a `clip_from_view` transformation.
87 /// Clip Space is in OpenGL NDC (-1 to +1) z range.
88 /// @param l the left side
89 /// @param r the right side
90 /// @param t the up side
91 /// @param b the down side
92 /// @param n near
93 /// @param f far
94 [[nodiscard]] static m4 create_ortho_lrud(float l, float r, float t, float b, float n, float f);
95
96 /// Create a perspective projection matrix.
97 [[nodiscard]] static m4 create_perspective(const An &fov, float aspect_ratio, float near, float far);
98
99 /// Get a direct pointer to the data in column major format, for API integration.
100 float *get_column_major_data_ptr();
101
102 /// Get a direct pointer to the const data in column major format, for API integration.
103 [[nodiscard]] const float* get_column_major_data_ptr() const;
104
105 /// Invert the current matrix.
106 /// @see get_inverted
107 bool invert();
108
109 /// Return the inverted matrix
110 /// @see invert
111 [[nodiscard]] m4 get_inverted() const;
112
113 /// Return a single value given a row and column (note: zero/0 based index).
114 [[nodiscard]] float get(int row, int col) const;
115
116 /// Return a single value given a row and column (note: one/1 based index).
117 [[nodiscard]] float get1(int row, int col) const;
118
119 /// Get a transformed vec4.
120 [[nodiscard]] v4 get_transformed(const v4 &p) const;
121
122 /// Get a transformed vec3 assuming it's a point
123 [[nodiscard]] v3 get_transformed_point(const v3 &p) const;
124
125 /// Get a transformed (right, up, in)
126 [[nodiscard]] v3 get_transformed(const Rui& rui) const;
127
128 /// Get a transformed vec3, assuming it's a normal vector
129 [[nodiscard]] v3 get_transformed_vec(const v3 &p) const;
130
131 /// Get a transformed unit3
132 [[nodiscard]] n3 get_transformed_vec(const n3 &p) const;
133
134 /// Get a row as a vec4.
135 [[nodiscard]] v4 get_row(int r) const;
136
137 /// Get a column as vec4.
138 [[nodiscard]] v4 get_column(int c) const;
139
140 /// Combine this with a translation matrix.
141 [[nodiscard]] m4 get_translated(const v3 &t) const;
142
143 /// Combine this with a rotation matrix.
144 [[nodiscard]] m4 get_rotated(const AA &aa) const;
145
146 /// Get the current translation of the transformation matrix.
147 [[nodiscard]] v3 get_translation() const;
148
149 /// Get the major vector.
150 [[nodiscard]] v4 get_major() const;
151
152 /// Get the local X axis.
153 [[nodiscard]] n3 get_x_axis() const;
154
155 /// Get the local Y axis.
156 [[nodiscard]] n3 get_y_axis() const;
157
158 /// Get the local Z axis.
159 [[nodiscard]] n3 get_z_axis() const;
160
161 /// Gets the transpose of a matrix.
162 /// If the matrix is a rotation matrix, then the transpose is guaranteed to be the inverse of the matrix.
163 [[nodiscard]] m4 get_transposed() const;
164
165
166 void operator+=(const m4 &rhs);
167 void operator-=(const m4 &rhs);
168
169
170 private:
171 /// stored in column major
172 float data[16];
173 m4() = default;
174
175 47 constexpr m4(
176 float t00, float t01, float t02, float t03,
177 float t10, float t11, float t12, float t13,
178 float t20, float t21, float t22, float t23,
179 float t30, float t31, float t32, float t33)
180 47 : data{
181 t00, t01, t02, t03,
182 t10, t11, t12, t13,
183 t20, t21, t22, t23,
184 t30, t31, t32, t33}
185 {
186 47 }
187 };
188
189 /// The identity matrix.
190 constexpr m4 m4_identity = m4::from_scalar(1);
191
192 /// Convert a matrix to a string representation, prefer fmt.
193 std::string string_from(const m4 &m);
194
195 m4 operator+(const m4 &lhs, const m4 &rhs);
196 m4 operator-(const m4 &lhs, const m4 &rhs);
197 m4 operator*(const m4 &lhs, const m4 &rhs);
198 v4 operator*(const m4 &lhs, const v4 &rhs);
199
200 /** @}*/
201
202 ADD_CATCH_FORMATTER_DEF(m4)
203 }
204
205
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::m4, std::string, eu::string_from);
206