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