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