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