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
502
503#if 0
504
505// The following functions are not part of the actual test. They get compiled,
506// but never executed. I used them to (manually) inspect the quality of the
507// generated code. Mostly only for vec4, because the code was only optimized
508// for that type.
509
510void test_constr(vec4& z)
511{
512 z = vec4();
513}
514void test_constr(float x, vec4& z)
515{
516 z = vec4(x);
517}
518void test_constr(float a, float b, float c, float d, vec4& z)
519{
520 z = vec4(a, b, c, d);
521}
522
523void test_change0(float x, vec4& z)
524{
525 z[0] = x;
526}
527void test_change2(float x, vec4& z)
528{
529 z[2] = x;
530}
531
532void test_extract0(const vec4& x, float& z)
533{
534 z = x[0];
535}
536void test_extract2(const vec4& x, float& z)
537{
538 z = x[2];
539}
540
541bool test_equal(const vec4& x, const vec4& y)
542{
543 return x == y;
544}
545bool test_not_equal(const vec4& x, const vec4& y)
546{
547 return x != y;
548}
549
550void test_add(const vec4& x, const vec4& y, vec4& z)
551{
552 z = x + y;
553}
554void test_add(vec4& x, const vec4& y)
555{
556 x += y;
557}
558
559void test_negate(const vec4& x, vec4& y)
560{
561 y = -x;
562}
563
564void test_mul(const vec4& x, const vec4& y, vec4& z)
565{
566 z = x * y;
567}
568void test_mul(float x, const vec4& y, vec4& z)
569{
570 z = x * y;
571}
572
573void test_div(const vec4& x, const vec4& y, vec4& z)
574{
575 z = x / y;
576}
577void test_div(float x, const vec4& y, vec4& z)
578{
579 z = x / y;
580}
581void test_div(const vec4& x, float y, vec4& z)
582{
583 z = x / y;
584}
585
586void test_sum(const vec4& x, float& y)
587{
588 y = sum(x);
589}
590void test_sum_broadcast(const vec4& x, vec4& y)
591{
592 y = sum_broadcast(x);
593}
594
595void test_dot(const vec4& x, const vec4& y, float& z)
596{
597 z = dot(x, y);
598}
599void test_dot_broadcast(const vec4& x, const vec4& y, vec4& z)
600{
601 z = dot_broadcast(x, y);
602}
603
604void test_length2(const vec4& x, float& y)
605{
606 y = length2(x);
607}
608
609void test_length(const vec4& x, float& y)
610{
611 y = length(x);
612}
613
614void test_normalize(const vec4& x, vec4& y)
615{
616 y = normalize(x);
617}
618
619void test_recip(const vec4& x, vec4& y)
620{
621 y = recip(x);
622}
623
624
625void test_constr(vec3& z)
626{
627 z = vec3();
628}
629void test_constr(float x, vec3& z)
630{
631 z = vec3(x);
632}
633void test_constr(float a, float b, float c, vec3& z)
634{
635 z = vec3(a, b, c);
636}
637void test_constr(vec4 x, vec3& y)
638{
639 y = vec3(x);
640}
641
642void test_change0(float x, vec3& z)
643{
644 z[0] = x;
645}
646void test_change2(float x, vec3& z)
647{
648 z[2] = x;
649}
650
651void test_extract0(const vec3& x, float& z)
652{
653 z = x[0];
654}
655void test_extract2(const vec3& x, float& z)
656{
657 z = x[2];
658}
659
660bool test_equal(const vec3& x, const vec3& y)
661{
662 return x == y;
663}
664bool test_not_equal(const vec3& x, const vec3& y)
665{
666 return x != y;
667}
668
669void test_add(const vec3& x, const vec3& y, vec3& z)
670{
671 z = x + y;
672}
673void test_add(vec3& x, const vec3& y)
674{
675 x += y;
676}
677
678void test_negate(const vec3& x, vec3& y)
679{
680 y = -x;
681}
682
683void test_mul(const vec3& x, const vec3& y, vec3& z)
684{
685 z = x * y;
686}
687void test_mul(float x, const vec3& y, vec3& z)
688{
689 z = x * y;
690}
691
692void test_div(const vec3& x, const vec3& y, vec3& z)
693{
694 z = x / y;
695}
696void test_div(float x, const vec3& y, vec3& z)
697{
698 z = x / y;
699}
700void test_div(const vec3& x, float y, vec3& z)
701{
702 z = x / y;
703}
704
705void test_min(const vec3& x, const vec3& y, vec3& z)
706{
707 z = min(x, y);
708}
709
710void test_min(const vec4& x, const vec4& y, vec4& z)
711{
712 z = min(x, y);
713}
714
715void test_clamp(const vec3& x, const vec3& y, const vec3& z, vec3& w)
716{
717 w = clamp(x, y, z);
718}
719
720void test_clamp(const vec4& x, const vec4& y, const vec4& z, vec4& w)
721{
722 w = clamp(x, y, z);
723}
724
725void test_clamp(const vec3& x, float y, float z, vec3& w)
726{
727 w = clamp(x, y, z);
728}
729
730void test_clamp(const vec4& x, float y, float z, vec4& w)
731{
732 w = clamp(x, y, z);
733}
734
735void test_clamp(const vec4& x, vec4& y)
736{
737 y = clamp(x, 0.0f, 1.0f);
738}
739
740void test_sum(const vec3& x, float& y)
741{
742 y = sum(x);
743}
744
745void test_dot(const vec3& x, const vec3& y, float& z)
746{
747 z = dot(x, y);
748}
749
750void test_length2(const vec3& x, float& y)
751{
752 y = length2(x);
753}
754
755void test_length(const vec3& x, float& y)
756{
757 y = length(x);
758}
759
760void test_normalize(const vec3& x, vec3& y)
761{
762 y = normalize(x);
763}
764
765void test_round(const vec4& x, ivec4& y)
766{
767 y = round(x);
768}
769void test_trunc(const vec4& x, ivec4& y)
770{
771 y = trunc(x);
772}
773
774#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
constexpr double round(double x)
Definition: cstd.hh:247
Definition: gl_mat.hh:23
constexpr vecN< N, T > recip(const vecN< N, T > &x)
Definition: gl_vec.hh:237
constexpr vecN< 3, T > cross(const vecN< 3, T > &x, const vecN< 3, T > &y)
Definition: gl_vec.hh:355
vecN< 3, float > vec3
Definition: gl_vec.hh:151
vecN< 3, int > ivec3
Definition: gl_vec.hh:154
constexpr T min_component(const vecN< N, T > &x)
Definition: gl_vec.hh:276
constexpr T dot(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:322
vecN< 2, int > ivec2
Definition: gl_vec.hh:153
constexpr vecN< N, int > trunc(const vecN< N, T > &x)
Definition: gl_vec.hh:376
vecN< 2, float > vec2
Definition: gl_vec.hh:150
vecN< 4, int > ivec4
Definition: gl_vec.hh:155
vecN< 4, float > vec4
Definition: gl_vec.hh:152
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:341
constexpr T length2(const vecN< N, T > &x)
Definition: gl_vec.hh:334
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:267
constexpr vecN< N, T > dot_broadcast(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:327
constexpr T degrees(T r)
Definition: gl_vec.hh:175
constexpr vecN< N, T > sum_broadcast(const vecN< N, T > &x)
Definition: gl_vec.hh:315
constexpr T radians(T d)
Definition: gl_vec.hh:171
vecN< N, T > normalize(const vecN< N, T > &x)
Definition: gl_vec.hh:348
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:285
float rsqrt(float x)
Definition: gl_vec.hh:161
constexpr vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
Definition: gl_vec.hh:294
auto sum(InputRange &&range, Proj proj={})
Definition: stl.hh:245