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