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