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
vecN< 4, int > ivec4
Definition: gl_vec.hh:144
T min_component(const vecN< N, T > &x)
Definition: gl_vec.hh:278
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:343
float rsqrt(float x)
Definition: gl_vec.hh:150
T length2(const vecN< N, T > &x)
Definition: gl_vec.hh:336
vec4 v4(2, 1, -4, -3)
vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:269
imat3 j3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 0, 9))
#define M_PI
Definition: Math.hh:26
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
T degrees(T r)
Definition: gl_vec.hh:164
T radians(T d)
Definition: gl_vec.hh:160
vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:287
T sum(const vecN< N, T > &x)
Definition: gl_vec.hh:310
vecN< 3, T > cross(const vecN< 3, T > &x, const vecN< 3, T > &y)
Definition: gl_vec.hh:357
vecN< 3, int > ivec3
Definition: gl_vec.hh:143
vecN< N, T > recip(const vecN< N, T > &x)
Definition: gl_vec.hh:239
vecN< N, int > round(const vecN< N, T > &x)
Definition: gl_vec.hh:366
vecN< 4, float > vec4
Definition: gl_vec.hh:141
imat4 k4(ivec4(1, 2, 3, 4), ivec4(3, 4, 0, 6), ivec4(5, 6, 7, 8), ivec4(7, 8, 9, 0))
vecN< 2, int > ivec2
Definition: gl_vec.hh:142
T dot(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:324
imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
bool approxEq(T x, T y)
Definition: gl_vec.cc:8
vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
Definition: gl_vec.hh:296
vec3 w3(-1, -2, 2)
vecN< N, T > dot_broadcast(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:329
vecN< 3, float > vec3
Definition: gl_vec.hh:140
CHECK(vec2(1, 2) !=vec2(1, 4))
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1377
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
TEST_CASE("gl_vec: rsqrt")
Definition: gl_vec.cc:19
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))
vecN< N, T > sum_broadcast(const vecN< N, T > &x)
Definition: gl_vec.hh:317
vec4 w4(-1, 2, 2, -6)