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