openMSX
gl_mat.cc
Go to the documentation of this file.
1#include "catch.hpp"
2#include "gl_mat.hh"
3
4using namespace gl;
5
6// Test approximations.
7static constexpr bool approxEq(const mat4& x, const mat4&y)
8{
9 return norm2_2(x - y) < 1.0e-3f;
10}
11
12// Extra matrix types used in this test.
18
19// It's useful to test both integer and float variants because the
20// former are implemented in plain C++ and (only) the latter have SSE
21// optimizations.
22
23TEST_CASE("gl_mat: constructors")
24{
25 SECTION("default constructor") {
26 mat2 m2;
27 CHECK(m2[0] == vec2(1, 0));
28 CHECK(m2[1] == vec2(0, 1));
29
30 imat2 i2;
31 CHECK(i2[0] == ivec2(1, 0));
32 CHECK(i2[1] == ivec2(0, 1));
33
34 mat3 m3;
35 CHECK(m3[0] == vec3(1, 0, 0));
36 CHECK(m3[1] == vec3(0, 1, 0));
37 CHECK(m3[2] == vec3(0, 0, 1));
38
39 imat3 i3;
40 CHECK(i3[0] == ivec3(1, 0, 0));
41 CHECK(i3[1] == ivec3(0, 1, 0));
42 CHECK(i3[2] == ivec3(0, 0, 1));
43
44 mat4 m4;
45 CHECK(m4[0] == vec4(1, 0, 0, 0));
46 CHECK(m4[1] == vec4(0, 1, 0, 0));
47 CHECK(m4[2] == vec4(0, 0, 1, 0));
48 CHECK(m4[3] == vec4(0, 0, 0, 1));
49
50 imat4 i4;
51 CHECK(i4[0] == ivec4(1, 0, 0, 0));
52 CHECK(i4[1] == ivec4(0, 1, 0, 0));
53 CHECK(i4[2] == ivec4(0, 0, 1, 0));
54 CHECK(i4[3] == ivec4(0, 0, 0, 1));
55
56 mat32 m32;
57 CHECK(m32[0] == vec3(1, 0, 0));
58 CHECK(m32[1] == vec3(0, 1, 0));
59
60 mat23 m23;
61 CHECK(m23[0] == vec2(1, 0));
62 CHECK(m23[1] == vec2(0, 1));
63 CHECK(m23[2] == vec2(0, 0));
64 }
65 SECTION("diagonal constructor") {
66 mat2 m2(vec2(2, 3));
67 CHECK(m2[0] == vec2(2, 0));
68 CHECK(m2[1] == vec2(0, 3));
69
70 imat2 i2(ivec2(2, 3));
71 CHECK(i2[0] == ivec2(2, 0));
72 CHECK(i2[1] == ivec2(0, 3));
73
74 mat3 m3(vec3(2, 3, 4));
75 CHECK(m3[0] == vec3(2, 0, 0));
76 CHECK(m3[1] == vec3(0, 3, 0));
77 CHECK(m3[2] == vec3(0, 0, 4));
78
79 imat3 i3(ivec3(2, 3, 4));
80 CHECK(i3[0] == ivec3(2, 0, 0));
81 CHECK(i3[1] == ivec3(0, 3, 0));
82 CHECK(i3[2] == ivec3(0, 0, 4));
83
84 mat4 m4(vec4(2, 3, 4, 5));
85 CHECK(m4[0] == vec4(2, 0, 0, 0));
86 CHECK(m4[1] == vec4(0, 3, 0, 0));
87 CHECK(m4[2] == vec4(0, 0, 4, 0));
88 CHECK(m4[3] == vec4(0, 0, 0, 5));
89
90 imat4 i4(ivec4(2, 3, 4, 5));
91 CHECK(i4[0] == ivec4(2, 0, 0, 0));
92 CHECK(i4[1] == ivec4(0, 3, 0, 0));
93 CHECK(i4[2] == ivec4(0, 0, 4, 0));
94 CHECK(i4[3] == ivec4(0, 0, 0, 5));
95
96 mat32 m32(vec2(2, 3));
97 CHECK(m32[0] == vec3(2, 0, 0));
98 CHECK(m32[1] == vec3(0, 3, 0));
99
100 mat23 m23(vec2(2, 3));
101 CHECK(m23[0] == vec2(2, 0));
102 CHECK(m23[1] == vec2(0, 3));
103 CHECK(m23[2] == vec2(0, 0));
104 }
105 SECTION("construct from columns") {
106 mat2 m2(vec2(2, 3), vec2(4, 5));
107 CHECK(m2[0] == vec2(2, 3));
108 CHECK(m2[1] == vec2(4, 5));
109
110 imat2 i2(ivec2(2, 3), ivec2(4, 5));
111 CHECK(i2[0] == ivec2(2, 3));
112 CHECK(i2[1] == ivec2(4, 5));
113
114 mat3 m3(vec3(2, 3, 4), vec3(5, 6, 7), vec3(8, 9, 1));
115 CHECK(m3[0] == vec3(2, 3, 4));
116 CHECK(m3[1] == vec3(5, 6, 7));
117 CHECK(m3[2] == vec3(8, 9, 1));
118
119 imat3 i3(ivec3(2, 3, 4), ivec3(5, 6, 7), ivec3(8, 9, 1));
120 CHECK(i3[0] == ivec3(2, 3, 4));
121 CHECK(i3[1] == ivec3(5, 6, 7));
122 CHECK(i3[2] == ivec3(8, 9, 1));
123
124 mat4 m4(vec4(2, 3, 4, 5), vec4(3, 4, 5, 6), vec4(4, 5, 6, 7), vec4(5, 6, 7, 8));
125 CHECK(m4[0] == vec4(2, 3, 4, 5));
126 CHECK(m4[1] == vec4(3, 4, 5, 6));
127 CHECK(m4[2] == vec4(4, 5, 6, 7));
128 CHECK(m4[3] == vec4(5, 6, 7, 8));
129
130 imat4 i4(ivec4(2, 3, 4, 5), ivec4(3, 4, 5, 6), ivec4(4, 5, 6, 7), ivec4(5, 6, 7, 8));
131 CHECK(i4[0] == ivec4(2, 3, 4, 5));
132 CHECK(i4[1] == ivec4(3, 4, 5, 6));
133 CHECK(i4[2] == ivec4(4, 5, 6, 7));
134 CHECK(i4[3] == ivec4(5, 6, 7, 8));
135
136 mat32 m32(vec3(2, 3, 4), vec3(5, 6, 7));
137 CHECK(m32[0] == vec3(2, 3, 4));
138 CHECK(m32[1] == vec3(5, 6, 7));
139
140 mat23 m23(vec2(2, 3), vec2(4, 5), vec2(6, 7));
141 CHECK(m23[0] == vec2(2, 3));
142 CHECK(m23[1] == vec2(4, 5));
143 CHECK(m23[2] == vec2(6, 7));
144 }
145}
146
147TEST_CASE("gl_mat: modify columns or elements")
148{
149 mat2 m2(vec2(2, 3));
150 m2[1] = vec2(8, 9); m2[0][1] = 7;
151 CHECK(m2[0] == vec2(2, 7));
152 CHECK(m2[1] == vec2(8, 9));
153
154 imat2 i2(ivec2(2, 3));
155 i2[0] = ivec2(8, 9); i2[1][1] = 7;
156 CHECK(i2[0] == ivec2(8, 9));
157 CHECK(i2[1] == ivec2(0, 7));
158
159 mat3 m3(vec3(2, 3, 4));
160 m3[1] = vec3(7, 8, 9); m3[0][1] = 6;
161 CHECK(m3[0] == vec3(2, 6, 0));
162 CHECK(m3[1] == vec3(7, 8, 9));
163 CHECK(m3[2] == vec3(0, 0, 4));
164
165 imat3 i3(ivec3(2, 3, 4));
166 i3[0] = ivec3(7, 8, 9); i3[2][0] = 6;
167 CHECK(i3[0] == ivec3(7, 8, 9));
168 CHECK(i3[1] == ivec3(0, 3, 0));
169 CHECK(i3[2] == ivec3(6, 0, 4));
170
171 mat4 m4(vec4(2, 3, 4, 5));
172 m4[3] = vec4(6, 7, 8, 9); m4[1][1] = 1;
173 CHECK(m4[0] == vec4(2, 0, 0, 0));
174 CHECK(m4[1] == vec4(0, 1, 0, 0));
175 CHECK(m4[2] == vec4(0, 0, 4, 0));
176 CHECK(m4[3] == vec4(6, 7, 8, 9));
177
178 imat4 i4(ivec4(2, 3, 4, 5));
179 i4[1] = ivec4(6, 7, 8, 9); i4[2][3] = 1;
180 CHECK(i4[0] == ivec4(2, 0, 0, 0));
181 CHECK(i4[1] == ivec4(6, 7, 8, 9));
182 CHECK(i4[2] == ivec4(0, 0, 4, 1));
183 CHECK(i4[3] == ivec4(0, 0, 0, 5));
184
185 mat32 m32(vec2(2, 3));
186 m32[0] = vec3(7, 8, 9); m32[1][0] = 6;
187 CHECK(m32[0] == vec3(7, 8, 9));
188 CHECK(m32[1] == vec3(6, 3, 0));
189
190 mat23 m23(vec2(2, 3));
191 m23[1] = vec2(8, 9); m23[1][0] = 7;
192 CHECK(m23[0] == vec2(2, 0));
193 CHECK(m23[1] == vec2(7, 9));
194 CHECK(m23[2] == vec2(0, 0));
195}
196
197TEST_CASE("gl_mat: (in)equality")
198{
199 mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
200 mat3 n3(vec3(1, 0, 3), vec3(4, 5, 6), vec3(7, 8, 9));
201 mat3 o3(vec3(1, 2, 3), vec3(4, 5, 0), vec3(7, 8, 9));
202 mat3 p3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 0, 9));
203 CHECK(m3 == m3);
204 CHECK(m3 != n3);
205 CHECK(m3 != o3);
206 CHECK(m3 != p3);
207
208 imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9));
209 imat3 j3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 0, 9));
210 imat3 k3(ivec3(1, 2, 3), ivec3(4, 5, 0), ivec3(7, 8, 9));
211 imat3 l3(ivec3(0, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9));
214 CHECK(i3 != k3);
215 CHECK(i3 != l3);
216
217 mat4 m4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0));
218 mat4 n4(vec4(1, 2, 0, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0));
219 mat4 o4(vec4(1, 2, 3, 4), vec4(0, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0));
220 mat4 p4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 0, 7, 8), vec4(7, 8, 9, 0));
221 mat4 q4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 1));
224 CHECK(m4 != o4);
225 CHECK(m4 != p4);
226 CHECK(m4 != q4);
227
228 imat4 i4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0));
229 imat4 j4(ivec4(1, 0, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0));
230 imat4 k4(ivec4(1, 2, 3, 4), ivec4(3, 4, 0, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0));
231 imat4 l4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 0), ivec4(7, 8, 9, 0));
232 imat4 h4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(0, 8, 9, 0));
235 CHECK(i4 != k4);
236 CHECK(i4 != l4);
237 CHECK(i4 != h4);
238
239 mat32 m32(vec3(2, 3, 4), vec3(5, 6, 7));
240 mat32 n32(vec3(2, 3, 0), vec3(5, 6, 7));
241 mat32 o32(vec3(2, 3, 4), vec3(0, 6, 7));
244 CHECK(m32 != o32);
245
246 mat23 m23(vec2(2, 3), vec2(4, 5), vec2(6, 7));
247 mat23 n23(vec2(0, 3), vec2(4, 5), vec2(6, 7));
248 mat23 o23(vec2(2, 3), vec2(4, 0), vec2(6, 7));
249 mat23 p23(vec2(2, 3), vec2(4, 5), vec2(0, 7));
252 CHECK(m23 != o23);
253 CHECK(m23 != p23);
254}
255
256TEST_CASE("gl_mat: copy constructor, assignment")
257{
258 SECTION("mat2") {
259 mat2 m(vec2(2, 3));
260 mat2 n(m); CHECK(n == m);
261 m[1][0] = 9; CHECK(n != m);
262 n = m; CHECK(n == m);
263 }
264 SECTION("imat2") {
265 imat2 m(ivec2(2, 3));
266 imat2 n(m); CHECK(n == m);
267 m[0][1] = 9; CHECK(n != m);
268 n = m; CHECK(n == m);
269 }
270 SECTION("mat3") {
271 mat3 m(vec3(3, 4, 5));
272 mat3 n(m); CHECK(n == m);
273 m[2][1] = 8; CHECK(n != m);
274 n = m; CHECK(n == m);
275 }
276 SECTION("imat3") {
277 imat3 m(ivec3(3, 4, 5));
278 imat3 n(m); CHECK(n == m);
279 m[1][2] = 8; CHECK(n != m);
280 n = m; CHECK(n == m);
281 }
282 SECTION("mat4") {
283 mat4 m(vec4(4, 5, 6, 7));
284 mat4 n(m); CHECK(n == m);
285 m[3][1] = 2; CHECK(n != m);
286 n = m; CHECK(n == m);
287 }
288 SECTION("imat3") {
289 imat4 m(ivec4(4, 5, 6, 7));
290 imat4 n(m); CHECK(n == m);
291 m[0][1] = 1; CHECK(n != m);
292 n = m; CHECK(n == m);
293 }
294}
295
296TEST_CASE("gl_mat: construct from larger matrix")
297{
298 mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4(7, 8, 9, 1), vec4(1, 0, 0, 0));
299 mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
300 mat2 m2(vec2(1, 2), vec2(4, 5));
301 CHECK(mat3(m4) == m3);
302 CHECK(mat2(m4) == m2);
303 CHECK(mat2(m3) == m2);
304
305 imat4 i4(ivec4(1, 2, 3, 4), ivec4(4, 5, 6, 7), ivec4(7, 8, 9, 1), ivec4(1, 0, 0, 0));
306 imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9));
307 imat2 i2(ivec2(1, 2), ivec2(4, 5));
308 CHECK(imat3(i4) == i3);
309 CHECK(imat2(i4) == i2);
310 CHECK(imat2(i3) == i2);
311
312 CHECK(mat32(m4) == mat32(vec3(1, 2, 3), vec3(4, 5, 6)));
313 CHECK(mat32(m3) == mat32(vec3(1, 2, 3), vec3(4, 5, 6)));
314 CHECK(mat23(m4) == mat23(vec2(1, 2), vec2(4, 5), vec2(7, 8)));
315 CHECK(mat23(m3) == mat23(vec2(1, 2), vec2(4, 5), vec2(7, 8)));
316}
317
318TEST_CASE("gl_mat: addition, subtraction, negation")
319{
320 mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
321 mat3 n3(vec3(2, 4, 6), vec3(1, 3, 5), vec3(7, 8, 9));
322 mat3 o3 = m3 + n3;
323 mat3 p3 = m3 - n3;
324 CHECK(o3 == mat3(vec3( 3, 6, 9), vec3(5, 8, 11), vec3(14, 16, 18)));
325 CHECK(p3 == mat3(vec3(-1, -2, -3), vec3(3, 2, 1), vec3( 0, 0, 0)));
326 p3 += n3;
327 o3 -= n3;
328 CHECK(o3 == m3);
329 CHECK(p3 == m3);
330 CHECK(-m3 == mat3(vec3(-1, -2, -3), vec3(-4, -5, -6), vec3(-7, -8, -9)));
331
332 imat3 i3(ivec3(6, 3, 0), ivec3(2, 4, 6), ivec3(3, 4, 5));
333 imat3 j3(ivec3(1, 2, 3), ivec3(4, 0, 4), ivec3(0, 1, 1));
334 imat3 k3 = i3 + j3;
335 imat3 l3 = i3 - j3;
336 CHECK(k3 == imat3(ivec3(7, 5, 3), ivec3( 6, 4, 10), ivec3(3, 5, 6)));
337 CHECK(l3 == imat3(ivec3(5, 1, -3), ivec3(-2, 4, 2), ivec3(3, 3, 4)));
338 l3 += j3;
339 k3 -= j3;
340 CHECK(k3 == i3);
341 CHECK(l3 == i3);
342 CHECK(-i3 == imat3(ivec3(-6, -3, -0), ivec3(-2, -4, -6), ivec3(-3, -4, -5)));
343
344 mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4(7, 8, 9, 1), vec4(1, 0, 0, 0));
345 mat4 n4(vec4(2, 4, 6, 8), vec4(1, 3, 5, 7), vec4(7, 8, 9, 2), vec4(0, 0, 0, 1));
346 mat4 o4 = m4 + n4;
347 mat4 p4 = m4 - n4;
348 CHECK(o4 == mat4(vec4( 3, 6, 9, 12), vec4(5, 8, 11, 14), vec4(14, 16, 18, 3), vec4(1, 0, 0, 1)));
349 CHECK(p4 == mat4(vec4(-1, -2, -3, -4), vec4(3, 2, 1, 0), vec4( 0, 0, 0, -1), vec4(1, 0, 0, -1)));
350 p4 += n4;
351 o4 -= n4;
352 CHECK(o4 == m4);
353 CHECK(p4 == m4);
354 CHECK(-m4 == mat4(vec4(-1, -2, -3, -4), vec4(-4, -5, -6, -7), vec4(-7, -8, -9, -1), vec4(-1, 0, 0, 0)));
355
356 imat4 i4(ivec4(0, 1, 2, 3), ivec4(4, 3, 2, 1), ivec4(1, 1, 1, 1), ivec4(5, 5, 4, 4));
357 imat4 j4(ivec4(2, 3, 4, 5), ivec4(1, 1, 2, 2), ivec4(0, 0, 1, 2), ivec4(1, 2, 2, 0));
358 imat4 k4 = i4 + j4;
359 imat4 l4 = i4 - j4;
360 CHECK(k4 == imat4(ivec4( 2, 4, 6, 8), ivec4(5, 4, 4, 3), ivec4(1, 1, 2, 3), ivec4(6, 7, 6, 4)));
361 CHECK(l4 == imat4(ivec4(-2, -2, -2, -2), ivec4(3, 2, 0, -1), ivec4(1, 1, 0, -1), ivec4(4, 3, 2, 4)));
362 l4 += j4;
363 k4 -= j4;
364 CHECK(k4 == i4);
365 CHECK(l4 == i4);
366 CHECK(-i4 == imat4(ivec4(0, -1, -2, -3), ivec4(-4, -3, -2, -1), ivec4(-1, -1, -1, -1), ivec4(-5, -5, -4, -4)));
367
368 mat32 m32(vec3(3, 4, 5), vec3(4, 2, 0));
369 mat32 n32(vec3(1, 1, 2), vec3(4, 4, 3));
370 mat32 o32 = m32 + n32;
371 mat32 p32 = m32 - n32;
372 CHECK(o32 == mat32(vec3(4, 5, 7), vec3(8, 6, 3)));
373 CHECK(p32 == mat32(vec3(2, 3, 3), vec3(0, -2, -3)));
374 p32 += n32;
375 o32 -= n32;
376 CHECK(o32 == m32);
377 CHECK(p32 == m32);
378 CHECK(-m32 == mat32(vec3(-3, -4, -5), vec3(-4, -2, 0)));
379}
380
381TEST_CASE("gl_mat: matrix * scalar")
382{
383 mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3( 7, 8, 9));
384 mat3 n3(vec3(2, 4, 6), vec3(8, 10, 12), vec3(14, 16, 18));
385 CHECK((2.0f * m3) == n3);
386 CHECK((m3 * 2.0f) == n3);
387 m3 *= 2.0f;
388 CHECK(m3 == n3);
389
390 imat3 i3(ivec3(2, 1, 0), ivec3(-1, 5, 3), ivec3( 7, 0, -3));
391 imat3 j3(ivec3(4, 2, 0), ivec3(-2, 10, 6), ivec3(14, 0, -6));
392 CHECK((2 * i3) == j3);
393 CHECK((i3 * 2) == j3);
394 i3 *= 2;
395 CHECK(i3 == j3);
396
397 mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4( 7, 8, 9, 10), vec4(0, 0, -1, -2));
398 mat4 n4(vec4(2, 4, 6, 8), vec4(8, 10, 12, 14), vec4(14, 16, 18, 20), vec4(0, 0, -2, -4));
399 CHECK((2.0f * m4) == n4);
400 CHECK((m4 * 2.0f) == n4);
401 m4 *= 2.0f;
402 CHECK(m4 == n4);
403
404 imat4 i4(ivec4(0, 1, 2, 3), ivec4(1, 0, 0, 2), ivec4(3, 2, 1, 0), ivec4(0, 0, -1, -2));
405 imat4 j4(ivec4(0, 3, 6, 9), ivec4(3, 0, 0, 6), ivec4(9, 6, 3, 0), ivec4(0, 0, -3, -6));
406 CHECK((3 * i4) == j4);
407 CHECK((i4 * 3) == j4);
408 i4 *= 3;
409 CHECK(i4 == j4);
410
411 mat32 m32(vec3( 3, 4, 5), vec3( 4, 2, 0));
412 mat32 n32(vec3(-6, -8, -10), vec3(-8, -4, 0));
413 CHECK((-2.0f * m32) == n32);
414 CHECK((m32 * -2.0f) == n32);
415 m32 *= -2.0f;
416 CHECK(m32 == n32);
417}
418
419TEST_CASE("gl_mat: matrix * column-vector")
420{
421 mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
422 CHECK((m3 * vec3(1, 0, 0)) == vec3( 1, 2, 3));
423 CHECK((m3 * vec3(0, 2, 0)) == vec3( 8, 10, 12));
424 CHECK((m3 * vec3(0, 0, 3)) == vec3(21, 24, 27));
425 CHECK((m3 * vec3(1, 2, 3)) == vec3(30, 36, 42));
426
427 imat3 i3(ivec3(0, -2, 1), ivec3(1, -1, 0), ivec3(-1, -2, 1));
428 CHECK((i3 * ivec3(-1, 0, 0)) == ivec3( 0, 2, -1));
429 CHECK((i3 * ivec3( 0, 0, 0)) == ivec3( 0, 0, 0));
430 CHECK((i3 * ivec3( 0, 0, 3)) == ivec3(-3, -6, 3));
431 CHECK((i3 * ivec3(-1, 0, 3)) == ivec3(-3, -4, 2));
432
433 mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4(7, 8, 9, 1), vec4(0, 1, 0, -1));
434 CHECK((m4 * vec4(1, 0, 0, 0)) == vec4( 1, 2, 3, 4));
435 CHECK((m4 * vec4(0, 2, 0, 0)) == vec4( 8, 10, 12, 14));
436 CHECK((m4 * vec4(0, 0, 3, 0)) == vec4(21, 24, 27, 3));
437 CHECK((m4 * vec4(0, 0, 0, 4)) == vec4( 0, 4, 0, -4));
438 CHECK((m4 * vec4(1, 2, 3, 4)) == vec4(30, 40, 42, 17));
439
440 imat4 i4(ivec4(-1, 2, 0, -3), ivec4(0, 1, 2, -1), ivec4(0, 1, 1, 0), ivec4(-1, 1, 0, -1));
441 CHECK((i4 * ivec4(-1, 0, 0, 0)) == ivec4( 1, -2, 0, 3));
442 CHECK((i4 * ivec4( 0, 2, 0, 0)) == ivec4( 0, 2, 4, -2));
443 CHECK((i4 * ivec4( 0, 0, -2, 0)) == ivec4( 0, -2, -2, 0));
444 CHECK((i4 * ivec4( 0, 0, 0, 1)) == ivec4(-1, 1, 0, -1));
445 CHECK((i4 * ivec4(-1, 2, -2, 1)) == ivec4( 0, -1, 2, 0));
446
447 mat32 m32(vec3(3, 4, 5), vec3(4, 2, 0));
448 CHECK((m32 * vec2(2, 3)) == vec3(18, 14, 10));
449
450 mat23 m23(vec2(3, 4), vec2(1, 5), vec2(4, 2));
451 CHECK((m23 * vec3(1, 2, 3)) == vec2(17, 20));
452}
453
454TEST_CASE("gl_mat: matrix * matrix")
455{
456 mat3 m3(vec3(1, -1, 1), vec3(2, 0, -1), vec3(0, 1, 1));
457 mat3 n3(vec3(1, 1, -1), vec3(0, -2, 1), vec3(1, 0, 1));
458 mat3 o3(vec3(0, -1, 2), vec3(1, 2, -2), vec3(0, 2, 1));
459 CHECK((m3 * n3) == mat3(vec3(3, -2, -1), vec3(-4, 1, 3), vec3(1, 0, 2)));
460 CHECK((n3 * o3) == mat3(vec3(2, 2, 1), vec3(-1, -3, -1), vec3(1, -4, 3)));
461 CHECK(((m3 * n3) * o3) == (m3 * (n3 * o3)));
462
463 imat3 i3(ivec3( 1, 1, 1), ivec3(-2, 0, -1), ivec3(0, -1, 1));
464 imat3 j3(ivec3(-1, 0, -1), ivec3( 1, -2, 1), ivec3(1, -1, 1));
465 CHECK((i3 * j3) == imat3(ivec3(-1, 0, -2), ivec3(5, 0, 4), ivec3(3, 0, 3)));
466
467 mat4 m4(vec4(1, -1, 1, 0), vec4(2, 0, -1, 1), vec4(0, 1, 1, -1), vec4(2, 0, 1, -1));
468 mat4 n4(vec4(1, 1, -1, 1), vec4(0, -2, 1, 0), vec4(1, 0, 1, -1), vec4(0, 1, 2, -2));
469 CHECK((m4 * n4) == mat4(vec4(5, -2, 0, 1), vec4(-4, 1, 3, -3), vec4(-1, 0, 1, 0), vec4(-2, 2, -1, 1)));
470 CHECK((n4 * m4) == mat4(vec4(2, 3, -1, 0), vec4( 1, 3, -1, 1), vec4( 1, -3, 0, 1), vec4( 3, 1, -3, 3)));
471
472 imat4 i4(ivec4(1, -1, 1, 2), ivec4(2, -1, -1, 1), ivec4(2, 1, 1, -1), ivec4( 2, -1, 1, -1));
473 imat4 j4(ivec4(1, 1, -1, 1), ivec4(2, -2, 1, -1), ivec4(1, -2, 1, -1), ivec4(-1, 1, 2, -2));
474 CHECK((i4 * j4) == imat4(ivec4(3, -4, 0, 3), ivec4(-2, 2, 4, 2), ivec4(-3, 3, 3, 0), ivec4(1, 4, -2, -1)));
475
476 mat32 m32(vec3(1, 2, -1), vec3(-1, -1, 2));
477 mat23 m23(vec2(1, -2), vec2(2, -1), vec2(1, -1));
478 CHECK((m32 * m23) == mat3(vec3(3, 4, -5), vec3(3, 5, -4), vec3(2, 3, -3)));
479 CHECK((m23 * m32) == mat2(vec2(4, -3), vec2(-1, 1)));
480 CHECK((m3 * m32) == mat32(vec3(5, -2, -2), vec3(-3, 3, 2)));
481 CHECK((m23 * m3 ) == mat23(vec2(0, -2), vec2(1, -3), vec2(3, -2)));
482}
483
484TEST_CASE("gl_mat: transpose")
485{
486 mat3 m3(vec3(1, -1, 1), vec3(2, 0, -1), vec3(0, 1, 1));
487 CHECK(transpose(m3) == mat3(vec3(1, 2, 0), vec3(-1, 0, 1), vec3(1, -1, 1)));
488
489 imat3 i3(ivec3(1, 1, 1), ivec3(-2, 0, -1), ivec3(0, -1, 1));
490 CHECK(transpose(i3) == imat3(ivec3(1, -2, 0), ivec3(1, 0, -1), ivec3(1, -1, 1)));
491
492 mat4 m4(vec4(1, -1, 1, 0), vec4(2, 0, -1, 1), vec4(0, 1, 1, -1), vec4(2, 0, 1, -1));
493 CHECK(transpose(m4) == mat4(vec4(1, 2, 0, 2), vec4(-1, 0, 1, 0), vec4(1, -1, 1, 1), vec4(0, 1, -1, -1)));
494
495 imat4 i4(ivec4(1, -1, 1, 2), ivec4(2, -1, -1, 1), ivec4(2, 1, 1, -1), ivec4(2, -1, 1, -1));
496 CHECK(transpose(i4) == imat4(ivec4(1, 2, 2, 2), ivec4(-1, -1, 1, -1), ivec4(1, -1, 1, 1), ivec4(2, 1, -1, -1)));
497
498 mat32 m32(vec3(1, 2, 3), vec3(4, 5, 6));
499 mat23 m23(vec2(1, 4), vec2(2, 5), vec2(3, 6));
500 CHECK(transpose(m32) == m23);
501 CHECK(transpose(m23) == m32);
502}
503
504TEST_CASE("gl_mat: determinant, inverse")
505{
506 mat2 m2(vec2(1, -1), vec2(0, 1));
507 CHECK(determinant(m2) == 1.0f);
508 mat2 i2 = inverse(m2);
509 CHECK(determinant(i2) == 1.0f);
510 CHECK(i2 == mat2(vec2(1, 1), vec2(0, 1)));
511 CHECK(m2 * i2 == mat2());
512 CHECK(i2 * m2 == mat2());
513
514 mat3 m3(vec3(1, 0, -1), vec3(0, 1, 0), vec3(1, -1, 1));
515 CHECK(determinant(m3) == 2.0f);
516 mat3 i3 = inverse(m3);
517 CHECK(determinant(i3) == 0.5f);
518 CHECK(i3 == mat3(vec3(0.5f, 0.5f, 0.5f), vec3(0, 1, 0), vec3(-0.5f, 0.5f, 0.5f)));
519 CHECK(m3 * i3 == mat3());
520 CHECK(i3 * m3 == mat3());
521
522 mat4 m4(vec4(0, 1, 1, 0), vec4(-1, 0, 1, 0), vec4(1, 1, 0, -1), vec4(0, 1, 0, 0));
523 CHECK(determinant(m4) == -1.0f);
524 mat4 i4 = inverse(m4);
525 CHECK(approxEq(i4, mat4(vec4(1, -1, 0, -1), vec4(0, 0, 0, 1), vec4(1, 0, 0, -1), vec4(1, -1, -1, 0))));
526 CHECK(approxEq(m4 * i4, mat4()));
527 CHECK(approxEq(i4 * m4, mat4()));
528}
529
530TEST_CASE("gl_mat: norm-2 squared")
531{
532 mat3 m3(vec3(1, -1, 1), vec3(2, 0, -1), vec3(0, 1, 1));
533 CHECK(norm2_2(m3) == 10);
534
535 imat3 i3(ivec3(1, 2, 1), ivec3(-2, 3, -1), ivec3(2, 1, 4));
536 CHECK(norm2_2(i3) == 41);
537
538 mat4 m4(vec4(1, -1, 1, 2), vec4(2, 0, -1, 1), vec4(0, 1, 1, 0), vec4(0, 1, 1, 3));
539 CHECK(norm2_2(m4) == 26);
540
541 imat4 i4(ivec4(1, 2, 1, -3), ivec4(-2, 3, -1, 0), ivec4(2, 1, 4, -2), ivec4(0, 2, 2, 2));
542 CHECK(norm2_2(i4) == 66);
543
544 mat32 m32(vec3(1, 2, -1), vec3(-1, -1, 2));
545 mat23 m23(vec2(1, -1), vec2(2, -1), vec2(-1, 2));
547}
548
549
550#if 0
551
552// The following functions are not part of the actual test. They get compiled,
553// but never executed. I used them to (manually) inspect the quality of the
554// generated code. Only for mat4, because the code was only optimized for that
555// type.
556
557void test_constr(mat4& A)
558{
559 A = mat4();
560}
561void test_constr(const vec4& x, mat4& A)
562{
563 A = mat4(x);
564}
565void test_constr(const vec4& x, const vec4& y, const vec4& z, const vec4& w, mat4& A)
566{
567 A = mat4(x, y, z, w);
568}
569void test_constr(const mat4& A, mat3& B)
570{
571 B = mat3(A);
572}
573
574void test_change0(const vec4& x, mat4& A)
575{
576 A[0] = x;
577}
578void test_change2(const vec4& x, mat4& A)
579{
580 A[2] = x;
581}
582void test_extr0(const mat4& A, vec4& x)
583{
584 x = A[0];
585}
586void test_extr2(const mat4& A, vec4& x)
587{
588 x = A[2];
589}
590
591bool test_equal(const mat4& A, const mat4& B)
592{
593 return A == B;
594}
595bool test_not_equal(const mat4& A, const mat4& B)
596{
597 return A != B;
598}
599
600void test_add(const mat4& A, const mat4& B, mat4& C)
601{
602 C = A + B;
603}
604void test_add(const mat4& A, mat4& B)
605{
606 B += A;
607}
608void test_sub(const mat4& A, const mat4& B, mat4& C)
609{
610 C = A - B;
611}
612void test_negate(const mat4& A, mat4& B)
613{
614 B = -A;
615}
616
617void test_mul(float x, const mat4& A, mat4& B)
618{
619 B = x * A;
620}
621void test_mul(const mat4& A, const vec4& x, vec4& y)
622{
623 y = A * x;
624}
625void test_mul(const mat4& A, const mat4& B, mat4& C)
626{
627 C = A * B;
628}
629
630void test_transpose(const mat4& A, mat4& B)
631{
632 B = transpose(A);
633}
634
635void test_determinant(const mat4& A, float& x)
636{
637 x = determinant(A);
638}
639
640void test_inverse(const mat4& A, mat4& B)
641{
642 B = inverse(A);
643}
644
645void test_norm(const mat4& A, float& x)
646{
647 x = norm2_2(A);
648}
649
650#endif
mat23 o23(vec2(2, 3), vec2(4, 0), vec2(6, 7))
matMxN< 2, 3, float > mat23
Definition: gl_mat.cc:17
CHECK(m3==m3)
matMxN< 4, 4, int > imat4
Definition: gl_mat.cc:15
mat23 p23(vec2(2, 3), vec2(4, 5), vec2(0, 7))
mat3 n3(vec3(1, 0, 3), vec3(4, 5, 6), vec3(7, 8, 9))
imat4 k4(ivec4(1, 2, 3, 4), ivec4(3, 4, 0, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
matMxN< 3, 2, float > mat32
Definition: gl_mat.cc:16
imat4 i4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
matMxN< 2, 2, int > imat2
Definition: gl_mat.cc:13
mat32 m32(vec3(2, 3, 4), vec3(5, 6, 7))
mat4 o4(vec4(1, 2, 3, 4), vec4(0, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
mat3 o3(vec3(1, 2, 3), vec3(4, 5, 0), vec3(7, 8, 9))
imat3 l3(ivec3(0, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
imat4 j4(ivec4(1, 0, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
mat4 m4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
TEST_CASE("gl_mat: constructors")
Definition: gl_mat.cc:23
mat4 n4(vec4(1, 2, 0, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
imat3 k3(ivec3(1, 2, 3), ivec3(4, 5, 0), ivec3(7, 8, 9))
imat3 j3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 0, 9))
imat4 h4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(0, 8, 9, 0))
mat23 n23(vec2(0, 3), vec2(4, 5), vec2(6, 7))
mat4 p4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 0, 7, 8), vec4(7, 8, 9, 0))
mat32 o32(vec3(2, 3, 4), vec3(0, 6, 7))
mat3 p3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 0, 9))
mat4 q4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 1))
imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
mat32 n32(vec3(2, 3, 0), vec3(5, 6, 7))
matMxN< 3, 3, int > imat3
Definition: gl_mat.cc:14
imat4 l4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 0), ivec4(7, 8, 9, 0))
mat23 m23(vec2(2, 3), vec2(4, 5), vec2(6, 7))
Definition: gl_mat.hh:23
constexpr T norm2_2(const matMxN< M, N, T > &A)
Definition: gl_mat.hh:321
vecN< 3, float > vec3
Definition: gl_vec.hh:150
vecN< 3, int > ivec3
Definition: gl_vec.hh:153
vecN< 2, int > ivec2
Definition: gl_vec.hh:152
vecN< 2, float > vec2
Definition: gl_vec.hh:149
matMxN< 3, 3, float > mat3
Definition: gl_mat.hh:122
vecN< 4, int > ivec4
Definition: gl_vec.hh:154
matMxN< 4, 4, float > mat4
Definition: gl_mat.hh:123
vecN< 4, float > vec4
Definition: gl_vec.hh:151
matMxN< 2, 2, float > mat2
Definition: gl_mat.hh:121
constexpr matMxN< N, M, T > transpose(const matMxN< M, N, T > &A)
Definition: gl_mat.hh:191
constexpr matMxN< 2, 2, T > inverse(const matMxN< 2, 2, T > &A)
Definition: gl_mat.hh:238
constexpr T determinant(const matMxN< 2, 2, T > &A)
Definition: gl_mat.hh:204
std::array< const EDStorage, 4 > A