openMSX
gl_mat.cc
Go to the documentation of this file.
1 #include "catch.hpp"
2 #include "gl_mat.hh"
3 
4 using namespace gl;
5 
6 // Test approximations.
7 static 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 
23 TEST_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 
147 TEST_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 
197 TEST_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));
212  CHECK(i3 == i3);
213  CHECK(i3 != j3);
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));
222  CHECK(m4 == m4);
223  CHECK(m4 != n4);
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));
233  CHECK(i4 == i4);
234  CHECK(i4 != j4);
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));
242  CHECK(m32 == m32);
243  CHECK(m32 != n32);
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));
250  CHECK(m23 == m23);
251  CHECK(m23 != n23);
252  CHECK(m23 != o23);
253  CHECK(m23 != p23);
254 }
255 
256 TEST_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 
296 TEST_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 
318 TEST_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 
381 TEST_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 
419 TEST_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 
454 TEST_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 
484 TEST_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 
504 TEST_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 
530 TEST_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));
546  CHECK(norm2_2(m32) == norm2_2(m23));
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 
557 void test_constr(mat4& A)
558 {
559  A = mat4();
560 }
561 void test_constr(const vec4& x, mat4& A)
562 {
563  A = mat4(x);
564 }
565 void 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 }
569 void test_constr(const mat4& A, mat3& B)
570 {
571  B = mat3(A);
572 }
573 
574 void test_change0(const vec4& x, mat4& A)
575 {
576  A[0] = x;
577 }
578 void test_change2(const vec4& x, mat4& A)
579 {
580  A[2] = x;
581 }
582 void test_extr0(const mat4& A, vec4& x)
583 {
584  x = A[0];
585 }
586 void test_extr2(const mat4& A, vec4& x)
587 {
588  x = A[2];
589 }
590 
591 bool test_equal(const mat4& A, const mat4& B)
592 {
593  return A == B;
594 }
595 bool test_not_equal(const mat4& A, const mat4& B)
596 {
597  return A != B;
598 }
599 
600 void test_add(const mat4& A, const mat4& B, mat4& C)
601 {
602  C = A + B;
603 }
604 void test_add(const mat4& A, mat4& B)
605 {
606  B += A;
607 }
608 void test_sub(const mat4& A, const mat4& B, mat4& C)
609 {
610  C = A - B;
611 }
612 void test_negate(const mat4& A, mat4& B)
613 {
614  B = -A;
615 }
616 
617 void test_mul(float x, const mat4& A, mat4& B)
618 {
619  B = x * A;
620 }
621 void test_mul(const mat4& A, const vec4& x, vec4& y)
622 {
623  y = A * x;
624 }
625 void test_mul(const mat4& A, const mat4& B, mat4& C)
626 {
627  C = A * B;
628 }
629 
630 void test_transpose(const mat4& A, mat4& B)
631 {
632  B = transpose(A);
633 }
634 
635 void test_determinant(const mat4& A, float& x)
636 {
637  x = determinant(A);
638 }
639 
640 void test_inverse(const mat4& A, mat4& B)
641 {
642  B = inverse(A);
643 }
644 
645 void test_norm(const mat4& A, float& x)
646 {
647  x = norm2_2(A);
648 }
649 
650 #endif
n3
mat3 n3(vec3(1, 0, 3), vec3(4, 5, 6), vec3(7, 8, 9))
j4
imat4 j4(ivec4(1, 0, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
gl::ivec3
vecN< 3, int > ivec3
Definition: gl_vec.hh:148
p3
mat3 p3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 0, 9))
gl_mat.hh
openmsx::B
Definition: CPUCore.cc:204
gl::matMxN
Definition: gl_mat.hh:30
gl::transpose
matMxN< N, M, T > transpose(const matMxN< M, N, T > &A)
Definition: gl_mat.hh:246
i4
imat4 i4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
imat3
matMxN< 3, 3, int > imat3
Definition: gl_mat.cc:14
mat23
matMxN< 2, 3, float > mat23
Definition: gl_mat.cc:17
CHECK
CHECK(m3==m3)
n4
mat4 n4(vec4(1, 2, 0, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
openmsx::A
Definition: CPUCore.cc:204
j3
imat3 j3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 0, 9))
q4
mat4 q4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 1))
gl::mat2
matMxN< 2, 2, float > mat2
Definition: gl_mat.hh:157
gl
Definition: gl_mat.hh:24
gl::vecN
Definition: gl_vec.hh:35
n23
mat23 n23(vec2(0, 3), vec2(4, 5), vec2(6, 7))
h4
imat4 h4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(0, 8, 9, 0))
o4
mat4 o4(vec4(1, 2, 3, 4), vec4(0, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
gl::ivec4
vecN< 4, int > ivec4
Definition: gl_vec.hh:149
imat4
matMxN< 4, 4, int > imat4
Definition: gl_mat.cc:15
gl::ivec2
vecN< 2, int > ivec2
Definition: gl_vec.hh:147
gl::vec4
vecN< 4, float > vec4
Definition: gl_vec.hh:146
mat32
matMxN< 3, 2, float > mat32
Definition: gl_mat.cc:16
m23
mat23 m23(vec2(2, 3), vec2(4, 5), vec2(6, 7))
gl::vec3
vecN< 3, float > vec3
Definition: gl_vec.hh:145
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1377
gl::determinant
T determinant(const matMxN< 2, 2, T > &A)
Definition: gl_mat.hh:259
k4
imat4 k4(ivec4(1, 2, 3, 4), ivec4(3, 4, 0, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
gl::inverse
matMxN< 2, 2, T > inverse(const matMxN< 2, 2, T > &A)
Definition: gl_mat.hh:293
imat2
matMxN< 2, 2, int > imat2
Definition: gl_mat.cc:13
p23
mat23 p23(vec2(2, 3), vec2(4, 5), vec2(0, 7))
p4
mat4 p4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 0, 7, 8), vec4(7, 8, 9, 0))
n32
mat32 n32(vec3(2, 3, 0), vec3(5, 6, 7))
o23
mat23 o23(vec2(2, 3), vec2(4, 0), vec2(6, 7))
gl::vec2
vecN< 2, float > vec2
Definition: gl_vec.hh:144
i3
imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
o32
mat32 o32(vec3(2, 3, 4), vec3(0, 6, 7))
m32
mat32 m32(vec3(2, 3, 4), vec3(5, 6, 7))
gl::norm2_2
T norm2_2(const matMxN< M, N, T > &A)
Definition: gl_mat.hh:376
k3
imat3 k3(ivec3(1, 2, 3), ivec3(4, 5, 0), ivec3(7, 8, 9))
gl::mat3
matMxN< 3, 3, float > mat3
Definition: gl_mat.hh:158
gl::mat4
matMxN< 4, 4, float > mat4
Definition: gl_mat.hh:159
m4
mat4 m4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
openmsx::C
Definition: CPUCore.cc:204
o3
mat3 o3(vec3(1, 2, 3), vec3(4, 5, 0), vec3(7, 8, 9))
l3
imat3 l3(ivec3(0, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
l4
imat4 l4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 0), ivec4(7, 8, 9, 0))
TEST_CASE
TEST_CASE("gl_mat: constructors")
Definition: gl_mat.cc:23