openMSX
gl_vec.cc
Go to the documentation of this file.
1 #include "catch.hpp"
2 #include "gl_vec.hh"
3 
4 using namespace gl;
5 
6 // Test approximations.
7 template<typename T>
8 bool approxEq(T x, T y)
9 {
10  return std::abs(x - y) < T(1.0e-5);
11 }
12 template<int N, typename T>
13 bool approxEq(const vecN<N, T>& x, const vecN<N, T>&y)
14 {
15  return length2(x - y) < T(1.0e-4);
16 }
17 
18 
19 TEST_CASE("gl_vec: rsqrt")
20 {
21  CHECK(rsqrt(16.0f) == 0.25f);
22  CHECK(rsqrt(16.0 ) == 0.25 );
23 }
24 
25 TEST_CASE("gl_vec: radians, degrees")
26 {
27  CHECK(approxEq(radians( 0.0), 0.0 ));
28  CHECK(approxEq(radians( 90.0), M_PI / 2));
29  CHECK(approxEq(radians(180.0), M_PI ));
30  CHECK(approxEq(degrees(0.0 ), 0.0));
31  CHECK(approxEq(degrees(M_PI / 2), 90.0));
32  CHECK(approxEq(degrees(M_PI ), 180.0));
33 }
34 
35 // It's useful to test both integer and float variants because the
36 // former are implemented in plain C++ and (only) the latter have SSE
37 // optimizations.
38 
39 TEST_CASE("gl_vec: constructors")
40 {
41  SECTION("default constructor") {
42  vec2 v2;
43  CHECK(v2[0] == 0);
44  CHECK(v2[1] == 0);
45  ivec2 i2;
46  CHECK(i2[0] == 0);
47  CHECK(i2[1] == 0);
48 
49  vec3 v3;
50  CHECK(v3[0] == 0);
51  CHECK(v3[1] == 0);
52  CHECK(v3[2] == 0);
53  ivec3 i3;
54  CHECK(i3[0] == 0);
55  CHECK(i3[1] == 0);
56  CHECK(i3[2] == 0);
57 
58  vec4 v4;
59  CHECK(v4[0] == 0);
60  CHECK(v4[1] == 0);
61  CHECK(v4[2] == 0);
62  CHECK(v4[3] == 0);
63  ivec4 i4;
64  CHECK(i4[0] == 0);
65  CHECK(i4[1] == 0);
66  CHECK(i4[2] == 0);
67  CHECK(i4[3] == 0);
68  }
69  SECTION("broadcast constructor") {
70  vec2 v2(2);
71  CHECK(v2[0] == 2);
72  CHECK(v2[1] == 2);
73  ivec2 i2(2);
74  CHECK(i2[0] == 2);
75  CHECK(i2[1] == 2);
76 
77  vec3 v3(3);
78  CHECK(v3[0] == 3);
79  CHECK(v3[1] == 3);
80  CHECK(v3[2] == 3);
81  ivec3 i3(3);
82  CHECK(i3[0] == 3);
83  CHECK(i3[1] == 3);
84  CHECK(i3[2] == 3);
85 
86  vec4 v4(4);
87  CHECK(v4[0] == 4);
88  CHECK(v4[1] == 4);
89  CHECK(v4[2] == 4);
90  CHECK(v4[3] == 4);
91  ivec4 i4(4);
92  CHECK(i4[0] == 4);
93  CHECK(i4[1] == 4);
94  CHECK(i4[2] == 4);
95  CHECK(i4[3] == 4);
96  }
97  SECTION("per-element constructor") {
98  vec2 v2(2, 3);
99  CHECK(v2[0] == 2);
100  CHECK(v2[1] == 3);
101  ivec2 i2(2, 3);
102  CHECK(i2[0] == 2);
103  CHECK(i2[1] == 3);
104 
105  vec3 v3(3, 4, 5);
106  CHECK(v3[0] == 3);
107  CHECK(v3[1] == 4);
108  CHECK(v3[2] == 5);
109  ivec3 i3(3, 4, 5);
110  CHECK(i3[0] == 3);
111  CHECK(i3[1] == 4);
112  CHECK(i3[2] == 5);
113 
114  vec4 v4(4, 5, 6, 7);
115  CHECK(v4[0] == 4);
116  CHECK(v4[1] == 5);
117  CHECK(v4[2] == 6);
118  CHECK(v4[3] == 7);
119  ivec4 i4(4, 5, 6, 7);
120  CHECK(i4[0] == 4);
121  CHECK(i4[1] == 5);
122  CHECK(i4[2] == 6);
123  CHECK(i4[3] == 7);
124  }
125  SECTION("construct from smaller vectors/scalar") {
126  vec3 v3(3, vec2(4, 5));
127  CHECK(v3[0] == 3);
128  CHECK(v3[1] == 4);
129  CHECK(v3[2] == 5);
130  ivec3 i3(ivec2(4, 5), 3);
131  CHECK(i3[0] == 4);
132  CHECK(i3[1] == 5);
133  CHECK(i3[2] == 3);
134 
135  vec4 v4(4, vec3(5, 6, 7));
136  CHECK(v4[0] == 4);
137  CHECK(v4[1] == 5);
138  CHECK(v4[2] == 6);
139  CHECK(v4[3] == 7);
140  ivec4 i4(ivec3(5, 6, 7), 4);
141  CHECK(i4[0] == 5);
142  CHECK(i4[1] == 6);
143  CHECK(i4[2] == 7);
144  CHECK(i4[3] == 4);
145 
146  vec4 w4(vec2(5, 6), vec2(7, 8));
147  CHECK(w4[0] == 5);
148  CHECK(w4[1] == 6);
149  CHECK(w4[2] == 7);
150  CHECK(w4[3] == 8);
151  ivec4 j4(ivec2(5, 6), ivec2(7, 8));
152  CHECK(j4[0] == 5);
153  CHECK(j4[1] == 6);
154  CHECK(j4[2] == 7);
155  CHECK(j4[3] == 8);
156 
157  #if 0
158  // Not implemeneted yet (also not yet needed).
159  vec4 x4(1, vec2(3, 5), 7);
160  CHECK(x4[0] == 1);
161  CHECK(x4[1] == 3);
162  CHECK(x4[2] == 5);
163  CHECK(x4[3] == 7);
164  ivec4 k4(2, ivec2(4, 6), 8);
165  CHECK(k4[0] == 2);
166  CHECK(k4[1] == 4);
167  CHECK(k4[2] == 6);
168  CHECK(k4[3] == 8);
169  #endif
170 
171  #if 0
172  // Ok, compile error:
173  // static assertion failed: wrong vector length in constructor
174  ivec3 wrong1(3, ivec3(4, 5, 6));
175  ivec4 wrong2(3, ivec2(4, 5));
176  ivec4 wrong3(ivec2(4, 5), ivec3(8, 9));
177  #endif
178  }
179 }
180 
181 TEST_CASE("gl_vec: modify elements")
182 {
183  vec2 v2;
184  v2[0] = 5;
185  CHECK(v2[0] == 5);
186  CHECK(v2[1] == 0);
187  v2[1] = 7;
188  CHECK(v2[0] == 5);
189  CHECK(v2[1] == 7);
190  ivec2 i2;
191  i2[0] = 5;
192  CHECK(i2[0] == 5);
193  CHECK(i2[1] == 0);
194  i2[1] = 7;
195  CHECK(i2[0] == 5);
196  CHECK(i2[1] == 7);
197 
198  vec3 v3(1);
199  v3[1] = 2;
200  CHECK(v3[0] == 1);
201  CHECK(v3[1] == 2);
202  CHECK(v3[2] == 1);
203  ivec3 i3(1);
204  i3[1] = 2;
205  CHECK(i3[0] == 1);
206  CHECK(i3[1] == 2);
207  CHECK(i3[2] == 1);
208 
209  vec4 v4(1, 2, 3, 4);
210  v4[0] = 9; v4[2] = 8;
211  CHECK(v4[0] == 9);
212  CHECK(v4[1] == 2);
213  CHECK(v4[2] == 8);
214  CHECK(v4[3] == 4);
215  ivec4 i4(1, 2, 3, 4);
216  i4[0] = 9; i4[2] = 8;
217  CHECK(i4[0] == 9);
218  CHECK(i4[1] == 2);
219  CHECK(i4[2] == 8);
220  CHECK(i4[3] == 4);
221 }
222 
223 TEST_CASE("gl_vec: (in)equality")
224 {
225  CHECK( vec2(1, 2) == vec2(1, 2));
226  CHECK( vec2(1, 2) != vec2(1, 4));
227  CHECK( vec2(1, 2) != vec2(3, 2));
228  CHECK( vec2(1, 2) != vec2(3, 4));
229  CHECK(ivec2(1, 2) == ivec2(1, 2));
230  CHECK(ivec2(1, 2) != ivec2(1, 4));
231  CHECK(ivec2(1, 2) != ivec2(3, 2));
232  CHECK(ivec2(1, 2) != ivec2(3, 4));
233 
234  CHECK( vec3(1, 2, 3) == vec3(1, 2, 3));
235  CHECK( vec3(1, 2, 3) != vec3(1, 2, 4));
236  CHECK(ivec3(1, 2, 3) == ivec3(1, 2, 3));
237  CHECK(ivec3(1, 2, 3) != ivec3(1, 2, 4));
238 
239  CHECK( vec4(1, 2, 3, 4) == vec4(1, 2, 3, 4));
240  CHECK( vec4(1, 2, 3, 4) != vec4(1, 2, 4, 4));
241  CHECK(ivec4(1, 2, 3, 4) == ivec4(1, 2, 3, 4));
242  CHECK(ivec4(1, 2, 3, 4) != ivec4(1, 2, 4, 4));
243 }
244 
245 TEST_CASE("gl_vec: copy constructor, assignment")
246 {
247  SECTION("vec2") {
248  vec2 v(2, 3);
249  vec2 w(v); CHECK(v == w);
250  v[0] = 9; CHECK(v != w);
251  w = v; CHECK(v == w);
252  }
253  SECTION("ivec2") {
254  ivec2 v(2, 3);
255  ivec2 w(v); CHECK(v == w);
256  v[1] = 9; CHECK(v != w);
257  w = v; CHECK(v == w);
258  }
259  SECTION("vec3") {
260  vec3 v(3, 4, 5);
261  vec3 w(v); CHECK(v == w);
262  v[2] = 8; CHECK(v != w);
263  w = v; CHECK(v == w);
264  }
265  SECTION("ivec3") {
266  ivec3 v(3, 4, 5);
267  ivec3 w(v); CHECK(v == w);
268  v[1] = 8; CHECK(v != w);
269  w = v; CHECK(v == w);
270  }
271  SECTION("vec4") {
272  vec4 v(4, 5, 6, 7);
273  vec4 w(v); CHECK(v == w);
274  v[3] = 0; CHECK(v != w);
275  w = v; CHECK(v == w);
276  }
277  SECTION("ivec4") {
278  ivec4 v(4, 5, 6, 7);
279  ivec4 w(v); CHECK(v == w);
280  v[0] = 1; CHECK(v != w);
281  w = v; CHECK(v == w);
282  }
283 }
284 
285 TEST_CASE("gl_vec: construct from larger vector")
286 {
287  vec4 v4(1, 2, 3, 4);
288  vec3 v3(7, 8, 9);
289  CHECK(vec3(v4) == vec3(1, 2, 3));
290  CHECK(vec2(v4) == vec2(1, 2));
291  CHECK(vec2(v3) == vec2(7, 8));
292 
293  ivec4 i4(1, 2, 3, 4);
294  ivec3 i3(7, 8, 9);
295  CHECK(ivec3(i4) == ivec3(1, 2, 3));
296  CHECK(ivec2(i4) == ivec2(1, 2));
297  CHECK(ivec2(i3) == ivec2(7, 8));
298 }
299 
300 // From here on I'll skip tests on vec2 and ivec2.
301 // Vectors of dimension 2 and 3 are handled by the same C++ code, so
302 // if there's a bug it should show up in both types.
303 
304 TEST_CASE("gl_vec: vector add")
305 {
306  vec3 v3(1, 2, 3); vec4 v4(1, 2, 3, 4);
307  ivec3 i3(1, 2, 3); ivec4 i4(1, 2, 3, 4);
308  CHECK((v3 + vec3(4, 5, 6)) == vec3(5, 7, 9));
309  CHECK((i3 + ivec3(4, 5, 6)) == ivec3(5, 7, 9));
310  CHECK((v4 + vec4(4, 5, 6, 7)) == vec4(5, 7, 9, 11));
311  CHECK((i4 + ivec4(4, 5, 6, 7)) == ivec4(5, 7, 9, 11));
312 
313  v3 += vec3(2, 3, 4);
314  i3 += ivec3(2, 3, 4);
315  v4 += vec4(2, 3, 4, 5);
316  i4 += ivec4(2, 3, 4, 5);
317  CHECK(v3 == vec3(3, 5, 7));
318  CHECK(i3 == ivec3(3, 5, 7));
319  CHECK(v4 == vec4(3, 5, 7, 9));
320  CHECK(i4 == ivec4(3, 5, 7, 9));
321 }
322 
323 TEST_CASE("gl_vec: vector subtract")
324 {
325  vec3 v3(1, 2, 3); vec4 v4(1, 2, 3, 4);
326  ivec3 i3(1, 2, 3); ivec4 i4(1, 2, 3, 4);
327  CHECK((v3 - vec3(4, 3, 2)) == vec3(-3, -1, 1));
328  CHECK((i3 - ivec3(4, 3, 2)) == ivec3(-3, -1, 1));
329  CHECK((v4 - vec4(4, 3, 2, 1)) == vec4(-3, -1, 1, 3));
330  CHECK((i4 - ivec4(4, 3, 2, 1)) == ivec4(-3, -1, 1, 3));
331 
332  v3 -= vec3(2, 4, 6);
333  i3 -= ivec3(2, 4, 6);
334  v4 -= vec4(2, 4, 6, 8);
335  i4 -= ivec4(2, 4, 6, 8);
336  CHECK(v3 == vec3(-1, -2, -3));
337  CHECK(i3 == ivec3(-1, -2, -3));
338  CHECK(v4 == vec4(-1, -2, -3, -4));
339  CHECK(i4 == ivec4(-1, -2, -3, -4));
340 }
341 
342 TEST_CASE("gl_vec: vector negate")
343 {
344  CHECK((- vec3(4, -3, 2)) == vec3(-4, 3, -2));
345  CHECK((-ivec3(4, -3, 2)) == ivec3(-4, 3, -2));
346  CHECK((- vec4(4, -3, 2, -1)) == vec4(-4, 3, -2, 1));
347  CHECK((-ivec4(4, -3, 2, -1)) == ivec4(-4, 3, -2, 1));
348 }
349 
350 TEST_CASE("gl_vec: component-wise vector multiplication")
351 {
352  vec3 v3(0, 2, -3); vec4 v4(0, 2, -3, 4);
353  ivec3 i3(0, 2, -3); ivec4 i4(0, 2, -3, 4);
354  // scalar * vector
355  CHECK((2.0f * v3) == vec3(0, 4, -6));
356  CHECK((2 * i3) == ivec3(0, 4, -6));
357  CHECK((2.0f * v4) == vec4(0, 4, -6, 8));
358  CHECK((2 * i4) == ivec4(0, 4, -6, 8));
359  // vector * scalar
360  CHECK((v3 * 2.0f) == vec3(0, 4, -6));
361  CHECK((i3 * 2 ) == ivec3(0, 4, -6));
362  CHECK((v4 * 2.0f) == vec4(0, 4, -6, 8));
363  CHECK((i4 * 2 ) == ivec4(0, 4, -6, 8));
364  // vector * vector
365  vec3 w3(-1, 2, -3); vec4 w4(-1, 2, -3, -4);
366  ivec3 j3(-1, 2, -3); ivec4 j4(-1, 2, -3, -4);
367  CHECK((v3 * w3) == vec3(0, 4, 9));
368  CHECK((i3 * j3) == ivec3(0, 4, 9));
369  CHECK((v4 * w4) == vec4(0, 4, 9, -16));
370  CHECK((i4 * j4) == ivec4(0, 4, 9, -16));
371  // *= scalar
372  v3 *= 2.0f; CHECK(v3 == vec3(0, 4, -6));
373  i3 *= 2; CHECK(i3 == ivec3(0, 4, -6));
374  v4 *= 2.0f; CHECK(v4 == vec4(0, 4, -6, 8));
375  i4 *= 2; CHECK(i4 == ivec4(0, 4, -6, 8));
376  // *= vector
377  v3 *= w3; CHECK(v3 == vec3(0, 8, 18));
378  i3 *= j3; CHECK(i3 == ivec3(0, 8, 18));
379  v4 *= w4; CHECK(v4 == vec4(0, 8, 18, -32));
380  i4 *= j4; CHECK(i4 == ivec4(0, 8, 18, -32));
381 }
382 
383 TEST_CASE("gl_vec: reciprocal (only floating point)")
384 {
385  CHECK(approxEq(recip(vec3(4, 2, 0.5)), vec3(0.25, 0.5, 2)));
386  CHECK(approxEq(recip(vec4(4, 2, 0.5, 1)), vec4(0.25, 0.5, 2, 1)));
387 }
388 
389 TEST_CASE("gl_vec: component-wise division (only floating point)")
390 {
391  vec3 v3( 0, 1, -4);
392  vec3 w3(-1, -2, 2);
393  CHECK((v3 / 2.0f) == vec3( 0, 0.5f, -2));
394  CHECK((6.0f / w3) == vec3(-6, -3, 3));
395  CHECK((v3 / w3) == vec3( 0, -0.5f, -2));
396 
397  vec4 v4( 2, 1, -4, -3);
398  vec4 w4(-1, 2, 2, -6);
399  CHECK(approxEq((v4 / -2.0f), vec4(-1, -0.5f, 2, 1.5f)));
400  CHECK(approxEq((6.0f / w4), vec4(-6, 3, 3, -1)));
401  CHECK(approxEq((v4 / w4), vec4(-2, 0.5f, -2, 0.5f)));
402 }
403 
404 TEST_CASE("gl_vec: component-wise min/max")
405 {
406  CHECK(min( vec3(2, 3, 4), vec3(1, -5, 7)) == vec3(1, -5, 4));
407  CHECK(min(ivec3(2, 3, 4), ivec3(1, -5, 7)) == ivec3(1, -5, 4));
408  CHECK(min( vec4(1, -2, 5, -7), vec4(0, 2, -4, -3)) == vec4(0, -2, -4, -7));
409  CHECK(min(ivec4(1, -2, 5, -7), ivec4(0, 2, -4, -3)) == ivec4(0, -2, -4, -7));
410 
411  CHECK(max( vec3(2, 3, 4), vec3(1, -5, 7)) == vec3(2, 3, 7));
412  CHECK(max(ivec3(2, 3, 4), ivec3(1, -5, 7)) == ivec3(2, 3, 7));
413  CHECK(max( vec4(1, -2, 5, -7), vec4(0, 2, -4, -3)) == vec4(1, 2, 5, -3));
414  CHECK(max(ivec4(1, -2, 5, -7), ivec4(0, 2, -4, -3)) == ivec4(1, 2, 5, -3));
415 }
416 
417 TEST_CASE("gl_vec: minimum component within a vector")
418 {
419  CHECK(min_component( vec3(1, 5, -7.2f)) == -7.2f);
420  CHECK(min_component(ivec3(3, 2, 4)) == 2);
421  CHECK(min_component( vec4(-1, 2, 5.2f, 0)) == -1);
422  CHECK(min_component(ivec4(1, -2, 5, -7)) == -7);
423 }
424 
425 TEST_CASE("gl_vec: clamp") {
426  CHECK(clamp( vec3(2, 3, 4), vec3(0, 4, -4), vec3(4, 7, 0)) == vec3(2, 4, 0));
427  CHECK(clamp(ivec3(2, 3, 4), ivec3(0, 4, -4), ivec3(4, 7, 0)) == ivec3(2, 4, 0));
428  CHECK(clamp( vec4(4, 2, 7, 1), vec4(0, 3, 2, 1), vec4(4, 6, 8, 3)) == vec4(4, 3, 7, 1));
429  CHECK(clamp(ivec4(4, 2, 7, 1), ivec4(0, 3, 2, 1), ivec4(4, 6, 8, 3)) == ivec4(4, 3, 7, 1));
430 
431  CHECK(clamp( vec3(2, 3, 4), 1.0f, 3.0f) == vec3(2, 3, 3));
432  CHECK(clamp(ivec3(2, 3, 4), 1, 3 ) == ivec3(2, 3, 3));
433  CHECK(clamp( vec4(4, 2, 7, 1), 2.0f, 6.0f) == vec4(4, 2, 6, 2));
434  CHECK(clamp(ivec4(4, 2, 7, 1), 2, 6 ) == ivec4(4, 2, 6, 2));
435 }
436 
437 TEST_CASE("gl_vec: sum of vector components")
438 {
439  CHECK(sum( vec3(4, -3, 2)) == 3.0f);
440  CHECK(sum(ivec3(4, -3, 2)) == 3 );
441  CHECK(sum( vec4(4, -3, 2, -1)) == 2.0f);
442  CHECK(sum(ivec4(4, -3, 2, -1)) == 2 );
443 
444  CHECK(sum_broadcast(vec3(4, -3, 2)) == vec3(3.0f));
445  CHECK(sum_broadcast(vec4(4, -3, 2, -1)) == vec4(2.0f));
446 }
447 
448 TEST_CASE("gl_vec: dot product")
449 {
450  CHECK(dot( vec3(4, -3, 2), vec3(-1, 3, 2) ) == -9.0f);
451  CHECK(dot(ivec3(4, -3, 2), ivec3(-1, 3, 2) ) == -9 );
452  CHECK(dot( vec4(4, -3, 2, -1), vec4(-1, 3, 2, -2)) == -7.0f);
453  CHECK(dot(ivec4(4, -3, 2, -1), ivec4(-1, 3, 2, -2)) == -7 );
454 
455  CHECK(dot_broadcast(vec3(4, -3, 2), vec3(-1, 3, 2) ) == vec3(-9.0f));
456  CHECK(dot_broadcast(vec4(4, -3, 2, -1), vec4(-1, 3, 2, -2)) == vec4(-7.0f));
457 }
458 
459 TEST_CASE("gl_vec: cross product (only for vectors of length 3)")
460 {
461  CHECK(cross( vec3(4, -3, 2), vec3(-1, 3, 2)) == vec3(-12, -10, 9));
462  CHECK(cross(ivec3(4, -3, 2), ivec3(-1, 3, 2)) == ivec3(-12, -10, 9));
463 }
464 
465 TEST_CASE("gl_vec: vector length squared (2-norm squared)")
466 {
467  CHECK(length2( vec3(4, -3, 2 )) == 29.0f);
468  CHECK(length2(ivec3(4, -3, 2 )) == 29 );
469  CHECK(length2( vec4(4, -3, 2, -1)) == 30.0f);
470  CHECK(length2(ivec4(4, -3, 2, -1)) == 30 );
471 }
472 TEST_CASE("gl_vec: vector length (2-norm), (only floating point)")
473 {
474  CHECK(length(vec3(4, -3, 2 )) == sqrtf(29.0f));
475  CHECK(length(vec4(4, -3, 2, -1)) == sqrtf(30.0f));
476 }
477 
478 TEST_CASE("gl_vec: vector normalization, only floating point")
479 {
480  CHECK(normalize(vec3( 0, 4, -3 )) == vec3( 0.0f, 0.8f, -0.6f));
481  CHECK(normalize(vec4(-4, 0, 0, 3)) == vec4(-0.8f, 0.0f, 0.0f, 0.6f));
482 }
483 
484 TEST_CASE("gl_vec: round")
485 {
486  CHECK(round(vec3( 1.1f, 2.6f, -3.8f)) == ivec3( 1, 3, -4));
487  CHECK(round(vec4(-1.1f, 2.4f, 3.8f, -4.6f)) == ivec4(-1, 2, 4, -5));
488  // round integers, nop
489  CHECK(round(ivec4(1, -2, 3, -4)) == ivec4(1, -2, 3, -4));
490 }
491 
492 TEST_CASE("gl_vec: trunc")
493 {
494  CHECK(trunc(vec3( 1.1f, 2.5f, -3.8f)) == ivec3( 1, 2, -3));
495  CHECK(trunc(vec4(-1.1f, 2.5f, 3.8f, -4.5f)) == ivec4(-1, 2, 3, -4));
496  // trunc integers, nop
497  CHECK(trunc(ivec4(1, -2, 3, -4)) == ivec4(1, -2, 3, -4));
498 }
499 
500 
501 #if 0
502 
503 // The following functions are not part of the actual test. They get compiled,
504 // but never executed. I used them to (manually) inspect the quality of the
505 // generated code. Mostly only for vec4, because the code was only optimized
506 // for that type.
507 
508 void test_constr(vec4& z)
509 {
510  z = vec4();
511 }
512 void test_constr(float x, vec4& z)
513 {
514  z = vec4(x);
515 }
516 void test_constr(float a, float b, float c, float d, vec4& z)
517 {
518  z = vec4(a, b, c, d);
519 }
520 
521 void test_change0(float x, vec4& z)
522 {
523  z[0] = x;
524 }
525 void test_change2(float x, vec4& z)
526 {
527  z[2] = x;
528 }
529 
530 void test_extract0(const vec4& x, float& z)
531 {
532  z = x[0];
533 }
534 void test_extract2(const vec4& x, float& z)
535 {
536  z = x[2];
537 }
538 
539 bool test_equal(const vec4& x, const vec4& y)
540 {
541  return x == y;
542 }
543 bool test_not_equal(const vec4& x, const vec4& y)
544 {
545  return x != y;
546 }
547 
548 void test_add(const vec4& x, const vec4& y, vec4& z)
549 {
550  z = x + y;
551 }
552 void test_add(vec4& x, const vec4& y)
553 {
554  x += y;
555 }
556 
557 void test_negate(const vec4& x, vec4& y)
558 {
559  y = -x;
560 }
561 
562 void test_mul(const vec4& x, const vec4& y, vec4& z)
563 {
564  z = x * y;
565 }
566 void test_mul(float x, const vec4& y, vec4& z)
567 {
568  z = x * y;
569 }
570 
571 void test_div(const vec4& x, const vec4& y, vec4& z)
572 {
573  z = x / y;
574 }
575 void test_div(float x, const vec4& y, vec4& z)
576 {
577  z = x / y;
578 }
579 void test_div(const vec4& x, float y, vec4& z)
580 {
581  z = x / y;
582 }
583 
584 void test_sum(const vec4& x, float& y)
585 {
586  y = sum(x);
587 }
588 void test_sum_broadcast(const vec4& x, vec4& y)
589 {
590  y = sum_broadcast(x);
591 }
592 
593 void test_dot(const vec4& x, const vec4& y, float& z)
594 {
595  z = dot(x, y);
596 }
597 void test_dot_broadcast(const vec4& x, const vec4& y, vec4& z)
598 {
599  z = dot_broadcast(x, y);
600 }
601 
602 void test_length2(const vec4& x, float& y)
603 {
604  y = length2(x);
605 }
606 
607 void test_length(const vec4& x, float& y)
608 {
609  y = length(x);
610 }
611 
612 void test_normalize(const vec4& x, vec4& y)
613 {
614  y = normalize(x);
615 }
616 
617 void test_recip(const vec4& x, vec4& y)
618 {
619  y = recip(x);
620 }
621 
622 
623 void test_constr(vec3& z)
624 {
625  z = vec3();
626 }
627 void test_constr(float x, vec3& z)
628 {
629  z = vec3(x);
630 }
631 void test_constr(float a, float b, float c, vec3& z)
632 {
633  z = vec3(a, b, c);
634 }
635 void test_constr(vec4 x, vec3& y)
636 {
637  y = vec3(x);
638 }
639 
640 void test_change0(float x, vec3& z)
641 {
642  z[0] = x;
643 }
644 void test_change2(float x, vec3& z)
645 {
646  z[2] = x;
647 }
648 
649 void test_extract0(const vec3& x, float& z)
650 {
651  z = x[0];
652 }
653 void test_extract2(const vec3& x, float& z)
654 {
655  z = x[2];
656 }
657 
658 bool test_equal(const vec3& x, const vec3& y)
659 {
660  return x == y;
661 }
662 bool test_not_equal(const vec3& x, const vec3& y)
663 {
664  return x != y;
665 }
666 
667 void test_add(const vec3& x, const vec3& y, vec3& z)
668 {
669  z = x + y;
670 }
671 void test_add(vec3& x, const vec3& y)
672 {
673  x += y;
674 }
675 
676 void test_negate(const vec3& x, vec3& y)
677 {
678  y = -x;
679 }
680 
681 void test_mul(const vec3& x, const vec3& y, vec3& z)
682 {
683  z = x * y;
684 }
685 void test_mul(float x, const vec3& y, vec3& z)
686 {
687  z = x * y;
688 }
689 
690 void test_div(const vec3& x, const vec3& y, vec3& z)
691 {
692  z = x / y;
693 }
694 void test_div(float x, const vec3& y, vec3& z)
695 {
696  z = x / y;
697 }
698 void test_div(const vec3& x, float y, vec3& z)
699 {
700  z = x / y;
701 }
702 
703 void test_min(const vec3& x, const vec3& y, vec3& z)
704 {
705  z = min(x, y);
706 }
707 
708 void test_min(const vec4& x, const vec4& y, vec4& z)
709 {
710  z = min(x, y);
711 }
712 
713 void test_clamp(const vec3& x, const vec3& y, const vec3& z, vec3& w)
714 {
715  w = clamp(x, y, z);
716 }
717 
718 void test_clamp(const vec4& x, const vec4& y, const vec4& z, vec4& w)
719 {
720  w = clamp(x, y, z);
721 }
722 
723 void test_clamp(const vec3& x, float y, float z, vec3& w)
724 {
725  w = clamp(x, y, z);
726 }
727 
728 void test_clamp(const vec4& x, float y, float z, vec4& w)
729 {
730  w = clamp(x, y, z);
731 }
732 
733 void test_clamp(const vec4& x, vec4& y)
734 {
735  y = clamp(x, 0.0f, 1.0f);
736 }
737 
738 void test_sum(const vec3& x, float& y)
739 {
740  y = sum(x);
741 }
742 
743 void test_dot(const vec3& x, const vec3& y, float& z)
744 {
745  z = dot(x, y);
746 }
747 
748 void test_length2(const vec3& x, float& y)
749 {
750  y = length2(x);
751 }
752 
753 void test_length(const vec3& x, float& y)
754 {
755  y = length(x);
756 }
757 
758 void test_normalize(const vec3& x, vec3& y)
759 {
760  y = normalize(x);
761 }
762 
763 void test_round(const vec4& x, ivec4& y)
764 {
765  y = round(x);
766 }
767 void test_trunc(const vec4& x, ivec4& y)
768 {
769  y = trunc(x);
770 }
771 
772 #endif
#define M_PI
Definition: Math.hh:27
imat4 k4(ivec4(1, 2, 3, 4), ivec4(3, 4, 0, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
imat4 i4(ivec4(1, 2, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
imat4 j4(ivec4(1, 0, 3, 4), ivec4(3, 4, 5, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
imat3 j3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 0, 9))
imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
CHECK(vec2(1, 2) !=vec2(1, 4))
TEST_CASE("gl_vec: rsqrt")
Definition: gl_vec.cc:19
vec4 v4(2, 1, -4, -3)
vec3 w3(-1, -2, 2)
bool approxEq(T x, T y)
Definition: gl_vec.cc:8
vec4 w4(-1, 2, 2, -6)
Definition: gl_mat.hh:23
vecN< 3, float > vec3
Definition: gl_vec.hh:140
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:269
vecN< 3, int > ivec3
Definition: gl_vec.hh:143
constexpr T min_component(const vecN< N, T > &x)
Definition: gl_vec.hh:278
constexpr T dot(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:324
vecN< 2, int > ivec2
Definition: gl_vec.hh:142
vecN< 2, float > vec2
Definition: gl_vec.hh:139
vecN< 4, int > ivec4
Definition: gl_vec.hh:144
vecN< 4, float > vec4
Definition: gl_vec.hh:141
vecN< N, int > round(const vecN< N, T > &x)
Definition: gl_vec.hh:366
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:343
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:287
constexpr vecN< N, int > trunc(const vecN< N, T > &x)
Definition: gl_vec.hh:378
vecN< N, T > normalize(const vecN< N, T > &x)
Definition: gl_vec.hh:350
constexpr T length2(const vecN< N, T > &x)
Definition: gl_vec.hh:336
constexpr vecN< 3, T > cross(const vecN< 3, T > &x, const vecN< 3, T > &y)
Definition: gl_vec.hh:357
constexpr vecN< N, T > recip(const vecN< N, T > &x)
Definition: gl_vec.hh:239
constexpr T degrees(T r)
Definition: gl_vec.hh:164
constexpr vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
Definition: gl_vec.hh:296
constexpr T sum(const vecN< N, T > &x)
Definition: gl_vec.hh:310
constexpr T radians(T d)
Definition: gl_vec.hh:160
float rsqrt(float x)
Definition: gl_vec.hh:150
constexpr vecN< N, T > sum_broadcast(const vecN< N, T > &x)
Definition: gl_vec.hh:317
constexpr vecN< N, T > dot_broadcast(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:329
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:118