1 /*
2 * Copyright 1993-2010 NVIDIA Corporation. All rights reserved.
3 *
4 * Please refer to the NVIDIA end user license agreement (EULA) associated
5 * with this source code for terms and conditions that govern your use of
6 * this software. Any use, reproduction, disclosure, or distribution of
7 * this software and related documentation outside the terms of the EULA
8 * is strictly prohibited.
9 *
10 */
11
12 /*
13 This file implements common mathematical operations on vector types
14 (float3, float4 etc.) since these are not provided as standard by CUDA.
15
16 The syntax is modelled on the Cg standard library.
17
18 This is part of the CUTIL library and is not supported by NVIDIA.
19
20 Thanks to Linh Hah for additions and fixes.
21 */
22
23 /*
24 This file (cutil_math.h) has been modified by Andreas Schuh to add the
25 MIRTKCU_API modifier and embed it into the MIRTK namespace.
26 */
27
28 #ifndef MIRTK_CutilMath_H
29 #define MIRTK_CutilMath_H
30
31 #if !defined(__CUDACC__)
32 # include <cmath>
33 # include <cstdlib>
34 # include <algorithm>
35 #endif
36
37 #include "mirtk/Config.h" // MIRTKCU_API
38 #include "mirtk/CudaRuntime.h"
39
40
41 namespace mirtk {
42
43 ////////////////////////////////////////////////////////////////////////////////
44 // Standard C library functions for built-in types
45 ////////////////////////////////////////////////////////////////////////////////
46
47 using ::floorf;
48 using ::fmodf;
49 using ::fabs;
50
51 using std::abs;
52 using std::min;
53 using std::max;
54
55 ////////////////////////////////////////////////////////////////////////////////
56 // host implementations of CUDA functions
57 ////////////////////////////////////////////////////////////////////////////////
58 #if !defined(__CUDACC__)
59
fminf(float a,float b)60 inline float fminf(float a, float b)
61 {
62 return a < b ? a : b;
63 }
64
fmaxf(float a,float b)65 inline float fmaxf(float a, float b)
66 {
67 return a > b ? a : b;
68 }
69
rsqrtf(float x)70 inline float rsqrtf(float x)
71 {
72 return 1.0f / sqrtf(x);
73 }
74
75 #endif // !defined(__CUDACC__)
76 ////////////////////////////////////////////////////////////////////////////////
77 // constructors
78 ////////////////////////////////////////////////////////////////////////////////
79
make_float2(float s)80 MIRTKCU_API inline float2 make_float2(float s)
81 {
82 return make_float2(s, s);
83 }
make_float2(float3 a)84 MIRTKCU_API inline float2 make_float2(float3 a)
85 {
86 return make_float2(a.x, a.y);
87 }
make_float2(int2 a)88 MIRTKCU_API inline float2 make_float2(int2 a)
89 {
90 return make_float2(float(a.x), float(a.y));
91 }
make_float2(uint2 a)92 MIRTKCU_API inline float2 make_float2(uint2 a)
93 {
94 return make_float2(float(a.x), float(a.y));
95 }
96
make_int2(int s)97 MIRTKCU_API inline int2 make_int2(int s)
98 {
99 return make_int2(s, s);
100 }
make_int2(int3 a)101 MIRTKCU_API inline int2 make_int2(int3 a)
102 {
103 return make_int2(a.x, a.y);
104 }
make_int2(uint2 a)105 MIRTKCU_API inline int2 make_int2(uint2 a)
106 {
107 return make_int2(int(a.x), int(a.y));
108 }
make_int2(float2 a)109 MIRTKCU_API inline int2 make_int2(float2 a)
110 {
111 return make_int2(int(a.x), int(a.y));
112 }
113
make_uint2(uint s)114 MIRTKCU_API inline uint2 make_uint2(uint s)
115 {
116 return make_uint2(s, s);
117 }
make_uint2(uint3 a)118 MIRTKCU_API inline uint2 make_uint2(uint3 a)
119 {
120 return make_uint2(a.x, a.y);
121 }
make_uint2(int2 a)122 MIRTKCU_API inline uint2 make_uint2(int2 a)
123 {
124 return make_uint2(uint(a.x), uint(a.y));
125 }
126
make_float3(float s)127 MIRTKCU_API inline float3 make_float3(float s)
128 {
129 return make_float3(s, s, s);
130 }
make_float3(float2 a)131 MIRTKCU_API inline float3 make_float3(float2 a)
132 {
133 return make_float3(a.x, a.y, 0.0f);
134 }
make_float3(float2 a,float s)135 MIRTKCU_API inline float3 make_float3(float2 a, float s)
136 {
137 return make_float3(a.x, a.y, s);
138 }
make_float3(float4 a)139 MIRTKCU_API inline float3 make_float3(float4 a)
140 {
141 return make_float3(a.x, a.y, a.z);
142 }
make_float3(int3 a)143 MIRTKCU_API inline float3 make_float3(int3 a)
144 {
145 return make_float3(float(a.x), float(a.y), float(a.z));
146 }
make_float3(uint3 a)147 MIRTKCU_API inline float3 make_float3(uint3 a)
148 {
149 return make_float3(float(a.x), float(a.y), float(a.z));
150 }
151
make_int3(int s)152 MIRTKCU_API inline int3 make_int3(int s)
153 {
154 return make_int3(s, s, s);
155 }
make_int3(int2 a)156 MIRTKCU_API inline int3 make_int3(int2 a)
157 {
158 return make_int3(a.x, a.y, 0);
159 }
make_int3(int2 a,int s)160 MIRTKCU_API inline int3 make_int3(int2 a, int s)
161 {
162 return make_int3(a.x, a.y, s);
163 }
make_int3(uint3 a)164 MIRTKCU_API inline int3 make_int3(uint3 a)
165 {
166 return make_int3(int(a.x), int(a.y), int(a.z));
167 }
make_int3(float3 a)168 MIRTKCU_API inline int3 make_int3(float3 a)
169 {
170 return make_int3(int(a.x), int(a.y), int(a.z));
171 }
172
make_uint3(uint s)173 MIRTKCU_API inline uint3 make_uint3(uint s)
174 {
175 return make_uint3(s, s, s);
176 }
make_uint3(uint2 a)177 MIRTKCU_API inline uint3 make_uint3(uint2 a)
178 {
179 return make_uint3(a.x, a.y, 0);
180 }
make_uint3(uint2 a,uint s)181 MIRTKCU_API inline uint3 make_uint3(uint2 a, uint s)
182 {
183 return make_uint3(a.x, a.y, s);
184 }
make_uint3(uint4 a)185 MIRTKCU_API inline uint3 make_uint3(uint4 a)
186 {
187 return make_uint3(a.x, a.y, a.z);
188 }
make_uint3(int3 a)189 MIRTKCU_API inline uint3 make_uint3(int3 a)
190 {
191 return make_uint3(uint(a.x), uint(a.y), uint(a.z));
192 }
193
make_float4(float s)194 MIRTKCU_API inline float4 make_float4(float s)
195 {
196 return make_float4(s, s, s, s);
197 }
make_float4(float3 a)198 MIRTKCU_API inline float4 make_float4(float3 a)
199 {
200 return make_float4(a.x, a.y, a.z, 0.0f);
201 }
make_float4(float3 a,float w)202 MIRTKCU_API inline float4 make_float4(float3 a, float w)
203 {
204 return make_float4(a.x, a.y, a.z, w);
205 }
make_float4(int4 a)206 MIRTKCU_API inline float4 make_float4(int4 a)
207 {
208 return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
209 }
make_float4(uint4 a)210 MIRTKCU_API inline float4 make_float4(uint4 a)
211 {
212 return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
213 }
214
make_int4(int s)215 MIRTKCU_API inline int4 make_int4(int s)
216 {
217 return make_int4(s, s, s, s);
218 }
make_int4(int3 a)219 MIRTKCU_API inline int4 make_int4(int3 a)
220 {
221 return make_int4(a.x, a.y, a.z, 0);
222 }
make_int4(int3 a,int w)223 MIRTKCU_API inline int4 make_int4(int3 a, int w)
224 {
225 return make_int4(a.x, a.y, a.z, w);
226 }
make_int4(uint4 a)227 MIRTKCU_API inline int4 make_int4(uint4 a)
228 {
229 return make_int4(int(a.x), int(a.y), int(a.z), int(a.w));
230 }
make_int4(float4 a)231 MIRTKCU_API inline int4 make_int4(float4 a)
232 {
233 return make_int4(int(a.x), int(a.y), int(a.z), int(a.w));
234 }
235
236
make_uint4(uint s)237 MIRTKCU_API inline uint4 make_uint4(uint s)
238 {
239 return make_uint4(s, s, s, s);
240 }
make_uint4(uint3 a)241 MIRTKCU_API inline uint4 make_uint4(uint3 a)
242 {
243 return make_uint4(a.x, a.y, a.z, 0);
244 }
make_uint4(uint3 a,uint w)245 MIRTKCU_API inline uint4 make_uint4(uint3 a, uint w)
246 {
247 return make_uint4(a.x, a.y, a.z, w);
248 }
make_uint4(int4 a)249 MIRTKCU_API inline uint4 make_uint4(int4 a)
250 {
251 return make_uint4(uint(a.x), uint(a.y), uint(a.z), uint(a.w));
252 }
253
254 ////////////////////////////////////////////////////////////////////////////////
255 // negate
256 ////////////////////////////////////////////////////////////////////////////////
257
258 MIRTKCU_API inline float2 operator-(float2 &a)
259 {
260 return make_float2(-a.x, -a.y);
261 }
262 MIRTKCU_API inline int2 operator-(int2 &a)
263 {
264 return make_int2(-a.x, -a.y);
265 }
266 MIRTKCU_API inline float3 operator-(float3 &a)
267 {
268 return make_float3(-a.x, -a.y, -a.z);
269 }
270 MIRTKCU_API inline int3 operator-(int3 &a)
271 {
272 return make_int3(-a.x, -a.y, -a.z);
273 }
274 MIRTKCU_API inline float4 operator-(float4 &a)
275 {
276 return make_float4(-a.x, -a.y, -a.z, -a.w);
277 }
278 MIRTKCU_API inline int4 operator-(int4 &a)
279 {
280 return make_int4(-a.x, -a.y, -a.z, -a.w);
281 }
282
283 ////////////////////////////////////////////////////////////////////////////////
284 // addition
285 ////////////////////////////////////////////////////////////////////////////////
286
287 MIRTKCU_API inline float2 operator+(float2 a, float2 b)
288 {
289 return make_float2(a.x + b.x, a.y + b.y);
290 }
291 MIRTKCU_API inline void operator+=(float2 &a, float2 b)
292 {
293 a.x += b.x; a.y += b.y;
294 }
295 MIRTKCU_API inline float2 operator+(float2 a, float b)
296 {
297 return make_float2(a.x + b, a.y + b);
298 }
299 MIRTKCU_API inline float2 operator+(float b, float2 a)
300 {
301 return make_float2(a.x + b, a.y + b);
302 }
303 MIRTKCU_API inline void operator+=(float2 &a, float b)
304 {
305 a.x += b; a.y += b;
306 }
307
308 MIRTKCU_API inline int2 operator+(int2 a, int2 b)
309 {
310 return make_int2(a.x + b.x, a.y + b.y);
311 }
312 MIRTKCU_API inline void operator+=(int2 &a, int2 b)
313 {
314 a.x += b.x; a.y += b.y;
315 }
316 MIRTKCU_API inline int2 operator+(int2 a, int b)
317 {
318 return make_int2(a.x + b, a.y + b);
319 }
320 MIRTKCU_API inline int2 operator+(int b, int2 a)
321 {
322 return make_int2(a.x + b, a.y + b);
323 }
324 MIRTKCU_API inline void operator+=(int2 &a, int b)
325 {
326 a.x += b; a.y += b;
327 }
328
329 MIRTKCU_API inline uint2 operator+(uint2 a, uint2 b)
330 {
331 return make_uint2(a.x + b.x, a.y + b.y);
332 }
333 MIRTKCU_API inline void operator+=(uint2 &a, uint2 b)
334 {
335 a.x += b.x; a.y += b.y;
336 }
337 MIRTKCU_API inline uint2 operator+(uint2 a, uint b)
338 {
339 return make_uint2(a.x + b, a.y + b);
340 }
341 MIRTKCU_API inline uint2 operator+(uint b, uint2 a)
342 {
343 return make_uint2(a.x + b, a.y + b);
344 }
345 MIRTKCU_API inline void operator+=(uint2 &a, uint b)
346 {
347 a.x += b; a.y += b;
348 }
349
350
351 MIRTKCU_API inline float3 operator+(float3 a, float3 b)
352 {
353 return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
354 }
355 MIRTKCU_API inline void operator+=(float3 &a, float3 b)
356 {
357 a.x += b.x; a.y += b.y; a.z += b.z;
358 }
359 MIRTKCU_API inline float3 operator+(float3 a, float b)
360 {
361 return make_float3(a.x + b, a.y + b, a.z + b);
362 }
363 MIRTKCU_API inline void operator+=(float3 &a, float b)
364 {
365 a.x += b; a.y += b; a.z += b;
366 }
367
368 MIRTKCU_API inline int3 operator+(int3 a, int3 b)
369 {
370 return make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
371 }
372 MIRTKCU_API inline void operator+=(int3 &a, int3 b)
373 {
374 a.x += b.x; a.y += b.y; a.z += b.z;
375 }
376 MIRTKCU_API inline int3 operator+(int3 a, int b)
377 {
378 return make_int3(a.x + b, a.y + b, a.z + b);
379 }
380 MIRTKCU_API inline void operator+=(int3 &a, int b)
381 {
382 a.x += b; a.y += b; a.z += b;
383 }
384
385 MIRTKCU_API inline uint3 operator+(uint3 a, uint3 b)
386 {
387 return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z);
388 }
389 MIRTKCU_API inline void operator+=(uint3 &a, uint3 b)
390 {
391 a.x += b.x; a.y += b.y; a.z += b.z;
392 }
393 MIRTKCU_API inline uint3 operator+(uint3 a, uint b)
394 {
395 return make_uint3(a.x + b, a.y + b, a.z + b);
396 }
397 MIRTKCU_API inline void operator+=(uint3 &a, uint b)
398 {
399 a.x += b; a.y += b; a.z += b;
400 }
401
402 MIRTKCU_API inline int3 operator+(int b, int3 a)
403 {
404 return make_int3(a.x + b, a.y + b, a.z + b);
405 }
406 MIRTKCU_API inline uint3 operator+(uint b, uint3 a)
407 {
408 return make_uint3(a.x + b, a.y + b, a.z + b);
409 }
410 MIRTKCU_API inline float3 operator+(float b, float3 a)
411 {
412 return make_float3(a.x + b, a.y + b, a.z + b);
413 }
414
415 MIRTKCU_API inline float4 operator+(float4 a, float4 b)
416 {
417 return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
418 }
419 MIRTKCU_API inline void operator+=(float4 &a, float4 b)
420 {
421 a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
422 }
423 MIRTKCU_API inline float4 operator+(float4 a, float b)
424 {
425 return make_float4(a.x + b, a.y + b, a.z + b, a.w + b);
426 }
427 MIRTKCU_API inline float4 operator+(float b, float4 a)
428 {
429 return make_float4(a.x + b, a.y + b, a.z + b, a.w + b);
430 }
431 MIRTKCU_API inline void operator+=(float4 &a, float b)
432 {
433 a.x += b; a.y += b; a.z += b; a.w += b;
434 }
435
436 MIRTKCU_API inline int4 operator+(int4 a, int4 b)
437 {
438 return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
439 }
440 MIRTKCU_API inline void operator+=(int4 &a, int4 b)
441 {
442 a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
443 }
444 MIRTKCU_API inline int4 operator+(int4 a, int b)
445 {
446 return make_int4(a.x + b, a.y + b, a.z + b, a.w + b);
447 }
448 MIRTKCU_API inline int4 operator+(int b, int4 a)
449 {
450 return make_int4(a.x + b, a.y + b, a.z + b, a.w + b);
451 }
452 MIRTKCU_API inline void operator+=(int4 &a, int b)
453 {
454 a.x += b; a.y += b; a.z += b; a.w += b;
455 }
456
457 MIRTKCU_API inline uint4 operator+(uint4 a, uint4 b)
458 {
459 return make_uint4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
460 }
461 MIRTKCU_API inline void operator+=(uint4 &a, uint4 b)
462 {
463 a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
464 }
465 MIRTKCU_API inline uint4 operator+(uint4 a, uint b)
466 {
467 return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b);
468 }
469 MIRTKCU_API inline uint4 operator+(uint b, uint4 a)
470 {
471 return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b);
472 }
473 MIRTKCU_API inline void operator+=(uint4 &a, uint b)
474 {
475 a.x += b; a.y += b; a.z += b; a.w += b;
476 }
477
478 ////////////////////////////////////////////////////////////////////////////////
479 // subtract
480 ////////////////////////////////////////////////////////////////////////////////
481
482 MIRTKCU_API inline float2 operator-(float2 a, float2 b)
483 {
484 return make_float2(a.x - b.x, a.y - b.y);
485 }
486 MIRTKCU_API inline void operator-=(float2 &a, float2 b)
487 {
488 a.x -= b.x; a.y -= b.y;
489 }
490 MIRTKCU_API inline float2 operator-(float2 a, float b)
491 {
492 return make_float2(a.x - b, a.y - b);
493 }
494 MIRTKCU_API inline float2 operator-(float b, float2 a)
495 {
496 return make_float2(b - a.x, b - a.y);
497 }
498 MIRTKCU_API inline void operator-=(float2 &a, float b)
499 {
500 a.x -= b; a.y -= b;
501 }
502
503 MIRTKCU_API inline int2 operator-(int2 a, int2 b)
504 {
505 return make_int2(a.x - b.x, a.y - b.y);
506 }
507 MIRTKCU_API inline void operator-=(int2 &a, int2 b)
508 {
509 a.x -= b.x; a.y -= b.y;
510 }
511 MIRTKCU_API inline int2 operator-(int2 a, int b)
512 {
513 return make_int2(a.x - b, a.y - b);
514 }
515 MIRTKCU_API inline int2 operator-(int b, int2 a)
516 {
517 return make_int2(b - a.x, b - a.y);
518 }
519 MIRTKCU_API inline void operator-=(int2 &a, int b)
520 {
521 a.x -= b; a.y -= b;
522 }
523
524 MIRTKCU_API inline uint2 operator-(uint2 a, uint2 b)
525 {
526 return make_uint2(a.x - b.x, a.y - b.y);
527 }
528 MIRTKCU_API inline void operator-=(uint2 &a, uint2 b)
529 {
530 a.x -= b.x; a.y -= b.y;
531 }
532 MIRTKCU_API inline uint2 operator-(uint2 a, uint b)
533 {
534 return make_uint2(a.x - b, a.y - b);
535 }
536 MIRTKCU_API inline uint2 operator-(uint b, uint2 a)
537 {
538 return make_uint2(b - a.x, b - a.y);
539 }
540 MIRTKCU_API inline void operator-=(uint2 &a, uint b)
541 {
542 a.x -= b; a.y -= b;
543 }
544
545 MIRTKCU_API inline float3 operator-(float3 a, float3 b)
546 {
547 return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
548 }
549 MIRTKCU_API inline void operator-=(float3 &a, float3 b)
550 {
551 a.x -= b.x; a.y -= b.y; a.z -= b.z;
552 }
553 MIRTKCU_API inline float3 operator-(float3 a, float b)
554 {
555 return make_float3(a.x - b, a.y - b, a.z - b);
556 }
557 MIRTKCU_API inline float3 operator-(float b, float3 a)
558 {
559 return make_float3(b - a.x, b - a.y, b - a.z);
560 }
561 MIRTKCU_API inline void operator-=(float3 &a, float b)
562 {
563 a.x -= b; a.y -= b; a.z -= b;
564 }
565
566 MIRTKCU_API inline int3 operator-(int3 a, int3 b)
567 {
568 return make_int3(a.x - b.x, a.y - b.y, a.z - b.z);
569 }
570 MIRTKCU_API inline void operator-=(int3 &a, int3 b)
571 {
572 a.x -= b.x; a.y -= b.y; a.z -= b.z;
573 }
574 MIRTKCU_API inline int3 operator-(int3 a, int b)
575 {
576 return make_int3(a.x - b, a.y - b, a.z - b);
577 }
578 MIRTKCU_API inline int3 operator-(int b, int3 a)
579 {
580 return make_int3(b - a.x, b - a.y, b - a.z);
581 }
582 MIRTKCU_API inline void operator-=(int3 &a, int b)
583 {
584 a.x -= b; a.y -= b; a.z -= b;
585 }
586
587 MIRTKCU_API inline uint3 operator-(uint3 a, uint3 b)
588 {
589 return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z);
590 }
591 MIRTKCU_API inline void operator-=(uint3 &a, uint3 b)
592 {
593 a.x -= b.x; a.y -= b.y; a.z -= b.z;
594 }
595 MIRTKCU_API inline uint3 operator-(uint3 a, uint b)
596 {
597 return make_uint3(a.x - b, a.y - b, a.z - b);
598 }
599 MIRTKCU_API inline uint3 operator-(uint b, uint3 a)
600 {
601 return make_uint3(b - a.x, b - a.y, b - a.z);
602 }
603 MIRTKCU_API inline void operator-=(uint3 &a, uint b)
604 {
605 a.x -= b; a.y -= b; a.z -= b;
606 }
607
608 MIRTKCU_API inline float4 operator-(float4 a, float4 b)
609 {
610 return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
611 }
612 MIRTKCU_API inline void operator-=(float4 &a, float4 b)
613 {
614 a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
615 }
616 MIRTKCU_API inline float4 operator-(float4 a, float b)
617 {
618 return make_float4(a.x - b, a.y - b, a.z - b, a.w - b);
619 }
620 MIRTKCU_API inline void operator-=(float4 &a, float b)
621 {
622 a.x -= b; a.y -= b; a.z -= b; a.w -= b;
623 }
624
625 MIRTKCU_API inline int4 operator-(int4 a, int4 b)
626 {
627 return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
628 }
629 MIRTKCU_API inline void operator-=(int4 &a, int4 b)
630 {
631 a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
632 }
633 MIRTKCU_API inline int4 operator-(int4 a, int b)
634 {
635 return make_int4(a.x - b, a.y - b, a.z - b, a.w - b);
636 }
637 MIRTKCU_API inline int4 operator-(int b, int4 a)
638 {
639 return make_int4(b - a.x, b - a.y, b - a.z, b - a.w);
640 }
641 MIRTKCU_API inline void operator-=(int4 &a, int b)
642 {
643 a.x -= b; a.y -= b; a.z -= b; a.w -= b;
644 }
645
646 MIRTKCU_API inline uint4 operator-(uint4 a, uint4 b)
647 {
648 return make_uint4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
649 }
650 MIRTKCU_API inline void operator-=(uint4 &a, uint4 b)
651 {
652 a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
653 }
654 MIRTKCU_API inline uint4 operator-(uint4 a, uint b)
655 {
656 return make_uint4(a.x - b, a.y - b, a.z - b, a.w - b);
657 }
658 MIRTKCU_API inline uint4 operator-(uint b, uint4 a)
659 {
660 return make_uint4(b - a.x, b - a.y, b - a.z, b - a.w);
661 }
662 MIRTKCU_API inline void operator-=(uint4 &a, uint b)
663 {
664 a.x -= b; a.y -= b; a.z -= b; a.w -= b;
665 }
666
667 ////////////////////////////////////////////////////////////////////////////////
668 // multiply
669 ////////////////////////////////////////////////////////////////////////////////
670
671 MIRTKCU_API inline float2 operator*(float2 a, float2 b)
672 {
673 return make_float2(a.x * b.x, a.y * b.y);
674 }
675 MIRTKCU_API inline void operator*=(float2 &a, float2 b)
676 {
677 a.x *= b.x; a.y *= b.y;
678 }
679 MIRTKCU_API inline float2 operator*(float2 a, float b)
680 {
681 return make_float2(a.x * b, a.y * b);
682 }
683 MIRTKCU_API inline float2 operator*(float b, float2 a)
684 {
685 return make_float2(b * a.x, b * a.y);
686 }
687 MIRTKCU_API inline void operator*=(float2 &a, float b)
688 {
689 a.x *= b; a.y *= b;
690 }
691
692 MIRTKCU_API inline int2 operator*(int2 a, int2 b)
693 {
694 return make_int2(a.x * b.x, a.y * b.y);
695 }
696 MIRTKCU_API inline void operator*=(int2 &a, int2 b)
697 {
698 a.x *= b.x; a.y *= b.y;
699 }
700 MIRTKCU_API inline int2 operator*(int2 a, int b)
701 {
702 return make_int2(a.x * b, a.y * b);
703 }
704 MIRTKCU_API inline int2 operator*(int b, int2 a)
705 {
706 return make_int2(b * a.x, b * a.y);
707 }
708 MIRTKCU_API inline void operator*=(int2 &a, int b)
709 {
710 a.x *= b; a.y *= b;
711 }
712
713 MIRTKCU_API inline uint2 operator*(uint2 a, uint2 b)
714 {
715 return make_uint2(a.x * b.x, a.y * b.y);
716 }
717 MIRTKCU_API inline void operator*=(uint2 &a, uint2 b)
718 {
719 a.x *= b.x; a.y *= b.y;
720 }
721 MIRTKCU_API inline uint2 operator*(uint2 a, uint b)
722 {
723 return make_uint2(a.x * b, a.y * b);
724 }
725 MIRTKCU_API inline uint2 operator*(uint b, uint2 a)
726 {
727 return make_uint2(b * a.x, b * a.y);
728 }
729 MIRTKCU_API inline void operator*=(uint2 &a, uint b)
730 {
731 a.x *= b; a.y *= b;
732 }
733
734 MIRTKCU_API inline float3 operator*(float3 a, float3 b)
735 {
736 return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
737 }
738 MIRTKCU_API inline void operator*=(float3 &a, float3 b)
739 {
740 a.x *= b.x; a.y *= b.y; a.z *= b.z;
741 }
742 MIRTKCU_API inline float3 operator*(float3 a, float b)
743 {
744 return make_float3(a.x * b, a.y * b, a.z * b);
745 }
746 MIRTKCU_API inline float3 operator*(float b, float3 a)
747 {
748 return make_float3(b * a.x, b * a.y, b * a.z);
749 }
750 MIRTKCU_API inline void operator*=(float3 &a, float b)
751 {
752 a.x *= b; a.y *= b; a.z *= b;
753 }
754
755 MIRTKCU_API inline int3 operator*(int3 a, int3 b)
756 {
757 return make_int3(a.x * b.x, a.y * b.y, a.z * b.z);
758 }
759 MIRTKCU_API inline void operator*=(int3 &a, int3 b)
760 {
761 a.x *= b.x; a.y *= b.y; a.z *= b.z;
762 }
763 MIRTKCU_API inline int3 operator*(int3 a, int b)
764 {
765 return make_int3(a.x * b, a.y * b, a.z * b);
766 }
767 MIRTKCU_API inline int3 operator*(int b, int3 a)
768 {
769 return make_int3(b * a.x, b * a.y, b * a.z);
770 }
771 MIRTKCU_API inline void operator*=(int3 &a, int b)
772 {
773 a.x *= b; a.y *= b; a.z *= b;
774 }
775
776 MIRTKCU_API inline uint3 operator*(uint3 a, uint3 b)
777 {
778 return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z);
779 }
780 MIRTKCU_API inline void operator*=(uint3 &a, uint3 b)
781 {
782 a.x *= b.x; a.y *= b.y; a.z *= b.z;
783 }
784 MIRTKCU_API inline uint3 operator*(uint3 a, uint b)
785 {
786 return make_uint3(a.x * b, a.y * b, a.z * b);
787 }
788 MIRTKCU_API inline uint3 operator*(uint b, uint3 a)
789 {
790 return make_uint3(b * a.x, b * a.y, b * a.z);
791 }
792 MIRTKCU_API inline void operator*=(uint3 &a, uint b)
793 {
794 a.x *= b; a.y *= b; a.z *= b;
795 }
796
797 MIRTKCU_API inline float4 operator*(float4 a, float4 b)
798 {
799 return make_float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
800 }
801 MIRTKCU_API inline void operator*=(float4 &a, float4 b)
802 {
803 a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w;
804 }
805 MIRTKCU_API inline float4 operator*(float4 a, float b)
806 {
807 return make_float4(a.x * b, a.y * b, a.z * b, a.w * b);
808 }
809 MIRTKCU_API inline float4 operator*(float b, float4 a)
810 {
811 return make_float4(b * a.x, b * a.y, b * a.z, b * a.w);
812 }
813 MIRTKCU_API inline void operator*=(float4 &a, float b)
814 {
815 a.x *= b; a.y *= b; a.z *= b; a.w *= b;
816 }
817
818 MIRTKCU_API inline int4 operator*(int4 a, int4 b)
819 {
820 return make_int4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
821 }
822 MIRTKCU_API inline void operator*=(int4 &a, int4 b)
823 {
824 a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w;
825 }
826 MIRTKCU_API inline int4 operator*(int4 a, int b)
827 {
828 return make_int4(a.x * b, a.y * b, a.z * b, a.w * b);
829 }
830 MIRTKCU_API inline int4 operator*(int b, int4 a)
831 {
832 return make_int4(b * a.x, b * a.y, b * a.z, b * a.w);
833 }
834 MIRTKCU_API inline void operator*=(int4 &a, int b)
835 {
836 a.x *= b; a.y *= b; a.z *= b; a.w *= b;
837 }
838
839 MIRTKCU_API inline uint4 operator*(uint4 a, uint4 b)
840 {
841 return make_uint4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
842 }
843 MIRTKCU_API inline void operator*=(uint4 &a, uint4 b)
844 {
845 a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w;
846 }
847 MIRTKCU_API inline uint4 operator*(uint4 a, uint b)
848 {
849 return make_uint4(a.x * b, a.y * b, a.z * b, a.w * b);
850 }
851 MIRTKCU_API inline uint4 operator*(uint b, uint4 a)
852 {
853 return make_uint4(b * a.x, b * a.y, b * a.z, b * a.w);
854 }
855 MIRTKCU_API inline void operator*=(uint4 &a, uint b)
856 {
857 a.x *= b; a.y *= b; a.z *= b; a.w *= b;
858 }
859
860 ////////////////////////////////////////////////////////////////////////////////
861 // divide
862 ////////////////////////////////////////////////////////////////////////////////
863
864 MIRTKCU_API inline float2 operator/(float2 a, float2 b)
865 {
866 return make_float2(a.x / b.x, a.y / b.y);
867 }
868 MIRTKCU_API inline void operator/=(float2 &a, float2 b)
869 {
870 a.x /= b.x; a.y /= b.y;
871 }
872 MIRTKCU_API inline float2 operator/(float2 a, float b)
873 {
874 return make_float2(a.x / b, a.y / b);
875 }
876 MIRTKCU_API inline void operator/=(float2 &a, float b)
877 {
878 a.x /= b; a.y /= b;
879 }
880 MIRTKCU_API inline float2 operator/(float b, float2 a)
881 {
882 return make_float2(b / a.x, b / a.y);
883 }
884
885 MIRTKCU_API inline float3 operator/(float3 a, float3 b)
886 {
887 return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
888 }
889 MIRTKCU_API inline void operator/=(float3 &a, float3 b)
890 {
891 a.x /= b.x; a.y /= b.y; a.z /= b.z;
892 }
893 MIRTKCU_API inline float3 operator/(float3 a, float b)
894 {
895 return make_float3(a.x / b, a.y / b, a.z / b);
896 }
897 MIRTKCU_API inline void operator/=(float3 &a, float b)
898 {
899 a.x /= b; a.y /= b; a.z /= b;
900 }
901 MIRTKCU_API inline float3 operator/(float b, float3 a)
902 {
903 return make_float3(b / a.x, b / a.y, b / a.z);
904 }
905
906 MIRTKCU_API inline float4 operator/(float4 a, float4 b)
907 {
908 return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
909 }
910 MIRTKCU_API inline void operator/=(float4 &a, float4 b)
911 {
912 a.x /= b.x; a.y /= b.y; a.z /= b.z; a.w /= b.w;
913 }
914 MIRTKCU_API inline float4 operator/(float4 a, float b)
915 {
916 return make_float4(a.x / b, a.y / b, a.z / b, a.w / b);
917 }
918 MIRTKCU_API inline void operator/=(float4 &a, float b)
919 {
920 a.x /= b; a.y /= b; a.z /= b; a.w /= b;
921 }
922 MIRTKCU_API inline float4 operator/(float b, float4 a){
923 return make_float4(b / a.x, b / a.y, b / a.z, b / a.w);
924 }
925
926 ////////////////////////////////////////////////////////////////////////////////
927 // min
928 ////////////////////////////////////////////////////////////////////////////////
929
fminf(float2 a,float2 b)930 MIRTKCU_API inline float2 fminf(float2 a, float2 b)
931 {
932 return make_float2(fminf(a.x,b.x), fminf(a.y,b.y));
933 }
fminf(float3 a,float3 b)934 MIRTKCU_API inline float3 fminf(float3 a, float3 b)
935 {
936 return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z));
937 }
fminf(float4 a,float4 b)938 MIRTKCU_API inline float4 fminf(float4 a, float4 b)
939 {
940 return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w));
941 }
942
min(int2 a,int2 b)943 MIRTKCU_API inline int2 min(int2 a, int2 b)
944 {
945 return make_int2(min(a.x,b.x), min(a.y,b.y));
946 }
min(int3 a,int3 b)947 MIRTKCU_API inline int3 min(int3 a, int3 b)
948 {
949 return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
950 }
min(int4 a,int4 b)951 MIRTKCU_API inline int4 min(int4 a, int4 b)
952 {
953 return make_int4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w));
954 }
955
min(uint2 a,uint2 b)956 MIRTKCU_API inline uint2 min(uint2 a, uint2 b)
957 {
958 return make_uint2(min(a.x,b.x), min(a.y,b.y));
959 }
min(uint3 a,uint3 b)960 MIRTKCU_API inline uint3 min(uint3 a, uint3 b)
961 {
962 return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
963 }
min(uint4 a,uint4 b)964 MIRTKCU_API inline uint4 min(uint4 a, uint4 b)
965 {
966 return make_uint4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w));
967 }
968
min(uint2 a)969 MIRTKCU_API inline uint min(uint2 a)
970 {
971 return min(a.x,a.y);
972 }
min(uint3 a)973 MIRTKCU_API inline uint min(uint3 a)
974 {
975 return min(a.x,min(a.y, a.z));
976 }
min(uint4 a)977 MIRTKCU_API inline uint min(uint4 a)
978 {
979 return min(min(a.x, a.y),min(a.z, a.w));
980 }
981
min(float2 a)982 MIRTKCU_API inline float min(float2 a)
983 {
984 return min(a.x,a.y);
985 }
min(float3 a)986 MIRTKCU_API inline float min(float3 a)
987 {
988 return min(a.x,min(a.y, a.z));
989 }
min(float4 a)990 MIRTKCU_API inline float min(float4 a)
991 {
992 return min(min(a.x, a.y),min(a.z, a.w));
993 }
994
995 ////////////////////////////////////////////////////////////////////////////////
996 // max
997 ////////////////////////////////////////////////////////////////////////////////
998
fmaxf(float2 a,float2 b)999 MIRTKCU_API inline float2 fmaxf(float2 a, float2 b)
1000 {
1001 return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y));
1002 }
fmaxf(float3 a,float3 b)1003 MIRTKCU_API inline float3 fmaxf(float3 a, float3 b)
1004 {
1005 return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z));
1006 }
fmaxf(float4 a,float4 b)1007 MIRTKCU_API inline float4 fmaxf(float4 a, float4 b)
1008 {
1009 return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w));
1010 }
1011
max(int2 a,int2 b)1012 MIRTKCU_API inline int2 max(int2 a, int2 b)
1013 {
1014 return make_int2(max(a.x,b.x), max(a.y,b.y));
1015 }
max(int3 a,int3 b)1016 MIRTKCU_API inline int3 max(int3 a, int3 b)
1017 {
1018 return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
1019 }
max(int4 a,int4 b)1020 MIRTKCU_API inline int4 max(int4 a, int4 b)
1021 {
1022 return make_int4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w));
1023 }
1024
max(uint2 a,uint2 b)1025 MIRTKCU_API inline uint2 max(uint2 a, uint2 b)
1026 {
1027 return make_uint2(max(a.x,b.x), max(a.y,b.y));
1028 }
max(uint3 a,uint3 b)1029 MIRTKCU_API inline uint3 max(uint3 a, uint3 b)
1030 {
1031 return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
1032 }
max(uint4 a,uint4 b)1033 MIRTKCU_API inline uint4 max(uint4 a, uint4 b)
1034 {
1035 return make_uint4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w));
1036 }
1037
max(uint2 a)1038 MIRTKCU_API inline uint max(uint2 a)
1039 {
1040 return max(a.x,a.y);
1041 }
max(uint3 a)1042 MIRTKCU_API inline uint max(uint3 a)
1043 {
1044 return max(a.x,max(a.y, a.z));
1045 }
max(uint4 a)1046 MIRTKCU_API inline uint max(uint4 a)
1047 {
1048 return max(max(a.x, a.y),max(a.z, a.w));
1049 }
1050
max(float2 a)1051 MIRTKCU_API inline float max(float2 a)
1052 {
1053 return max(a.x,a.y);
1054 }
max(float3 a)1055 MIRTKCU_API inline float max(float3 a)
1056 {
1057 return max(a.x,max(a.y, a.z));
1058 }
max(float4 a)1059 MIRTKCU_API inline float max(float4 a)
1060 {
1061 return max(max(a.x, a.y),max(a.z, a.w));
1062 }
1063
1064 ////////////////////////////////////////////////////////////////////////////////
1065 // lerp
1066 // - linear interpolation between a and b, based on value t in [0, 1] range
1067 ////////////////////////////////////////////////////////////////////////////////
1068
lerp(float a,float b,float t)1069 MIRTKCU_API inline float lerp(float a, float b, float t)
1070 {
1071 return a + t*(b-a);
1072 }
lerp(float2 a,float2 b,float t)1073 MIRTKCU_API inline float2 lerp(float2 a, float2 b, float t)
1074 {
1075 return a + t*(b-a);
1076 }
lerp(float3 a,float3 b,float t)1077 MIRTKCU_API inline float3 lerp(float3 a, float3 b, float t)
1078 {
1079 return a + t*(b-a);
1080 }
lerp(float4 a,float4 b,float t)1081 MIRTKCU_API inline float4 lerp(float4 a, float4 b, float t)
1082 {
1083 return a + t*(b-a);
1084 }
1085
1086 ////////////////////////////////////////////////////////////////////////////////
1087 // clamp
1088 // - clamp the value v to be in the range [a, b]
1089 ////////////////////////////////////////////////////////////////////////////////
1090
clamp(float f,float a,float b)1091 MIRTKCU_API inline float clamp(float f, float a, float b)
1092 {
1093 return fmaxf(a, fminf(f, b));
1094 }
clamp(int f,int a,int b)1095 MIRTKCU_API inline int clamp(int f, int a, int b)
1096 {
1097 return max(a, min(f, b));
1098 }
clamp(uint f,uint a,uint b)1099 MIRTKCU_API inline uint clamp(uint f, uint a, uint b)
1100 {
1101 return max(a, min(f, b));
1102 }
1103
clamp(float2 v,float a,float b)1104 MIRTKCU_API inline float2 clamp(float2 v, float a, float b)
1105 {
1106 return make_float2(clamp(v.x, a, b), clamp(v.y, a, b));
1107 }
clamp(float2 v,float2 a,float2 b)1108 MIRTKCU_API inline float2 clamp(float2 v, float2 a, float2 b)
1109 {
1110 return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1111 }
clamp(float3 v,float a,float b)1112 MIRTKCU_API inline float3 clamp(float3 v, float a, float b)
1113 {
1114 return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1115 }
clamp(float3 v,float3 a,float3 b)1116 MIRTKCU_API inline float3 clamp(float3 v, float3 a, float3 b)
1117 {
1118 return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1119 }
clamp(float4 v,float a,float b)1120 MIRTKCU_API inline float4 clamp(float4 v, float a, float b)
1121 {
1122 return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1123 }
clamp(float4 v,float4 a,float4 b)1124 MIRTKCU_API inline float4 clamp(float4 v, float4 a, float4 b)
1125 {
1126 return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
1127 }
1128
clamp(int2 v,int a,int b)1129 MIRTKCU_API inline int2 clamp(int2 v, int a, int b)
1130 {
1131 return make_int2(clamp(v.x, a, b), clamp(v.y, a, b));
1132 }
clamp(int2 v,int2 a,int2 b)1133 MIRTKCU_API inline int2 clamp(int2 v, int2 a, int2 b)
1134 {
1135 return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1136 }
clamp(int3 v,int a,int b)1137 MIRTKCU_API inline int3 clamp(int3 v, int a, int b)
1138 {
1139 return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1140 }
clamp(int3 v,int3 a,int3 b)1141 MIRTKCU_API inline int3 clamp(int3 v, int3 a, int3 b)
1142 {
1143 return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1144 }
clamp(int4 v,int a,int b)1145 MIRTKCU_API inline int4 clamp(int4 v, int a, int b)
1146 {
1147 return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1148 }
clamp(int4 v,int4 a,int4 b)1149 MIRTKCU_API inline int4 clamp(int4 v, int4 a, int4 b)
1150 {
1151 return make_int4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
1152 }
1153
clamp(uint2 v,uint a,uint b)1154 MIRTKCU_API inline uint2 clamp(uint2 v, uint a, uint b)
1155 {
1156 return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b));
1157 }
clamp(uint2 v,uint2 a,uint2 b)1158 MIRTKCU_API inline uint2 clamp(uint2 v, uint2 a, uint2 b)
1159 {
1160 return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1161 }
clamp(uint3 v,uint a,uint b)1162 MIRTKCU_API inline uint3 clamp(uint3 v, uint a, uint b)
1163 {
1164 return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1165 }
clamp(uint3 v,uint3 a,uint3 b)1166 MIRTKCU_API inline uint3 clamp(uint3 v, uint3 a, uint3 b)
1167 {
1168 return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1169 }
clamp(uint4 v,uint a,uint b)1170 MIRTKCU_API inline uint4 clamp(uint4 v, uint a, uint b)
1171 {
1172 return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1173 }
clamp(uint4 v,uint4 a,uint4 b)1174 MIRTKCU_API inline uint4 clamp(uint4 v, uint4 a, uint4 b)
1175 {
1176 return make_uint4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
1177 }
1178
1179 ////////////////////////////////////////////////////////////////////////////////
1180 // dot product
1181 ////////////////////////////////////////////////////////////////////////////////
1182
dot(float2 a,float2 b)1183 MIRTKCU_API inline float dot(float2 a, float2 b)
1184 {
1185 return a.x * b.x + a.y * b.y;
1186 }
dot(float3 a,float3 b)1187 MIRTKCU_API inline float dot(float3 a, float3 b)
1188 {
1189 return a.x * b.x + a.y * b.y + a.z * b.z;
1190 }
dot(float4 a,float4 b)1191 MIRTKCU_API inline float dot(float4 a, float4 b)
1192 {
1193 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1194 }
1195
dot(int2 a,int2 b)1196 MIRTKCU_API inline int dot(int2 a, int2 b)
1197 {
1198 return a.x * b.x + a.y * b.y;
1199 }
dot(int3 a,int3 b)1200 MIRTKCU_API inline int dot(int3 a, int3 b)
1201 {
1202 return a.x * b.x + a.y * b.y + a.z * b.z;
1203 }
dot(int4 a,int4 b)1204 MIRTKCU_API inline int dot(int4 a, int4 b)
1205 {
1206 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1207 }
1208
dot(uint2 a,uint2 b)1209 MIRTKCU_API inline uint dot(uint2 a, uint2 b)
1210 {
1211 return a.x * b.x + a.y * b.y;
1212 }
dot(uint3 a,uint3 b)1213 MIRTKCU_API inline uint dot(uint3 a, uint3 b)
1214 {
1215 return a.x * b.x + a.y * b.y + a.z * b.z;
1216 }
dot(uint4 a,uint4 b)1217 MIRTKCU_API inline uint dot(uint4 a, uint4 b)
1218 {
1219 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1220 }
1221
1222 ////////////////////////////////////////////////////////////////////////////////
1223 // length
1224 ////////////////////////////////////////////////////////////////////////////////
1225
length(float2 v)1226 MIRTKCU_API inline float length(float2 v)
1227 {
1228 return sqrtf(dot(v, v));
1229 }
length(float3 v)1230 MIRTKCU_API inline float length(float3 v)
1231 {
1232 return sqrtf(dot(v, v));
1233 }
length(float4 v)1234 MIRTKCU_API inline float length(float4 v)
1235 {
1236 return sqrtf(dot(v, v));
1237 }
1238
1239 ////////////////////////////////////////////////////////////////////////////////
1240 // normalize
1241 ////////////////////////////////////////////////////////////////////////////////
1242
normalize(float2 v)1243 MIRTKCU_API inline float2 normalize(float2 v)
1244 {
1245 float invLen = rsqrtf(dot(v, v));
1246 return v * invLen;
1247 }
normalize(float3 v)1248 MIRTKCU_API inline float3 normalize(float3 v)
1249 {
1250 float invLen = rsqrtf(dot(v, v));
1251 return v * invLen;
1252 }
normalize(float4 v)1253 MIRTKCU_API inline float4 normalize(float4 v)
1254 {
1255 float invLen = rsqrtf(dot(v, v));
1256 return v * invLen;
1257 }
1258
1259 ////////////////////////////////////////////////////////////////////////////////
1260 // floor
1261 ////////////////////////////////////////////////////////////////////////////////
1262
floorf(float2 v)1263 MIRTKCU_API inline float2 floorf(float2 v)
1264 {
1265 return make_float2(floorf(v.x), floorf(v.y));
1266 }
floorf(float3 v)1267 MIRTKCU_API inline float3 floorf(float3 v)
1268 {
1269 return make_float3(floorf(v.x), floorf(v.y), floorf(v.z));
1270 }
floorf(float4 v)1271 MIRTKCU_API inline float4 floorf(float4 v)
1272 {
1273 return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w));
1274 }
1275
1276 ////////////////////////////////////////////////////////////////////////////////
1277 // frac - returns the fractional portion of a scalar or each vector component
1278 ////////////////////////////////////////////////////////////////////////////////
1279
fracf(float v)1280 MIRTKCU_API inline float fracf(float v)
1281 {
1282 return v - floorf(v);
1283 }
fracf(float2 v)1284 MIRTKCU_API inline float2 fracf(float2 v)
1285 {
1286 return make_float2(fracf(v.x), fracf(v.y));
1287 }
fracf(float3 v)1288 MIRTKCU_API inline float3 fracf(float3 v)
1289 {
1290 return make_float3(fracf(v.x), fracf(v.y), fracf(v.z));
1291 }
fracf(float4 v)1292 MIRTKCU_API inline float4 fracf(float4 v)
1293 {
1294 return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w));
1295 }
1296
1297 ////////////////////////////////////////////////////////////////////////////////
1298 // fmod
1299 ////////////////////////////////////////////////////////////////////////////////
1300
fmodf(float2 a,float2 b)1301 MIRTKCU_API inline float2 fmodf(float2 a, float2 b)
1302 {
1303 return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y));
1304 }
fmodf(float3 a,float3 b)1305 MIRTKCU_API inline float3 fmodf(float3 a, float3 b)
1306 {
1307 return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z));
1308 }
fmodf(float4 a,float4 b)1309 MIRTKCU_API inline float4 fmodf(float4 a, float4 b)
1310 {
1311 return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w));
1312 }
1313
1314 ////////////////////////////////////////////////////////////////////////////////
1315 // absolute value
1316 ////////////////////////////////////////////////////////////////////////////////
1317
fabs(float2 v)1318 MIRTKCU_API inline float2 fabs(float2 v)
1319 {
1320 return make_float2(fabs(v.x), fabs(v.y));
1321 }
fabs(float3 v)1322 MIRTKCU_API inline float3 fabs(float3 v)
1323 {
1324 return make_float3(fabs(v.x), fabs(v.y), fabs(v.z));
1325 }
fabs(float4 v)1326 MIRTKCU_API inline float4 fabs(float4 v)
1327 {
1328 return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
1329 }
1330
abs(int2 v)1331 MIRTKCU_API inline int2 abs(int2 v)
1332 {
1333 return make_int2(abs(v.x), abs(v.y));
1334 }
abs(int3 v)1335 MIRTKCU_API inline int3 abs(int3 v)
1336 {
1337 return make_int3(abs(v.x), abs(v.y), abs(v.z));
1338 }
abs(int4 v)1339 MIRTKCU_API inline int4 abs(int4 v)
1340 {
1341 return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w));
1342 }
1343
1344 ////////////////////////////////////////////////////////////////////////////////
1345 // reflect
1346 // - returns reflection of incident ray I around surface normal N
1347 // - N should be normalized, reflected vector's length is equal to length of I
1348 ////////////////////////////////////////////////////////////////////////////////
1349
reflect(float3 i,float3 n)1350 MIRTKCU_API inline float3 reflect(float3 i, float3 n)
1351 {
1352 return i - 2.0f * n * dot(n,i);
1353 }
1354
1355 ////////////////////////////////////////////////////////////////////////////////
1356 // cross product
1357 ////////////////////////////////////////////////////////////////////////////////
1358
cross(float3 a,float3 b)1359 MIRTKCU_API inline float3 cross(float3 a, float3 b)
1360 {
1361 return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
1362 }
1363
1364 ////////////////////////////////////////////////////////////////////////////////
1365 // smoothstep
1366 // - returns 0 if x < a
1367 // - returns 1 if x > b
1368 // - otherwise returns smooth interpolation between 0 and 1 based on x
1369 ////////////////////////////////////////////////////////////////////////////////
1370
smoothstep(float a,float b,float x)1371 MIRTKCU_API inline float smoothstep(float a, float b, float x)
1372 {
1373 float y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1374 return (y*y*(3.0f - (2.0f*y)));
1375 }
smoothstep(float2 a,float2 b,float2 x)1376 MIRTKCU_API inline float2 smoothstep(float2 a, float2 b, float2 x)
1377 {
1378 float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1379 return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y)));
1380 }
smoothstep(float3 a,float3 b,float3 x)1381 MIRTKCU_API inline float3 smoothstep(float3 a, float3 b, float3 x)
1382 {
1383 float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1384 return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y)));
1385 }
smoothstep(float4 a,float4 b,float4 x)1386 MIRTKCU_API inline float4 smoothstep(float4 a, float4 b, float4 x)
1387 {
1388 float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1389 return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y)));
1390 }
1391
1392 ////////////////////////////////////////////////////////////////////////////////
1393 // shift
1394 ////////////////////////////////////////////////////////////////////////////////
1395
1396 MIRTKCU_API inline uint2 operator<<(uint2 a, int b)
1397 {
1398 return make_uint2(a.x << b, a.y << b);
1399 }
1400
1401 MIRTKCU_API inline uint3 operator<<(uint3 a, int b)
1402 {
1403 return make_uint3(a.x << b, a.y << b, a.z << b);
1404 }
1405
1406 MIRTKCU_API inline uint4 operator<<(uint4 a, int b)
1407 {
1408 return make_uint4(a.x << b, a.y << b, a.z << b, a.w << b);
1409 }
1410
1411 MIRTKCU_API inline uint2 operator>>(uint2 a, int b)
1412 {
1413 return make_uint2(a.x >> b, a.y >> b);
1414 }
1415
1416 MIRTKCU_API inline uint3 operator>>(uint3 a, int b)
1417 {
1418 return make_uint3(a.x >> b, a.y >> b, a.z >> b);
1419 }
1420
1421 MIRTKCU_API inline uint4 operator>>(uint4 a, int b)
1422 {
1423 return make_uint4(a.x >> b, a.y >> b, a.z >> b, a.w >> b);
1424 }
1425
1426
1427
1428 MIRTKCU_API inline int2 operator<<(int2 a, int b)
1429 {
1430 return make_int2(a.x << b, a.y << b);
1431 }
1432
1433 MIRTKCU_API inline int3 operator<<(int3 a, int b)
1434 {
1435 return make_int3(a.x << b, a.y << b, a.z << b);
1436 }
1437
1438 MIRTKCU_API inline int4 operator<<(int4 a, int b)
1439 {
1440 return make_int4(a.x << b, a.y << b, a.z << b, a.w << b);
1441 }
1442
1443 MIRTKCU_API inline int2 operator>>(int2 a, int b)
1444 {
1445 return make_int2(a.x >> b, a.y >> b);
1446 }
1447
1448 MIRTKCU_API inline int3 operator>>(int3 a, int b)
1449 {
1450 return make_int3(a.x >> b, a.y >> b, a.z >> b);
1451 }
1452
1453 MIRTKCU_API inline int4 operator>>(int4 a, int b)
1454 {
1455 return make_int4(a.x >> b, a.y >> b, a.z >> b, a.w >> b);
1456 }
1457
1458
1459 } // namespace mirtk
1460
1461 #endif // MIRTK_CutilMath_H
1462