Point Cloud Library (PCL) 1.15.0
Loading...
Searching...
No Matches
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
1004#if !defined(__cplusplus) || (__cplusplus < 202002L)
1005// C++20 and higher provides std::lerp
1006inline __device__ __host__ float lerp(float a, float b, float t)
1007{
1008 return a + t*(b-a);
1009}
1010#endif
1011inline __device__ __host__ float2 lerp(float2 a, float2 b, float t)
1012{
1013 return a + t*(b-a);
1014}
1015inline __device__ __host__ float3 lerp(float3 a, float3 b, float t)
1016{
1017 return a + t*(b-a);
1018}
1019inline __device__ __host__ float4 lerp(float4 a, float4 b, float t)
1020{
1021 return a + t*(b-a);
1022}
1023
1024////////////////////////////////////////////////////////////////////////////////
1025// clamp
1026// - clamp the value v to be in the range [a, b]
1027////////////////////////////////////////////////////////////////////////////////
1028
1029inline __device__ __host__ float clamp(float f, float a, float b)
1030{
1031 return fmaxf(a, fminf(f, b));
1032}
1033inline __device__ __host__ int clamp(int f, int a, int b)
1034{
1035 return max(a, min(f, b));
1036}
1037inline __device__ __host__ uint clamp(uint f, uint a, uint b)
1038{
1039 return max(a, min(f, b));
1040}
1041
1042inline __device__ __host__ float2 clamp(float2 v, float a, float b)
1043{
1044 return make_float2(clamp(v.x, a, b), clamp(v.y, a, b));
1045}
1046inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b)
1047{
1048 return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1049}
1050inline __device__ __host__ float3 clamp(float3 v, float a, float b)
1051{
1052 return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1053}
1054inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b)
1055{
1056 return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1057}
1058inline __device__ __host__ float4 clamp(float4 v, float a, float b)
1059{
1060 return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1061}
1062inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b)
1063{
1064 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));
1065}
1066
1067inline __device__ __host__ int2 clamp(int2 v, int a, int b)
1068{
1069 return make_int2(clamp(v.x, a, b), clamp(v.y, a, b));
1070}
1071inline __device__ __host__ int2 clamp(int2 v, int2 a, int2 b)
1072{
1073 return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1074}
1075inline __device__ __host__ int3 clamp(int3 v, int a, int b)
1076{
1077 return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1078}
1079inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b)
1080{
1081 return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1082}
1083inline __device__ __host__ int4 clamp(int4 v, int a, int b)
1084{
1085 return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1086}
1087inline __device__ __host__ int4 clamp(int4 v, int4 a, int4 b)
1088{
1089 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));
1090}
1091
1092inline __device__ __host__ uint2 clamp(uint2 v, uint a, uint b)
1093{
1094 return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b));
1095}
1096inline __device__ __host__ uint2 clamp(uint2 v, uint2 a, uint2 b)
1097{
1098 return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1099}
1100inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b)
1101{
1102 return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1103}
1104inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b)
1105{
1106 return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1107}
1108inline __device__ __host__ uint4 clamp(uint4 v, uint a, uint b)
1109{
1110 return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1111}
1112inline __device__ __host__ uint4 clamp(uint4 v, uint4 a, uint4 b)
1113{
1114 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));
1115}
1116
1117////////////////////////////////////////////////////////////////////////////////
1118// dot product
1119////////////////////////////////////////////////////////////////////////////////
1120
1121inline __host__ __device__ float dot(float2 a, float2 b)
1122{
1123 return a.x * b.x + a.y * b.y;
1124}
1125inline __host__ __device__ float dot(float3 a, float3 b)
1126{
1127 return a.x * b.x + a.y * b.y + a.z * b.z;
1128}
1129inline __host__ __device__ float dot(float4 a, float4 b)
1130{
1131 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1132}
1133
1134inline __host__ __device__ int dot(int2 a, int2 b)
1135{
1136 return a.x * b.x + a.y * b.y;
1137}
1138inline __host__ __device__ int dot(int3 a, int3 b)
1139{
1140 return a.x * b.x + a.y * b.y + a.z * b.z;
1141}
1142inline __host__ __device__ int dot(int4 a, int4 b)
1143{
1144 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1145}
1146
1147inline __host__ __device__ uint dot(uint2 a, uint2 b)
1148{
1149 return a.x * b.x + a.y * b.y;
1150}
1151inline __host__ __device__ uint dot(uint3 a, uint3 b)
1152{
1153 return a.x * b.x + a.y * b.y + a.z * b.z;
1154}
1155inline __host__ __device__ uint dot(uint4 a, uint4 b)
1156{
1157 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1158}
1159
1160////////////////////////////////////////////////////////////////////////////////
1161// length
1162////////////////////////////////////////////////////////////////////////////////
1163
1164inline __host__ __device__ float length(float2 v)
1165{
1166 return sqrtf(dot(v, v));
1167}
1168inline __host__ __device__ float length(float3 v)
1169{
1170 return sqrtf(dot(v, v));
1171}
1172inline __host__ __device__ float length(float4 v)
1173{
1174 return sqrtf(dot(v, v));
1175}
1176
1177////////////////////////////////////////////////////////////////////////////////
1178// normalize
1179////////////////////////////////////////////////////////////////////////////////
1180
1181inline __host__ __device__ float2 normalize(float2 v)
1182{
1183 float invLen = rsqrtf(dot(v, v));
1184 return v * invLen;
1185}
1186inline __host__ __device__ float3 normalize(float3 v)
1187{
1188 float invLen = rsqrtf(dot(v, v));
1189 return v * invLen;
1190}
1191inline __host__ __device__ float4 normalize(float4 v)
1192{
1193 float invLen = rsqrtf(dot(v, v));
1194 return v * invLen;
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198// floor
1199////////////////////////////////////////////////////////////////////////////////
1200
1201inline __host__ __device__ float2 floorf(float2 v)
1202{
1203 return make_float2(floorf(v.x), floorf(v.y));
1204}
1205inline __host__ __device__ float3 floorf(float3 v)
1206{
1207 return make_float3(floorf(v.x), floorf(v.y), floorf(v.z));
1208}
1209inline __host__ __device__ float4 floorf(float4 v)
1210{
1211 return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w));
1212}
1213
1214////////////////////////////////////////////////////////////////////////////////
1215// frac - returns the fractional portion of a scalar or each vector component
1216////////////////////////////////////////////////////////////////////////////////
1217
1218inline __host__ __device__ float fracf(float v)
1219{
1220 return v - floorf(v);
1221}
1222inline __host__ __device__ float2 fracf(float2 v)
1223{
1224 return make_float2(fracf(v.x), fracf(v.y));
1225}
1226inline __host__ __device__ float3 fracf(float3 v)
1227{
1228 return make_float3(fracf(v.x), fracf(v.y), fracf(v.z));
1229}
1230inline __host__ __device__ float4 fracf(float4 v)
1231{
1232 return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w));
1233}
1234
1235////////////////////////////////////////////////////////////////////////////////
1236// fmod
1237////////////////////////////////////////////////////////////////////////////////
1238
1239inline __host__ __device__ float2 fmodf(float2 a, float2 b)
1240{
1241 return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y));
1242}
1243inline __host__ __device__ float3 fmodf(float3 a, float3 b)
1244{
1245 return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z));
1246}
1247inline __host__ __device__ float4 fmodf(float4 a, float4 b)
1248{
1249 return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w));
1250}
1251
1252////////////////////////////////////////////////////////////////////////////////
1253// absolute value
1254////////////////////////////////////////////////////////////////////////////////
1255
1256inline __host__ __device__ float2 fabs(float2 v)
1257{
1258 return make_float2(fabs(v.x), fabs(v.y));
1259}
1260inline __host__ __device__ float3 fabs(float3 v)
1261{
1262 return make_float3(fabs(v.x), fabs(v.y), fabs(v.z));
1263}
1264inline __host__ __device__ float4 fabs(float4 v)
1265{
1266 return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
1267}
1268
1269inline __host__ __device__ int2 abs(int2 v)
1270{
1271 return make_int2(abs(v.x), abs(v.y));
1272}
1273inline __host__ __device__ int3 abs(int3 v)
1274{
1275 return make_int3(abs(v.x), abs(v.y), abs(v.z));
1276}
1277inline __host__ __device__ int4 abs(int4 v)
1278{
1279 return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w));
1280}
1281
1282////////////////////////////////////////////////////////////////////////////////
1283// reflect
1284// - returns reflection of incident ray I around surface normal N
1285// - N should be normalized, reflected vector's length is equal to length of I
1286////////////////////////////////////////////////////////////////////////////////
1287
1288inline __host__ __device__ float3 reflect(float3 i, float3 n)
1289{
1290 return i - 2.0f * n * dot(n,i);
1291}
1292
1293////////////////////////////////////////////////////////////////////////////////
1294// cross product
1295////////////////////////////////////////////////////////////////////////////////
1296
1297inline __host__ __device__ float3 cross(float3 a, float3 b)
1298{
1299 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);
1300}
1301
1302////////////////////////////////////////////////////////////////////////////////
1303// smoothstep
1304// - returns 0 if x < a
1305// - returns 1 if x > b
1306// - otherwise returns smooth interpolation between 0 and 1 based on x
1307////////////////////////////////////////////////////////////////////////////////
1308
1309inline __device__ __host__ float smoothstep(float a, float b, float x)
1310{
1311 float y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1312 return (y*y*(3.0f - (2.0f*y)));
1313}
1314inline __device__ __host__ float2 smoothstep(float2 a, float2 b, float2 x)
1315{
1316 float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1317 return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y)));
1318}
1319inline __device__ __host__ float3 smoothstep(float3 a, float3 b, float3 x)
1320{
1321 float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1322 return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y)));
1323}
1324inline __device__ __host__ float4 smoothstep(float4 a, float4 b, float4 x)
1325{
1326 float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1327 return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y)));
1328}