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  mat2 m2(vec2(2, 3));
259  mat2 n2(m2);
260  CHECK(n2 == m2);
261  m2[1][0] = 9; n2 = m2;
262  CHECK(n2 == m2);
263 
264  imat2 i2(ivec2(2, 3));
265  imat2 j2(i2);
266  CHECK(j2 == i2);
267  i2[0][1] = 9; j2 = i2;
268  CHECK(j2 == i2);
269 
270  mat3 m3(vec3(3, 4, 5));
271  mat3 n3(m3);
272  CHECK(n3 == m3);
273  m3[2][1] = 8; n3 = m3;
274  CHECK(n3 == m3);
275 
276  imat3 i3(ivec3(3, 4, 5));
277  imat3 j3(i3);
278  CHECK(j3 == i3);
279  i3[1][2] = 8; j3 = i3;
280  CHECK(j3 == i3);
281 
282  mat4 m4(vec4(4, 5, 6, 7));
283  mat4 n4(m4);
284  CHECK(n4 == m4);
285  m3[3][1] = 2; n4 = m4;
286  CHECK(n4 == m4);
287 
288  imat4 i4(ivec4(4, 5, 6, 7));
289  imat4 j4(i4);
290  CHECK(i4 == j4);
291  i3[0][1] = 1; j4 = i4;
292  CHECK(i4 == j4);
293 }
294 
295 TEST_CASE("gl_mat: construct from larger matrix")
296 {
297  mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4(7, 8, 9, 1), vec4(1, 0, 0, 0));
298  mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
299  mat2 m2(vec2(1, 2), vec2(4, 5));
300  CHECK(mat3(m4) == m3);
301  CHECK(mat2(m4) == m2);
302  CHECK(mat2(m3) == m2);
303 
304  imat4 i4(ivec4(1, 2, 3, 4), ivec4(4, 5, 6, 7), ivec4(7, 8, 9, 1), ivec4(1, 0, 0, 0));
305  imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9));
306  imat2 i2(ivec2(1, 2), ivec2(4, 5));
307  CHECK(imat3(i4) == i3);
308  CHECK(imat2(i4) == i2);
309  CHECK(imat2(i3) == i2);
310 
311  CHECK(mat32(m4) == mat32(vec3(1, 2, 3), vec3(4, 5, 6)));
312  CHECK(mat32(m3) == mat32(vec3(1, 2, 3), vec3(4, 5, 6)));
313  CHECK(mat23(m4) == mat23(vec2(1, 2), vec2(4, 5), vec2(7, 8)));
314  CHECK(mat23(m3) == mat23(vec2(1, 2), vec2(4, 5), vec2(7, 8)));
315 }
316 
317 TEST_CASE("gl_mat: addition, subtraction, negation")
318 {
319  mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
320  mat3 n3(vec3(2, 4, 6), vec3(1, 3, 5), vec3(7, 8, 9));
321  mat3 o3 = m3 + n3;
322  mat3 p3 = m3 - n3;
323  CHECK(o3 == mat3(vec3( 3, 6, 9), vec3(5, 8, 11), vec3(14, 16, 18)));
324  CHECK(p3 == mat3(vec3(-1, -2, -3), vec3(3, 2, 1), vec3( 0, 0, 0)));
325  p3 += n3;
326  o3 -= n3;
327  CHECK(o3 == m3);
328  CHECK(p3 == m3);
329  CHECK(-m3 == mat3(vec3(-1, -2, -3), vec3(-4, -5, -6), vec3(-7, -8, -9)));
330 
331  imat3 i3(ivec3(6, 3, 0), ivec3(2, 4, 6), ivec3(3, 4, 5));
332  imat3 j3(ivec3(1, 2, 3), ivec3(4, 0, 4), ivec3(0, 1, 1));
333  imat3 k3 = i3 + j3;
334  imat3 l3 = i3 - j3;
335  CHECK(k3 == imat3(ivec3(7, 5, 3), ivec3( 6, 4, 10), ivec3(3, 5, 6)));
336  CHECK(l3 == imat3(ivec3(5, 1, -3), ivec3(-2, 4, 2), ivec3(3, 3, 4)));
337  l3 += j3;
338  k3 -= j3;
339  CHECK(k3 == i3);
340  CHECK(l3 == i3);
341  CHECK(-i3 == imat3(ivec3(-6, -3, -0), ivec3(-2, -4, -6), ivec3(-3, -4, -5)));
342 
343  mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4(7, 8, 9, 1), vec4(1, 0, 0, 0));
344  mat4 n4(vec4(2, 4, 6, 8), vec4(1, 3, 5, 7), vec4(7, 8, 9, 2), vec4(0, 0, 0, 1));
345  mat4 o4 = m4 + n4;
346  mat4 p4 = m4 - n4;
347  CHECK(o4 == mat4(vec4( 3, 6, 9, 12), vec4(5, 8, 11, 14), vec4(14, 16, 18, 3), vec4(1, 0, 0, 1)));
348  CHECK(p4 == mat4(vec4(-1, -2, -3, -4), vec4(3, 2, 1, 0), vec4( 0, 0, 0, -1), vec4(1, 0, 0, -1)));
349  p4 += n4;
350  o4 -= n4;
351  CHECK(o4 == m4);
352  CHECK(p4 == m4);
353  CHECK(-m4 == mat4(vec4(-1, -2, -3, -4), vec4(-4, -5, -6, -7), vec4(-7, -8, -9, -1), vec4(-1, 0, 0, 0)));
354 
355  imat4 i4(ivec4(0, 1, 2, 3), ivec4(4, 3, 2, 1), ivec4(1, 1, 1, 1), ivec4(5, 5, 4, 4));
356  imat4 j4(ivec4(2, 3, 4, 5), ivec4(1, 1, 2, 2), ivec4(0, 0, 1, 2), ivec4(1, 2, 2, 0));
357  imat4 k4 = i4 + j4;
358  imat4 l4 = i4 - j4;
359  CHECK(k4 == imat4(ivec4( 2, 4, 6, 8), ivec4(5, 4, 4, 3), ivec4(1, 1, 2, 3), ivec4(6, 7, 6, 4)));
360  CHECK(l4 == imat4(ivec4(-2, -2, -2, -2), ivec4(3, 2, 0, -1), ivec4(1, 1, 0, -1), ivec4(4, 3, 2, 4)));
361  l4 += j4;
362  k4 -= j4;
363  CHECK(k4 == i4);
364  CHECK(l4 == i4);
365  CHECK(-i4 == imat4(ivec4(0, -1, -2, -3), ivec4(-4, -3, -2, -1), ivec4(-1, -1, -1, -1), ivec4(-5, -5, -4, -4)));
366 
367  mat32 m32(vec3(3, 4, 5), vec3(4, 2, 0));
368  mat32 n32(vec3(1, 1, 2), vec3(4, 4, 3));
369  mat32 o32 = m32 + n32;
370  mat32 p32 = m32 - n32;
371  CHECK(o32 == mat32(vec3(4, 5, 7), vec3(8, 6, 3)));
372  CHECK(p32 == mat32(vec3(2, 3, 3), vec3(0, -2, -3)));
373  p32 += n32;
374  o32 -= n32;
375  CHECK(o32 == m32);
376  CHECK(p32 == m32);
377  CHECK(-m32 == mat32(vec3(-3, -4, -5), vec3(-4, -2, 0)));
378 }
379 
380 TEST_CASE("gl_mat: matrix * scalar")
381 {
382  mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3( 7, 8, 9));
383  mat3 n3(vec3(2, 4, 6), vec3(8, 10, 12), vec3(14, 16, 18));
384  CHECK((2.0f * m3) == n3);
385  CHECK((m3 * 2.0f) == n3);
386  m3 *= 2.0f;
387  CHECK(m3 == n3);
388 
389  imat3 i3(ivec3(2, 1, 0), ivec3(-1, 5, 3), ivec3( 7, 0, -3));
390  imat3 j3(ivec3(4, 2, 0), ivec3(-2, 10, 6), ivec3(14, 0, -6));
391  CHECK((2 * i3) == j3);
392  CHECK((i3 * 2) == j3);
393  i3 *= 2;
394  CHECK(i3 == j3);
395 
396  mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4( 7, 8, 9, 10), vec4(0, 0, -1, -2));
397  mat4 n4(vec4(2, 4, 6, 8), vec4(8, 10, 12, 14), vec4(14, 16, 18, 20), vec4(0, 0, -2, -4));
398  CHECK((2.0f * m4) == n4);
399  CHECK((m4 * 2.0f) == n4);
400  m4 *= 2.0f;
401  CHECK(m4 == n4);
402 
403  imat4 i4(ivec4(0, 1, 2, 3), ivec4(1, 0, 0, 2), ivec4(3, 2, 1, 0), ivec4(0, 0, -1, -2));
404  imat4 j4(ivec4(0, 3, 6, 9), ivec4(3, 0, 0, 6), ivec4(9, 6, 3, 0), ivec4(0, 0, -3, -6));
405  CHECK((3 * i4) == j4);
406  CHECK((i4 * 3) == j4);
407  i4 *= 3;
408  CHECK(i4 == j4);
409 
410  mat32 m32(vec3( 3, 4, 5), vec3( 4, 2, 0));
411  mat32 n32(vec3(-6, -8, -10), vec3(-8, -4, 0));
412  CHECK((-2.0f * m32) == n32);
413  CHECK((m32 * -2.0f) == n32);
414  m32 *= -2.0f;
415  CHECK(m32 == n32);
416 }
417 
418 TEST_CASE("gl_mat: matrix * column-vector")
419 {
420  mat3 m3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
421  CHECK((m3 * vec3(1, 0, 0)) == vec3( 1, 2, 3));
422  CHECK((m3 * vec3(0, 2, 0)) == vec3( 8, 10, 12));
423  CHECK((m3 * vec3(0, 0, 3)) == vec3(21, 24, 27));
424  CHECK((m3 * vec3(1, 2, 3)) == vec3(30, 36, 42));
425 
426  imat3 i3(ivec3(0, -2, 1), ivec3(1, -1, 0), ivec3(-1, -2, 1));
427  CHECK((i3 * ivec3(-1, 0, 0)) == ivec3( 0, 2, -1));
428  CHECK((i3 * ivec3( 0, 0, 0)) == ivec3( 0, 0, 0));
429  CHECK((i3 * ivec3( 0, 0, 3)) == ivec3(-3, -6, 3));
430  CHECK((i3 * ivec3(-1, 0, 3)) == ivec3(-3, -4, 2));
431 
432  mat4 m4(vec4(1, 2, 3, 4), vec4(4, 5, 6, 7), vec4(7, 8, 9, 1), vec4(0, 1, 0, -1));
433  CHECK((m4 * vec4(1, 0, 0, 0)) == vec4( 1, 2, 3, 4));
434  CHECK((m4 * vec4(0, 2, 0, 0)) == vec4( 8, 10, 12, 14));
435  CHECK((m4 * vec4(0, 0, 3, 0)) == vec4(21, 24, 27, 3));
436  CHECK((m4 * vec4(0, 0, 0, 4)) == vec4( 0, 4, 0, -4));
437  CHECK((m4 * vec4(1, 2, 3, 4)) == vec4(30, 40, 42, 17));
438 
439  imat4 i4(ivec4(-1, 2, 0, -3), ivec4(0, 1, 2, -1), ivec4(0, 1, 1, 0), ivec4(-1, 1, 0, -1));
440  CHECK((i4 * ivec4(-1, 0, 0, 0)) == ivec4( 1, -2, 0, 3));
441  CHECK((i4 * ivec4( 0, 2, 0, 0)) == ivec4( 0, 2, 4, -2));
442  CHECK((i4 * ivec4( 0, 0, -2, 0)) == ivec4( 0, -2, -2, 0));
443  CHECK((i4 * ivec4( 0, 0, 0, 1)) == ivec4(-1, 1, 0, -1));
444  CHECK((i4 * ivec4(-1, 2, -2, 1)) == ivec4( 0, -1, 2, 0));
445 
446  mat32 m32(vec3(3, 4, 5), vec3(4, 2, 0));
447  CHECK((m32 * vec2(2, 3)) == vec3(18, 14, 10));
448 
449  mat23 m23(vec2(3, 4), vec2(1, 5), vec2(4, 2));
450  CHECK((m23 * vec3(1, 2, 3)) == vec2(17, 20));
451 }
452 
453 TEST_CASE("gl_mat: matrix * matrix")
454 {
455  mat3 m3(vec3(1, -1, 1), vec3(2, 0, -1), vec3(0, 1, 1));
456  mat3 n3(vec3(1, 1, -1), vec3(0, -2, 1), vec3(1, 0, 1));
457  mat3 o3(vec3(0, -1, 2), vec3(1, 2, -2), vec3(0, 2, 1));
458  CHECK((m3 * n3) == mat3(vec3(3, -2, -1), vec3(-4, 1, 3), vec3(1, 0, 2)));
459  CHECK((n3 * o3) == mat3(vec3(2, 2, 1), vec3(-1, -3, -1), vec3(1, -4, 3)));
460  CHECK(((m3 * n3) * o3) == (m3 * (n3 * o3)));
461 
462  imat3 i3(ivec3( 1, 1, 1), ivec3(-2, 0, -1), ivec3(0, -1, 1));
463  imat3 j3(ivec3(-1, 0, -1), ivec3( 1, -2, 1), ivec3(1, -1, 1));
464  CHECK((i3 * j3) == imat3(ivec3(-1, 0, -2), ivec3(5, 0, 4), ivec3(3, 0, 3)));
465 
466  mat4 m4(vec4(1, -1, 1, 0), vec4(2, 0, -1, 1), vec4(0, 1, 1, -1), vec4(2, 0, 1, -1));
467  mat4 n4(vec4(1, 1, -1, 1), vec4(0, -2, 1, 0), vec4(1, 0, 1, -1), vec4(0, 1, 2, -2));
468  CHECK((m4 * n4) == mat4(vec4(5, -2, 0, 1), vec4(-4, 1, 3, -3), vec4(-1, 0, 1, 0), vec4(-2, 2, -1, 1)));
469  CHECK((n4 * m4) == mat4(vec4(2, 3, -1, 0), vec4( 1, 3, -1, 1), vec4( 1, -3, 0, 1), vec4( 3, 1, -3, 3)));
470 
471  imat4 i4(ivec4(1, -1, 1, 2), ivec4(2, -1, -1, 1), ivec4(2, 1, 1, -1), ivec4( 2, -1, 1, -1));
472  imat4 j4(ivec4(1, 1, -1, 1), ivec4(2, -2, 1, -1), ivec4(1, -2, 1, -1), ivec4(-1, 1, 2, -2));
473  CHECK((i4 * j4) == imat4(ivec4(3, -4, 0, 3), ivec4(-2, 2, 4, 2), ivec4(-3, 3, 3, 0), ivec4(1, 4, -2, -1)));
474 
475  mat32 m32(vec3(1, 2, -1), vec3(-1, -1, 2));
476  mat23 m23(vec2(1, -2), vec2(2, -1), vec2(1, -1));
477  CHECK((m32 * m23) == mat3(vec3(3, 4, -5), vec3(3, 5, -4), vec3(2, 3, -3)));
478  CHECK((m23 * m32) == mat2(vec2(4, -3), vec2(-1, 1)));
479  CHECK((m3 * m32) == mat32(vec3(5, -2, -2), vec3(-3, 3, 2)));
480  CHECK((m23 * m3 ) == mat23(vec2(0, -2), vec2(1, -3), vec2(3, -2)));
481 }
482 
483 TEST_CASE("gl_mat: transpose")
484 {
485  mat3 m3(vec3(1, -1, 1), vec3(2, 0, -1), vec3(0, 1, 1));
486  CHECK(transpose(m3) == mat3(vec3(1, 2, 0), vec3(-1, 0, 1), vec3(1, -1, 1)));
487 
488  imat3 i3(ivec3(1, 1, 1), ivec3(-2, 0, -1), ivec3(0, -1, 1));
489  CHECK(transpose(i3) == imat3(ivec3(1, -2, 0), ivec3(1, 0, -1), ivec3(1, -1, 1)));
490 
491  mat4 m4(vec4(1, -1, 1, 0), vec4(2, 0, -1, 1), vec4(0, 1, 1, -1), vec4(2, 0, 1, -1));
492  CHECK(transpose(m4) == mat4(vec4(1, 2, 0, 2), vec4(-1, 0, 1, 0), vec4(1, -1, 1, 1), vec4(0, 1, -1, -1)));
493 
494  imat4 i4(ivec4(1, -1, 1, 2), ivec4(2, -1, -1, 1), ivec4(2, 1, 1, -1), ivec4(2, -1, 1, -1));
495  CHECK(transpose(i4) == imat4(ivec4(1, 2, 2, 2), ivec4(-1, -1, 1, -1), ivec4(1, -1, 1, 1), ivec4(2, 1, -1, -1)));
496 
497  mat32 m32(vec3(1, 2, 3), vec3(4, 5, 6));
498  mat23 m23(vec2(1, 4), vec2(2, 5), vec2(3, 6));
499  CHECK(transpose(m32) == m23);
500  CHECK(transpose(m23) == m32);
501 }
502 
503 TEST_CASE("gl_mat: determinant, inverse")
504 {
505  mat2 m2(vec2(1, -1), vec2(0, 1));
506  CHECK(determinant(m2) == 1.0f);
507  mat2 i2 = inverse(m2);
508  CHECK(determinant(i2) == 1.0f);
509  CHECK(i2 == mat2(vec2(1, 1), vec2(0, 1)));
510  CHECK(m2 * i2 == mat2());
511  CHECK(i2 * m2 == mat2());
512 
513  mat3 m3(vec3(1, 0, -1), vec3(0, 1, 0), vec3(1, -1, 1));
514  CHECK(determinant(m3) == 2.0f);
515  mat3 i3 = inverse(m3);
516  CHECK(determinant(i3) == 0.5f);
517  CHECK(i3 == mat3(vec3(0.5f, 0.5f, 0.5f), vec3(0, 1, 0), vec3(-0.5f, 0.5f, 0.5f)));
518  CHECK(m3 * i3 == mat3());
519  CHECK(i3 * m3 == mat3());
520 
521  mat4 m4(vec4(0, 1, 1, 0), vec4(-1, 0, 1, 0), vec4(1, 1, 0, -1), vec4(0, 1, 0, 0));
522  CHECK(determinant(m4) == -1.0f);
523  mat4 i4 = inverse(m4);
524  CHECK(approxEq(i4, mat4(vec4(1, -1, 0, -1), vec4(0, 0, 0, 1), vec4(1, 0, 0, -1), vec4(1, -1, -1, 0))));
525  CHECK(approxEq(m4 * i4, mat4()));
526  CHECK(approxEq(i4 * m4, mat4()));
527 }
528 
529 TEST_CASE("gl_mat: norm-2 squared")
530 {
531  mat3 m3(vec3(1, -1, 1), vec3(2, 0, -1), vec3(0, 1, 1));
532  CHECK(norm2_2(m3) == 10);
533 
534  imat3 i3(ivec3(1, 2, 1), ivec3(-2, 3, -1), ivec3(2, 1, 4));
535  CHECK(norm2_2(i3) == 41);
536 
537  mat4 m4(vec4(1, -1, 1, 2), vec4(2, 0, -1, 1), vec4(0, 1, 1, 0), vec4(0, 1, 1, 3));
538  CHECK(norm2_2(m4) == 26);
539 
540  imat4 i4(ivec4(1, 2, 1, -3), ivec4(-2, 3, -1, 0), ivec4(2, 1, 4, -2), ivec4(0, 2, 2, 2));
541  CHECK(norm2_2(i4) == 66);
542 
543  mat32 m32(vec3(1, 2, -1), vec3(-1, -1, 2));
544  mat23 m23(vec2(1, -1), vec2(2, -1), vec2(-1, 2));
545  CHECK(norm2_2(m32) == norm2_2(m23));
546 }
547 
548 
549 #if 0
550 
551 // The following functions are not part of the actual test. They get compiled,
552 // but never executed. I used them to (manually) inspect the quality of the
553 // generated code. Only for mat4, because the code was only optimized for that
554 // type.
555 
556 void test_constr(mat4& A)
557 {
558  A = mat4();
559 }
560 void test_constr(const vec4& x, mat4& A)
561 {
562  A = mat4(x);
563 }
564 void test_constr(const vec4& x, const vec4& y, const vec4& z, const vec4& w, mat4& A)
565 {
566  A = mat4(x, y, z, w);
567 }
568 void test_constr(const mat4& A, mat3& B)
569 {
570  B = mat3(A);
571 }
572 
573 void test_change0(const vec4& x, mat4& A)
574 {
575  A[0] = x;
576 }
577 void test_change2(const vec4& x, mat4& A)
578 {
579  A[2] = x;
580 }
581 void test_extr0(const mat4& A, vec4& x)
582 {
583  x = A[0];
584 }
585 void test_extr2(const mat4& A, vec4& x)
586 {
587  x = A[2];
588 }
589 
590 bool test_equal(const mat4& A, const mat4& B)
591 {
592  return A == B;
593 }
594 bool test_not_equal(const mat4& A, const mat4& B)
595 {
596  return A != B;
597 }
598 
599 void test_add(const mat4& A, const mat4& B, mat4& C)
600 {
601  C = A + B;
602 }
603 void test_add(const mat4& A, mat4& B)
604 {
605  B += A;
606 }
607 void test_sub(const mat4& A, const mat4& B, mat4& C)
608 {
609  C = A - B;
610 }
611 void test_negate(const mat4& A, mat4& B)
612 {
613  B = -A;
614 }
615 
616 void test_mul(float x, const mat4& A, mat4& B)
617 {
618  B = x * A;
619 }
620 void test_mul(const mat4& A, const vec4& x, vec4& y)
621 {
622  y = A * x;
623 }
624 void test_mul(const mat4& A, const mat4& B, mat4& C)
625 {
626  C = A * B;
627 }
628 
629 void test_transpose(const mat4& A, mat4& B)
630 {
631  B = transpose(A);
632 }
633 
634 void test_determinant(const mat4& A, float& x)
635 {
636  x = determinant(A);
637 }
638 
639 void test_inverse(const mat4& A, mat4& B)
640 {
641  B = inverse(A);
642 }
643 
644 void test_norm(const mat4& A, float& x)
645 {
646  x = norm2_2(A);
647 }
648 
649 #endif
matMxN< 3, 3, float > mat3
Definition: gl_mat.hh:158
vecN< 4, int > ivec4
Definition: gl_vec.hh:144
imat3 k3(ivec3(1, 2, 3), ivec3(4, 5, 0), ivec3(7, 8, 9))
mat32 m32(vec3(2, 3, 4), vec3(5, 6, 7))
imat3 j3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 0, 9))
matMxN< 4, 4, float > mat4
Definition: gl_mat.hh:159
mat3 n3(vec3(1, 0, 3), vec3(4, 5, 6), vec3(7, 8, 9))
mat3 p3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 0, 9))
mat4 o4(vec4(1, 2, 3, 4), vec4(0, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
matMxN< 3, 3, int > imat3
Definition: gl_mat.cc:14
T norm2_2(const matMxN< M, N, T > &A)
Definition: gl_mat.hh:376
matMxN< 2, 2, float > mat2
Definition: gl_mat.hh:157
vecN< 3, int > ivec3
Definition: gl_vec.hh:143
matMxN< 4, 4, int > imat4
Definition: gl_mat.cc:15
mat4 n4(vec4(1, 2, 0, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 0))
matMxN< 2, 3, float > mat23
Definition: gl_mat.cc:17
CHECK(m3==m3)
mat23 m23(vec2(2, 3), vec2(4, 5), vec2(6, 7))
mat4 q4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 6, 7, 8), vec4(7, 8, 9, 1))
vecN< 4, float > vec4
Definition: gl_vec.hh:141
T determinant(const matMxN< 2, 2, T > &A)
Definition: gl_mat.hh:259
matMxN< 2, 2, int > imat2
Definition: gl_mat.cc:13
mat23 p23(vec2(2, 3), vec2(4, 5), vec2(0, 7))
imat4 k4(ivec4(1, 2, 3, 4), ivec4(3, 4, 0, 6), ivec4(5, 6, 7, 8), ivec4(7, 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))
vecN< 2, int > ivec2
Definition: gl_vec.hh:142
imat4 h4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(0, 8, 9, 0))
imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
matMxN< 2, 2, T > inverse(const matMxN< 2, 2, T > &A)
Definition: gl_mat.hh:293
mat4 m4(vec4(1, 2, 3, 4), vec4(3, 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))
vecN< 3, float > vec3
Definition: gl_vec.hh:140
matMxN< N, M, T > transpose(const matMxN< M, N, T > &A)
Definition: gl_mat.hh:246
imat4 l4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 0), ivec4(7, 8, 9, 0))
TEST_CASE("gl_mat: constructors")
Definition: gl_mat.cc:23
imat3 l3(ivec3(0, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
matMxN< 3, 2, float > mat32
Definition: gl_mat.cc:16
imat4 j4(ivec4(1, 0, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
vecN< 2, float > vec2
Definition: gl_vec.hh:139
Definition: gl_mat.hh:24
imat4 i4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
mat32 n32(vec3(2, 3, 0), vec3(5, 6, 7))
mat23 o23(vec2(2, 3), vec2(4, 0), vec2(6, 7))
mat32 o32(vec3(2, 3, 4), vec3(0, 6, 7))