CutilMath.h
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 
60 inline float fminf(float a, float b)
61 {
62  return a < b ? a : b;
63 }
64 
65 inline float fmaxf(float a, float b)
66 {
67  return a > b ? a : b;
68 }
69 
70 inline float rsqrtf(float x)
71 {
72  return 1.0f / sqrtf(x);
73 }
74 
75 #endif // !defined(__CUDACC__)
76 ////////////////////////////////////////////////////////////////////////////////
77 // constructors
78 ////////////////////////////////////////////////////////////////////////////////
79 
80 MIRTKCU_API inline float2 make_float2(float s)
81 {
82  return make_float2(s, s);
83 }
84 MIRTKCU_API inline float2 make_float2(float3 a)
85 {
86  return make_float2(a.x, a.y);
87 }
88 MIRTKCU_API inline float2 make_float2(int2 a)
89 {
90  return make_float2(float(a.x), float(a.y));
91 }
92 MIRTKCU_API inline float2 make_float2(uint2 a)
93 {
94  return make_float2(float(a.x), float(a.y));
95 }
96 
97 MIRTKCU_API inline int2 make_int2(int s)
98 {
99  return make_int2(s, s);
100 }
101 MIRTKCU_API inline int2 make_int2(int3 a)
102 {
103  return make_int2(a.x, a.y);
104 }
105 MIRTKCU_API inline int2 make_int2(uint2 a)
106 {
107  return make_int2(int(a.x), int(a.y));
108 }
109 MIRTKCU_API inline int2 make_int2(float2 a)
110 {
111  return make_int2(int(a.x), int(a.y));
112 }
113 
114 MIRTKCU_API inline uint2 make_uint2(uint s)
115 {
116  return make_uint2(s, s);
117 }
118 MIRTKCU_API inline uint2 make_uint2(uint3 a)
119 {
120  return make_uint2(a.x, a.y);
121 }
122 MIRTKCU_API inline uint2 make_uint2(int2 a)
123 {
124  return make_uint2(uint(a.x), uint(a.y));
125 }
126 
127 MIRTKCU_API inline float3 make_float3(float s)
128 {
129  return make_float3(s, s, s);
130 }
131 MIRTKCU_API inline float3 make_float3(float2 a)
132 {
133  return make_float3(a.x, a.y, 0.0f);
134 }
135 MIRTKCU_API inline float3 make_float3(float2 a, float s)
136 {
137  return make_float3(a.x, a.y, s);
138 }
139 MIRTKCU_API inline float3 make_float3(float4 a)
140 {
141  return make_float3(a.x, a.y, a.z);
142 }
143 MIRTKCU_API inline float3 make_float3(int3 a)
144 {
145  return make_float3(float(a.x), float(a.y), float(a.z));
146 }
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 
152 MIRTKCU_API inline int3 make_int3(int s)
153 {
154  return make_int3(s, s, s);
155 }
156 MIRTKCU_API inline int3 make_int3(int2 a)
157 {
158  return make_int3(a.x, a.y, 0);
159 }
160 MIRTKCU_API inline int3 make_int3(int2 a, int s)
161 {
162  return make_int3(a.x, a.y, s);
163 }
164 MIRTKCU_API inline int3 make_int3(uint3 a)
165 {
166  return make_int3(int(a.x), int(a.y), int(a.z));
167 }
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 
173 MIRTKCU_API inline uint3 make_uint3(uint s)
174 {
175  return make_uint3(s, s, s);
176 }
177 MIRTKCU_API inline uint3 make_uint3(uint2 a)
178 {
179  return make_uint3(a.x, a.y, 0);
180 }
181 MIRTKCU_API inline uint3 make_uint3(uint2 a, uint s)
182 {
183  return make_uint3(a.x, a.y, s);
184 }
185 MIRTKCU_API inline uint3 make_uint3(uint4 a)
186 {
187  return make_uint3(a.x, a.y, a.z);
188 }
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 
194 MIRTKCU_API inline float4 make_float4(float s)
195 {
196  return make_float4(s, s, s, s);
197 }
198 MIRTKCU_API inline float4 make_float4(float3 a)
199 {
200  return make_float4(a.x, a.y, a.z, 0.0f);
201 }
202 MIRTKCU_API inline float4 make_float4(float3 a, float w)
203 {
204  return make_float4(a.x, a.y, a.z, w);
205 }
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 }
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 
215 MIRTKCU_API inline int4 make_int4(int s)
216 {
217  return make_int4(s, s, s, s);
218 }
219 MIRTKCU_API inline int4 make_int4(int3 a)
220 {
221  return make_int4(a.x, a.y, a.z, 0);
222 }
223 MIRTKCU_API inline int4 make_int4(int3 a, int w)
224 {
225  return make_int4(a.x, a.y, a.z, w);
226 }
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 }
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 
237 MIRTKCU_API inline uint4 make_uint4(uint s)
238 {
239  return make_uint4(s, s, s, s);
240 }
241 MIRTKCU_API inline uint4 make_uint4(uint3 a)
242 {
243  return make_uint4(a.x, a.y, a.z, 0);
244 }
245 MIRTKCU_API inline uint4 make_uint4(uint3 a, uint w)
246 {
247  return make_uint4(a.x, a.y, a.z, w);
248 }
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 
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 }
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 }
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 
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 }
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 }
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 
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 }
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 }
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 
969 MIRTKCU_API inline uint min(uint2 a)
970 {
971  return min(a.x,a.y);
972 }
973 MIRTKCU_API inline uint min(uint3 a)
974 {
975  return min(a.x,min(a.y, a.z));
976 }
977 MIRTKCU_API inline uint min(uint4 a)
978 {
979  return min(min(a.x, a.y),min(a.z, a.w));
980 }
981 
982 MIRTKCU_API inline float min(float2 a)
983 {
984  return min(a.x,a.y);
985 }
986 MIRTKCU_API inline float min(float3 a)
987 {
988  return min(a.x,min(a.y, a.z));
989 }
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 
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 }
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 }
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 
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 }
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 }
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 
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 }
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 }
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 
1038 MIRTKCU_API inline uint max(uint2 a)
1039 {
1040  return max(a.x,a.y);
1041 }
1042 MIRTKCU_API inline uint max(uint3 a)
1043 {
1044  return max(a.x,max(a.y, a.z));
1045 }
1046 MIRTKCU_API inline uint max(uint4 a)
1047 {
1048  return max(max(a.x, a.y),max(a.z, a.w));
1049 }
1050 
1051 MIRTKCU_API inline float max(float2 a)
1052 {
1053  return max(a.x,a.y);
1054 }
1055 MIRTKCU_API inline float max(float3 a)
1056 {
1057  return max(a.x,max(a.y, a.z));
1058 }
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 
1069 MIRTKCU_API inline float lerp(float a, float b, float t)
1070 {
1071  return a + t*(b-a);
1072 }
1073 MIRTKCU_API inline float2 lerp(float2 a, float2 b, float t)
1074 {
1075  return a + t*(b-a);
1076 }
1077 MIRTKCU_API inline float3 lerp(float3 a, float3 b, float t)
1078 {
1079  return a + t*(b-a);
1080 }
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 
1091 MIRTKCU_API inline float clamp(float f, float a, float b)
1092 {
1093  return fmaxf(a, fminf(f, b));
1094 }
1095 MIRTKCU_API inline int clamp(int f, int a, int b)
1096 {
1097  return max(a, min(f, b));
1098 }
1099 MIRTKCU_API inline uint clamp(uint f, uint a, uint b)
1100 {
1101  return max(a, min(f, b));
1102 }
1103 
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 }
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 }
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 }
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 }
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 }
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 
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 }
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 }
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 }
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 }
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 }
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 
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 }
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 }
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 }
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 }
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 }
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 
1183 MIRTKCU_API inline float dot(float2 a, float2 b)
1184 {
1185  return a.x * b.x + a.y * b.y;
1186 }
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 }
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 
1196 MIRTKCU_API inline int dot(int2 a, int2 b)
1197 {
1198  return a.x * b.x + a.y * b.y;
1199 }
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 }
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 
1209 MIRTKCU_API inline uint dot(uint2 a, uint2 b)
1210 {
1211  return a.x * b.x + a.y * b.y;
1212 }
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 }
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 
1226 MIRTKCU_API inline float length(float2 v)
1227 {
1228  return sqrtf(dot(v, v));
1229 }
1230 MIRTKCU_API inline float length(float3 v)
1231 {
1232  return sqrtf(dot(v, v));
1233 }
1234 MIRTKCU_API inline float length(float4 v)
1235 {
1236  return sqrtf(dot(v, v));
1237 }
1238 
1239 ////////////////////////////////////////////////////////////////////////////////
1240 // normalize
1241 ////////////////////////////////////////////////////////////////////////////////
1242 
1243 MIRTKCU_API inline float2 normalize(float2 v)
1244 {
1245  float invLen = rsqrtf(dot(v, v));
1246  return v * invLen;
1247 }
1248 MIRTKCU_API inline float3 normalize(float3 v)
1249 {
1250  float invLen = rsqrtf(dot(v, v));
1251  return v * invLen;
1252 }
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 
1263 MIRTKCU_API inline float2 floorf(float2 v)
1264 {
1265  return make_float2(floorf(v.x), floorf(v.y));
1266 }
1267 MIRTKCU_API inline float3 floorf(float3 v)
1268 {
1269  return make_float3(floorf(v.x), floorf(v.y), floorf(v.z));
1270 }
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 
1280 MIRTKCU_API inline float fracf(float v)
1281 {
1282  return v - floorf(v);
1283 }
1284 MIRTKCU_API inline float2 fracf(float2 v)
1285 {
1286  return make_float2(fracf(v.x), fracf(v.y));
1287 }
1288 MIRTKCU_API inline float3 fracf(float3 v)
1289 {
1290  return make_float3(fracf(v.x), fracf(v.y), fracf(v.z));
1291 }
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 
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 }
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 }
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 
1318 MIRTKCU_API inline float2 fabs(float2 v)
1319 {
1320  return make_float2(fabs(v.x), fabs(v.y));
1321 }
1322 MIRTKCU_API inline float3 fabs(float3 v)
1323 {
1324  return make_float3(fabs(v.x), fabs(v.y), fabs(v.z));
1325 }
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 
1331 MIRTKCU_API inline int2 abs(int2 v)
1332 {
1333  return make_int2(abs(v.x), abs(v.y));
1334 }
1335 MIRTKCU_API inline int3 abs(int3 v)
1336 {
1337  return make_int3(abs(v.x), abs(v.y), abs(v.z));
1338 }
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 
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 
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 
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 }
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 }
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 }
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
Definition: IOConfig.h:41