Point Cloud Library (PCL)  1.14.1
cutil_math.h
1 /*
2  * Copyright 1993-2010 NVIDIA Corporation. All rights reserved.
3  *
4  * Please refer to the NVIDIA end user license agreement (EULA) associated
5  * with this source code for terms and conditions that govern your use of
6  * this software. Any use, reproduction, disclosure, or distribution of
7  * this software and related documentation outside the terms of the EULA
8  * is strictly prohibited.
9  *
10  */
11 
12 /*
13  This file implements common mathematical operations on vector types
14  (float3, float4 etc.) since these are not provided as standard by CUDA.
15 
16  The syntax is modelled on the Cg standard library.
17 
18  This is part of the CUTIL library and is not supported by NVIDIA.
19 
20  Thanks to Linh Hah for additions and fixes.
21 */
22 
23 #pragma once
24 
25 #include "cuda_runtime.h"
26 
27 using uint = unsigned int;
28 using ushort = unsigned short;
29 
30 #ifndef __CUDACC__
31 #include <math.h>
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 // host implementations of CUDA functions
35 ////////////////////////////////////////////////////////////////////////////////
36 
37 inline float fminf(float a, float b)
38 {
39  return a < b ? a : b;
40 }
41 
42 inline float fmaxf(float a, float b)
43 {
44  return a > b ? a : b;
45 }
46 
47 inline int max(int a, int b)
48 {
49  return a > b ? a : b;
50 }
51 
52 inline int min(int a, int b)
53 {
54  return a < b ? a : b;
55 }
56 
57 inline float rsqrtf(float x)
58 {
59  return 1.0f / sqrtf(x);
60 }
61 #endif
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 // constructors
65 ////////////////////////////////////////////////////////////////////////////////
66 
67 inline __host__ __device__ float2 make_float2(float s)
68 {
69  return make_float2(s, s);
70 }
71 inline __host__ __device__ float2 make_float2(float3 a)
72 {
73  return make_float2(a.x, a.y);
74 }
75 inline __host__ __device__ float2 make_float2(int2 a)
76 {
77  return make_float2(float(a.x), float(a.y));
78 }
79 inline __host__ __device__ float2 make_float2(uint2 a)
80 {
81  return make_float2(float(a.x), float(a.y));
82 }
83 
84 inline __host__ __device__ int2 make_int2(int s)
85 {
86  return make_int2(s, s);
87 }
88 inline __host__ __device__ int2 make_int2(int3 a)
89 {
90  return make_int2(a.x, a.y);
91 }
92 inline __host__ __device__ int2 make_int2(uint2 a)
93 {
94  return make_int2(int(a.x), int(a.y));
95 }
96 inline __host__ __device__ int2 make_int2(float2 a)
97 {
98  return make_int2(int(a.x), int(a.y));
99 }
100 
101 inline __host__ __device__ uint2 make_uint2(uint s)
102 {
103  return make_uint2(s, s);
104 }
105 inline __host__ __device__ uint2 make_uint2(uint3 a)
106 {
107  return make_uint2(a.x, a.y);
108 }
109 inline __host__ __device__ uint2 make_uint2(int2 a)
110 {
111  return make_uint2(uint(a.x), uint(a.y));
112 }
113 
114 inline __host__ __device__ float3 make_float3(float s)
115 {
116  return make_float3(s, s, s);
117 }
118 inline __host__ __device__ float3 make_float3(float2 a)
119 {
120  return make_float3(a.x, a.y, 0.0f);
121 }
122 inline __host__ __device__ float3 make_float3(float2 a, float s)
123 {
124  return make_float3(a.x, a.y, s);
125 }
126 inline __host__ __device__ float3 make_float3(float4 a)
127 {
128  return make_float3(a.x, a.y, a.z);
129 }
130 inline __host__ __device__ float3 make_float3(int3 a)
131 {
132  return make_float3(float(a.x), float(a.y), float(a.z));
133 }
134 inline __host__ __device__ float3 make_float3(uint3 a)
135 {
136  return make_float3(float(a.x), float(a.y), float(a.z));
137 }
138 
139 inline __host__ __device__ int3 make_int3(int s)
140 {
141  return make_int3(s, s, s);
142 }
143 inline __host__ __device__ int3 make_int3(int2 a)
144 {
145  return make_int3(a.x, a.y, 0);
146 }
147 inline __host__ __device__ int3 make_int3(int2 a, int s)
148 {
149  return make_int3(a.x, a.y, s);
150 }
151 inline __host__ __device__ int3 make_int3(uint3 a)
152 {
153  return make_int3(int(a.x), int(a.y), int(a.z));
154 }
155 inline __host__ __device__ int3 make_int3(float3 a)
156 {
157  return make_int3(int(a.x), int(a.y), int(a.z));
158 }
159 
160 inline __host__ __device__ uint3 make_uint3(uint s)
161 {
162  return make_uint3(s, s, s);
163 }
164 inline __host__ __device__ uint3 make_uint3(uint2 a)
165 {
166  return make_uint3(a.x, a.y, 0);
167 }
168 inline __host__ __device__ uint3 make_uint3(uint2 a, uint s)
169 {
170  return make_uint3(a.x, a.y, s);
171 }
172 inline __host__ __device__ uint3 make_uint3(uint4 a)
173 {
174  return make_uint3(a.x, a.y, a.z);
175 }
176 inline __host__ __device__ uint3 make_uint3(int3 a)
177 {
178  return make_uint3(uint(a.x), uint(a.y), uint(a.z));
179 }
180 
181 inline __host__ __device__ float4 make_float4(float s)
182 {
183  return make_float4(s, s, s, s);
184 }
185 inline __host__ __device__ float4 make_float4(float3 a)
186 {
187  return make_float4(a.x, a.y, a.z, 0.0f);
188 }
189 inline __host__ __device__ float4 make_float4(float3 a, float w)
190 {
191  return make_float4(a.x, a.y, a.z, w);
192 }
193 inline __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 }
197 inline __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 
202 inline __host__ __device__ int4 make_int4(int s)
203 {
204  return make_int4(s, s, s, s);
205 }
206 inline __host__ __device__ int4 make_int4(int3 a)
207 {
208  return make_int4(a.x, a.y, a.z, 0);
209 }
210 inline __host__ __device__ int4 make_int4(int3 a, int w)
211 {
212  return make_int4(a.x, a.y, a.z, w);
213 }
214 inline __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 }
218 inline __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 
224 inline __host__ __device__ uint4 make_uint4(uint s)
225 {
226  return make_uint4(s, s, s, s);
227 }
228 inline __host__ __device__ uint4 make_uint4(uint3 a)
229 {
230  return make_uint4(a.x, a.y, a.z, 0);
231 }
232 inline __host__ __device__ uint4 make_uint4(uint3 a, uint w)
233 {
234  return make_uint4(a.x, a.y, a.z, w);
235 }
236 inline __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 
245 inline __host__ __device__ float2 operator-(float2 &a)
246 {
247  return make_float2(-a.x, -a.y);
248 }
249 inline __host__ __device__ int2 operator-(int2 &a)
250 {
251  return make_int2(-a.x, -a.y);
252 }
253 inline __host__ __device__ float3 operator-(float3 &a)
254 {
255  return make_float3(-a.x, -a.y, -a.z);
256 }
257 inline __host__ __device__ int3 operator-(int3 &a)
258 {
259  return make_int3(-a.x, -a.y, -a.z);
260 }
261 inline __host__ __device__ float4 operator-(float4 &a)
262 {
263  return make_float4(-a.x, -a.y, -a.z, -a.w);
264 }
265 inline __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 
274 inline __host__ __device__ float2 operator+(float2 a, float2 b)
275 {
276  return make_float2(a.x + b.x, a.y + b.y);
277 }
278 inline __host__ __device__ void operator+=(float2 &a, float2 b)
279 {
280  a.x += b.x; a.y += b.y;
281 }
282 inline __host__ __device__ float2 operator+(float2 a, float b)
283 {
284  return make_float2(a.x + b, a.y + b);
285 }
286 inline __host__ __device__ float2 operator+(float b, float2 a)
287 {
288  return make_float2(a.x + b, a.y + b);
289 }
290 inline __host__ __device__ void operator+=(float2 &a, float b)
291 {
292  a.x += b; a.y += b;
293 }
294 
295 inline __host__ __device__ int2 operator+(int2 a, int2 b)
296 {
297  return make_int2(a.x + b.x, a.y + b.y);
298 }
299 inline __host__ __device__ void operator+=(int2 &a, int2 b)
300 {
301  a.x += b.x; a.y += b.y;
302 }
303 inline __host__ __device__ int2 operator+(int2 a, int b)
304 {
305  return make_int2(a.x + b, a.y + b);
306 }
307 inline __host__ __device__ int2 operator+(int b, int2 a)
308 {
309  return make_int2(a.x + b, a.y + b);
310 }
311 inline __host__ __device__ void operator+=(int2 &a, int b)
312 {
313  a.x += b; a.y += b;
314 }
315 
316 inline __host__ __device__ uint2 operator+(uint2 a, uint2 b)
317 {
318  return make_uint2(a.x + b.x, a.y + b.y);
319 }
320 inline __host__ __device__ void operator+=(uint2 &a, uint2 b)
321 {
322  a.x += b.x; a.y += b.y;
323 }
324 inline __host__ __device__ uint2 operator+(uint2 a, uint b)
325 {
326  return make_uint2(a.x + b, a.y + b);
327 }
328 inline __host__ __device__ uint2 operator+(uint b, uint2 a)
329 {
330  return make_uint2(a.x + b, a.y + b);
331 }
332 inline __host__ __device__ void operator+=(uint2 &a, uint b)
333 {
334  a.x += b; a.y += b;
335 }
336 
337 
338 inline __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 }
342 inline __host__ __device__ void operator+=(float3 &a, float3 b)
343 {
344  a.x += b.x; a.y += b.y; a.z += b.z;
345 }
346 inline __host__ __device__ float3 operator+(float3 a, float b)
347 {
348  return make_float3(a.x + b, a.y + b, a.z + b);
349 }
350 inline __host__ __device__ void operator+=(float3 &a, float b)
351 {
352  a.x += b; a.y += b; a.z += b;
353 }
354 
355 inline __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 }
359 inline __host__ __device__ void operator+=(int3 &a, int3 b)
360 {
361  a.x += b.x; a.y += b.y; a.z += b.z;
362 }
363 inline __host__ __device__ int3 operator+(int3 a, int b)
364 {
365  return make_int3(a.x + b, a.y + b, a.z + b);
366 }
367 inline __host__ __device__ void operator+=(int3 &a, int b)
368 {
369  a.x += b; a.y += b; a.z += b;
370 }
371 
372 inline __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 }
376 inline __host__ __device__ void operator+=(uint3 &a, uint3 b)
377 {
378  a.x += b.x; a.y += b.y; a.z += b.z;
379 }
380 inline __host__ __device__ uint3 operator+(uint3 a, uint b)
381 {
382  return make_uint3(a.x + b, a.y + b, a.z + b);
383 }
384 inline __host__ __device__ void operator+=(uint3 &a, uint b)
385 {
386  a.x += b; a.y += b; a.z += b;
387 }
388 
389 inline __host__ __device__ int3 operator+(int b, int3 a)
390 {
391  return make_int3(a.x + b, a.y + b, a.z + b);
392 }
393 inline __host__ __device__ uint3 operator+(uint b, uint3 a)
394 {
395  return make_uint3(a.x + b, a.y + b, a.z + b);
396 }
397 inline __host__ __device__ float3 operator+(float b, float3 a)
398 {
399  return make_float3(a.x + b, a.y + b, a.z + b);
400 }
401 
402 inline __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 }
406 inline __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 }
410 inline __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 }
414 inline __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 }
418 inline __host__ __device__ void operator+=(float4 &a, float b)
419 {
420  a.x += b; a.y += b; a.z += b; a.w += b;
421 }
422 
423 inline __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 }
427 inline __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 }
431 inline __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 }
435 inline __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 }
439 inline __host__ __device__ void operator+=(int4 &a, int b)
440 {
441  a.x += b; a.y += b; a.z += b; a.w += b;
442 }
443 
444 inline __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 }
448 inline __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 }
452 inline __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 }
456 inline __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 }
460 inline __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 
469 inline __host__ __device__ float2 operator-(float2 a, float2 b)
470 {
471  return make_float2(a.x - b.x, a.y - b.y);
472 }
473 inline __host__ __device__ void operator-=(float2 &a, float2 b)
474 {
475  a.x -= b.x; a.y -= b.y;
476 }
477 inline __host__ __device__ float2 operator-(float2 a, float b)
478 {
479  return make_float2(a.x - b, a.y - b);
480 }
481 inline __host__ __device__ float2 operator-(float b, float2 a)
482 {
483  return make_float2(b - a.x, b - a.y);
484 }
485 inline __host__ __device__ void operator-=(float2 &a, float b)
486 {
487  a.x -= b; a.y -= b;
488 }
489 
490 inline __host__ __device__ int2 operator-(int2 a, int2 b)
491 {
492  return make_int2(a.x - b.x, a.y - b.y);
493 }
494 inline __host__ __device__ void operator-=(int2 &a, int2 b)
495 {
496  a.x -= b.x; a.y -= b.y;
497 }
498 inline __host__ __device__ int2 operator-(int2 a, int b)
499 {
500  return make_int2(a.x - b, a.y - b);
501 }
502 inline __host__ __device__ int2 operator-(int b, int2 a)
503 {
504  return make_int2(b - a.x, b - a.y);
505 }
506 inline __host__ __device__ void operator-=(int2 &a, int b)
507 {
508  a.x -= b; a.y -= b;
509 }
510 
511 inline __host__ __device__ uint2 operator-(uint2 a, uint2 b)
512 {
513  return make_uint2(a.x - b.x, a.y - b.y);
514 }
515 inline __host__ __device__ void operator-=(uint2 &a, uint2 b)
516 {
517  a.x -= b.x; a.y -= b.y;
518 }
519 inline __host__ __device__ uint2 operator-(uint2 a, uint b)
520 {
521  return make_uint2(a.x - b, a.y - b);
522 }
523 inline __host__ __device__ uint2 operator-(uint b, uint2 a)
524 {
525  return make_uint2(b - a.x, b - a.y);
526 }
527 inline __host__ __device__ void operator-=(uint2 &a, uint b)
528 {
529  a.x -= b; a.y -= b;
530 }
531 
532 inline __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 }
536 inline __host__ __device__ void operator-=(float3 &a, float3 b)
537 {
538  a.x -= b.x; a.y -= b.y; a.z -= b.z;
539 }
540 inline __host__ __device__ float3 operator-(float3 a, float b)
541 {
542  return make_float3(a.x - b, a.y - b, a.z - b);
543 }
544 inline __host__ __device__ float3 operator-(float b, float3 a)
545 {
546  return make_float3(b - a.x, b - a.y, b - a.z);
547 }
548 inline __host__ __device__ void operator-=(float3 &a, float b)
549 {
550  a.x -= b; a.y -= b; a.z -= b;
551 }
552 
553 inline __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 }
557 inline __host__ __device__ void operator-=(int3 &a, int3 b)
558 {
559  a.x -= b.x; a.y -= b.y; a.z -= b.z;
560 }
561 inline __host__ __device__ int3 operator-(int3 a, int b)
562 {
563  return make_int3(a.x - b, a.y - b, a.z - b);
564 }
565 inline __host__ __device__ int3 operator-(int b, int3 a)
566 {
567  return make_int3(b - a.x, b - a.y, b - a.z);
568 }
569 inline __host__ __device__ void operator-=(int3 &a, int b)
570 {
571  a.x -= b; a.y -= b; a.z -= b;
572 }
573 
574 inline __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 }
578 inline __host__ __device__ void operator-=(uint3 &a, uint3 b)
579 {
580  a.x -= b.x; a.y -= b.y; a.z -= b.z;
581 }
582 inline __host__ __device__ uint3 operator-(uint3 a, uint b)
583 {
584  return make_uint3(a.x - b, a.y - b, a.z - b);
585 }
586 inline __host__ __device__ uint3 operator-(uint b, uint3 a)
587 {
588  return make_uint3(b - a.x, b - a.y, b - a.z);
589 }
590 inline __host__ __device__ void operator-=(uint3 &a, uint b)
591 {
592  a.x -= b; a.y -= b; a.z -= b;
593 }
594 
595 inline __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 }
599 inline __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 }
603 inline __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 }
607 inline __host__ __device__ void operator-=(float4 &a, float b)
608 {
609  a.x -= b; a.y -= b; a.z -= b; a.w -= b;
610 }
611 
612 inline __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 }
616 inline __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 }
620 inline __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 }
624 inline __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 }
628 inline __host__ __device__ void operator-=(int4 &a, int b)
629 {
630  a.x -= b; a.y -= b; a.z -= b; a.w -= b;
631 }
632 
633 inline __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 }
637 inline __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 }
641 inline __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 }
645 inline __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 }
649 inline __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 
658 inline __host__ __device__ float2 operator*(float2 a, float2 b)
659 {
660  return make_float2(a.x * b.x, a.y * b.y);
661 }
662 inline __host__ __device__ void operator*=(float2 &a, float2 b)
663 {
664  a.x *= b.x; a.y *= b.y;
665 }
666 inline __host__ __device__ float2 operator*(float2 a, float b)
667 {
668  return make_float2(a.x * b, a.y * b);
669 }
670 inline __host__ __device__ float2 operator*(float b, float2 a)
671 {
672  return make_float2(b * a.x, b * a.y);
673 }
674 inline __host__ __device__ void operator*=(float2 &a, float b)
675 {
676  a.x *= b; a.y *= b;
677 }
678 
679 inline __host__ __device__ int2 operator*(int2 a, int2 b)
680 {
681  return make_int2(a.x * b.x, a.y * b.y);
682 }
683 inline __host__ __device__ void operator*=(int2 &a, int2 b)
684 {
685  a.x *= b.x; a.y *= b.y;
686 }
687 inline __host__ __device__ int2 operator*(int2 a, int b)
688 {
689  return make_int2(a.x * b, a.y * b);
690 }
691 inline __host__ __device__ int2 operator*(int b, int2 a)
692 {
693  return make_int2(b * a.x, b * a.y);
694 }
695 inline __host__ __device__ void operator*=(int2 &a, int b)
696 {
697  a.x *= b; a.y *= b;
698 }
699 
700 inline __host__ __device__ uint2 operator*(uint2 a, uint2 b)
701 {
702  return make_uint2(a.x * b.x, a.y * b.y);
703 }
704 inline __host__ __device__ void operator*=(uint2 &a, uint2 b)
705 {
706  a.x *= b.x; a.y *= b.y;
707 }
708 inline __host__ __device__ uint2 operator*(uint2 a, uint b)
709 {
710  return make_uint2(a.x * b, a.y * b);
711 }
712 inline __host__ __device__ uint2 operator*(uint b, uint2 a)
713 {
714  return make_uint2(b * a.x, b * a.y);
715 }
716 inline __host__ __device__ void operator*=(uint2 &a, uint b)
717 {
718  a.x *= b; a.y *= b;
719 }
720 
721 inline __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 }
725 inline __host__ __device__ void operator*=(float3 &a, float3 b)
726 {
727  a.x *= b.x; a.y *= b.y; a.z *= b.z;
728 }
729 inline __host__ __device__ float3 operator*(float3 a, float b)
730 {
731  return make_float3(a.x * b, a.y * b, a.z * b);
732 }
733 inline __host__ __device__ float3 operator*(float b, float3 a)
734 {
735  return make_float3(b * a.x, b * a.y, b * a.z);
736 }
737 inline __host__ __device__ void operator*=(float3 &a, float b)
738 {
739  a.x *= b; a.y *= b; a.z *= b;
740 }
741 
742 inline __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 }
746 inline __host__ __device__ void operator*=(int3 &a, int3 b)
747 {
748  a.x *= b.x; a.y *= b.y; a.z *= b.z;
749 }
750 inline __host__ __device__ int3 operator*(int3 a, int b)
751 {
752  return make_int3(a.x * b, a.y * b, a.z * b);
753 }
754 inline __host__ __device__ int3 operator*(int b, int3 a)
755 {
756  return make_int3(b * a.x, b * a.y, b * a.z);
757 }
758 inline __host__ __device__ void operator*=(int3 &a, int b)
759 {
760  a.x *= b; a.y *= b; a.z *= b;
761 }
762 
763 inline __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 }
767 inline __host__ __device__ void operator*=(uint3 &a, uint3 b)
768 {
769  a.x *= b.x; a.y *= b.y; a.z *= b.z;
770 }
771 inline __host__ __device__ uint3 operator*(uint3 a, uint b)
772 {
773  return make_uint3(a.x * b, a.y * b, a.z * b);
774 }
775 inline __host__ __device__ uint3 operator*(uint b, uint3 a)
776 {
777  return make_uint3(b * a.x, b * a.y, b * a.z);
778 }
779 inline __host__ __device__ void operator*=(uint3 &a, uint b)
780 {
781  a.x *= b; a.y *= b; a.z *= b;
782 }
783 
784 inline __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 }
788 inline __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 }
792 inline __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 }
796 inline __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 }
800 inline __host__ __device__ void operator*=(float4 &a, float b)
801 {
802  a.x *= b; a.y *= b; a.z *= b; a.w *= b;
803 }
804 
805 inline __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 }
809 inline __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 }
813 inline __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 }
817 inline __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 }
821 inline __host__ __device__ void operator*=(int4 &a, int b)
822 {
823  a.x *= b; a.y *= b; a.z *= b; a.w *= b;
824 }
825 
826 inline __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 }
830 inline __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 }
834 inline __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 }
838 inline __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 }
842 inline __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 
851 inline __host__ __device__ float2 operator/(float2 a, float2 b)
852 {
853  return make_float2(a.x / b.x, a.y / b.y);
854 }
855 inline __host__ __device__ void operator/=(float2 &a, float2 b)
856 {
857  a.x /= b.x; a.y /= b.y;
858 }
859 inline __host__ __device__ float2 operator/(float2 a, float b)
860 {
861  return make_float2(a.x / b, a.y / b);
862 }
863 inline __host__ __device__ void operator/=(float2 &a, float b)
864 {
865  a.x /= b; a.y /= b;
866 }
867 inline __host__ __device__ float2 operator/(float b, float2 a)
868 {
869  return make_float2(b / a.x, b / a.y);
870 }
871 
872 inline __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 }
876 inline __host__ __device__ void operator/=(float3 &a, float3 b)
877 {
878  a.x /= b.x; a.y /= b.y; a.z /= b.z;
879 }
880 inline __host__ __device__ float3 operator/(float3 a, float b)
881 {
882  return make_float3(a.x / b, a.y / b, a.z / b);
883 }
884 inline __host__ __device__ void operator/=(float3 &a, float b)
885 {
886  a.x /= b; a.y /= b; a.z /= b;
887 }
888 inline __host__ __device__ float3 operator/(float b, float3 a)
889 {
890  return make_float3(b / a.x, b / a.y, b / a.z);
891 }
892 
893 inline __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 }
897 inline __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 }
901 inline __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 }
905 inline __host__ __device__ void operator/=(float4 &a, float b)
906 {
907  a.x /= b; a.y /= b; a.z /= b; a.w /= b;
908 }
909 inline __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 
917 inline __host__ __device__ float2 fminf(float2 a, float2 b)
918 {
919  return make_float2(fminf(a.x,b.x), fminf(a.y,b.y));
920 }
921 inline __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 }
925 inline __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 
930 inline __host__ __device__ int2 min(int2 a, int2 b)
931 {
932  return make_int2(min(a.x,b.x), min(a.y,b.y));
933 }
934 inline __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 }
938 inline __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 
943 inline __host__ __device__ uint2 min(uint2 a, uint2 b)
944 {
945  return make_uint2(min(a.x,b.x), min(a.y,b.y));
946 }
947 inline __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 }
951 inline __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 
960 inline __host__ __device__ float2 fmaxf(float2 a, float2 b)
961 {
962  return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y));
963 }
964 inline __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 }
968 inline __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 
973 inline __host__ __device__ int2 max(int2 a, int2 b)
974 {
975  return make_int2(max(a.x,b.x), max(a.y,b.y));
976 }
977 inline __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 }
981 inline __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 
986 inline __host__ __device__ uint2 max(uint2 a, uint2 b)
987 {
988  return make_uint2(max(a.x,b.x), max(a.y,b.y));
989 }
990 inline __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 }
994 inline __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 inline __device__ __host__ float lerp(float a, float b, float t)
1005 {
1006  return a + t*(b-a);
1007 }
1008 inline __device__ __host__ float2 lerp(float2 a, float2 b, float t)
1009 {
1010  return a + t*(b-a);
1011 }
1012 inline __device__ __host__ float3 lerp(float3 a, float3 b, float t)
1013 {
1014  return a + t*(b-a);
1015 }
1016 inline __device__ __host__ float4 lerp(float4 a, float4 b, float t)
1017 {
1018  return a + t*(b-a);
1019 }
1020 
1021 ////////////////////////////////////////////////////////////////////////////////
1022 // clamp
1023 // - clamp the value v to be in the range [a, b]
1024 ////////////////////////////////////////////////////////////////////////////////
1025 
1026 inline __device__ __host__ float clamp(float f, float a, float b)
1027 {
1028  return fmaxf(a, fminf(f, b));
1029 }
1030 inline __device__ __host__ int clamp(int f, int a, int b)
1031 {
1032  return max(a, min(f, b));
1033 }
1034 inline __device__ __host__ uint clamp(uint f, uint a, uint b)
1035 {
1036  return max(a, min(f, b));
1037 }
1038 
1039 inline __device__ __host__ float2 clamp(float2 v, float a, float b)
1040 {
1041  return make_float2(clamp(v.x, a, b), clamp(v.y, a, b));
1042 }
1043 inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b)
1044 {
1045  return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1046 }
1047 inline __device__ __host__ float3 clamp(float3 v, float a, float b)
1048 {
1049  return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1050 }
1051 inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b)
1052 {
1053  return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1054 }
1055 inline __device__ __host__ float4 clamp(float4 v, float a, float b)
1056 {
1057  return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1058 }
1059 inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b)
1060 {
1061  return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
1062 }
1063 
1064 inline __device__ __host__ int2 clamp(int2 v, int a, int b)
1065 {
1066  return make_int2(clamp(v.x, a, b), clamp(v.y, a, b));
1067 }
1068 inline __device__ __host__ int2 clamp(int2 v, int2 a, int2 b)
1069 {
1070  return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1071 }
1072 inline __device__ __host__ int3 clamp(int3 v, int a, int b)
1073 {
1074  return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1075 }
1076 inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b)
1077 {
1078  return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1079 }
1080 inline __device__ __host__ int4 clamp(int4 v, int a, int b)
1081 {
1082  return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1083 }
1084 inline __device__ __host__ int4 clamp(int4 v, int4 a, int4 b)
1085 {
1086  return make_int4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
1087 }
1088 
1089 inline __device__ __host__ uint2 clamp(uint2 v, uint a, uint b)
1090 {
1091  return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b));
1092 }
1093 inline __device__ __host__ uint2 clamp(uint2 v, uint2 a, uint2 b)
1094 {
1095  return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1096 }
1097 inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b)
1098 {
1099  return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1100 }
1101 inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b)
1102 {
1103  return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1104 }
1105 inline __device__ __host__ uint4 clamp(uint4 v, uint a, uint b)
1106 {
1107  return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1108 }
1109 inline __device__ __host__ uint4 clamp(uint4 v, uint4 a, uint4 b)
1110 {
1111  return make_uint4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
1112 }
1113 
1114 ////////////////////////////////////////////////////////////////////////////////
1115 // dot product
1116 ////////////////////////////////////////////////////////////////////////////////
1117 
1118 inline __host__ __device__ float dot(float2 a, float2 b)
1119 {
1120  return a.x * b.x + a.y * b.y;
1121 }
1122 inline __host__ __device__ float dot(float3 a, float3 b)
1123 {
1124  return a.x * b.x + a.y * b.y + a.z * b.z;
1125 }
1126 inline __host__ __device__ float dot(float4 a, float4 b)
1127 {
1128  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1129 }
1130 
1131 inline __host__ __device__ int dot(int2 a, int2 b)
1132 {
1133  return a.x * b.x + a.y * b.y;
1134 }
1135 inline __host__ __device__ int dot(int3 a, int3 b)
1136 {
1137  return a.x * b.x + a.y * b.y + a.z * b.z;
1138 }
1139 inline __host__ __device__ int dot(int4 a, int4 b)
1140 {
1141  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1142 }
1143 
1144 inline __host__ __device__ uint dot(uint2 a, uint2 b)
1145 {
1146  return a.x * b.x + a.y * b.y;
1147 }
1148 inline __host__ __device__ uint dot(uint3 a, uint3 b)
1149 {
1150  return a.x * b.x + a.y * b.y + a.z * b.z;
1151 }
1152 inline __host__ __device__ uint dot(uint4 a, uint4 b)
1153 {
1154  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
1155 }
1156 
1157 ////////////////////////////////////////////////////////////////////////////////
1158 // length
1159 ////////////////////////////////////////////////////////////////////////////////
1160 
1161 inline __host__ __device__ float length(float2 v)
1162 {
1163  return sqrtf(dot(v, v));
1164 }
1165 inline __host__ __device__ float length(float3 v)
1166 {
1167  return sqrtf(dot(v, v));
1168 }
1169 inline __host__ __device__ float length(float4 v)
1170 {
1171  return sqrtf(dot(v, v));
1172 }
1173 
1174 ////////////////////////////////////////////////////////////////////////////////
1175 // normalize
1176 ////////////////////////////////////////////////////////////////////////////////
1177 
1178 inline __host__ __device__ float2 normalize(float2 v)
1179 {
1180  float invLen = rsqrtf(dot(v, v));
1181  return v * invLen;
1182 }
1183 inline __host__ __device__ float3 normalize(float3 v)
1184 {
1185  float invLen = rsqrtf(dot(v, v));
1186  return v * invLen;
1187 }
1188 inline __host__ __device__ float4 normalize(float4 v)
1189 {
1190  float invLen = rsqrtf(dot(v, v));
1191  return v * invLen;
1192 }
1193 
1194 ////////////////////////////////////////////////////////////////////////////////
1195 // floor
1196 ////////////////////////////////////////////////////////////////////////////////
1197 
1198 inline __host__ __device__ float2 floorf(float2 v)
1199 {
1200  return make_float2(floorf(v.x), floorf(v.y));
1201 }
1202 inline __host__ __device__ float3 floorf(float3 v)
1203 {
1204  return make_float3(floorf(v.x), floorf(v.y), floorf(v.z));
1205 }
1206 inline __host__ __device__ float4 floorf(float4 v)
1207 {
1208  return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w));
1209 }
1210 
1211 ////////////////////////////////////////////////////////////////////////////////
1212 // frac - returns the fractional portion of a scalar or each vector component
1213 ////////////////////////////////////////////////////////////////////////////////
1214 
1215 inline __host__ __device__ float fracf(float v)
1216 {
1217  return v - floorf(v);
1218 }
1219 inline __host__ __device__ float2 fracf(float2 v)
1220 {
1221  return make_float2(fracf(v.x), fracf(v.y));
1222 }
1223 inline __host__ __device__ float3 fracf(float3 v)
1224 {
1225  return make_float3(fracf(v.x), fracf(v.y), fracf(v.z));
1226 }
1227 inline __host__ __device__ float4 fracf(float4 v)
1228 {
1229  return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w));
1230 }
1231 
1232 ////////////////////////////////////////////////////////////////////////////////
1233 // fmod
1234 ////////////////////////////////////////////////////////////////////////////////
1235 
1236 inline __host__ __device__ float2 fmodf(float2 a, float2 b)
1237 {
1238  return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y));
1239 }
1240 inline __host__ __device__ float3 fmodf(float3 a, float3 b)
1241 {
1242  return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z));
1243 }
1244 inline __host__ __device__ float4 fmodf(float4 a, float4 b)
1245 {
1246  return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w));
1247 }
1248 
1249 ////////////////////////////////////////////////////////////////////////////////
1250 // absolute value
1251 ////////////////////////////////////////////////////////////////////////////////
1252 
1253 inline __host__ __device__ float2 fabs(float2 v)
1254 {
1255  return make_float2(fabs(v.x), fabs(v.y));
1256 }
1257 inline __host__ __device__ float3 fabs(float3 v)
1258 {
1259  return make_float3(fabs(v.x), fabs(v.y), fabs(v.z));
1260 }
1261 inline __host__ __device__ float4 fabs(float4 v)
1262 {
1263  return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
1264 }
1265 
1266 inline __host__ __device__ int2 abs(int2 v)
1267 {
1268  return make_int2(abs(v.x), abs(v.y));
1269 }
1270 inline __host__ __device__ int3 abs(int3 v)
1271 {
1272  return make_int3(abs(v.x), abs(v.y), abs(v.z));
1273 }
1274 inline __host__ __device__ int4 abs(int4 v)
1275 {
1276  return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w));
1277 }
1278 
1279 ////////////////////////////////////////////////////////////////////////////////
1280 // reflect
1281 // - returns reflection of incident ray I around surface normal N
1282 // - N should be normalized, reflected vector's length is equal to length of I
1283 ////////////////////////////////////////////////////////////////////////////////
1284 
1285 inline __host__ __device__ float3 reflect(float3 i, float3 n)
1286 {
1287  return i - 2.0f * n * dot(n,i);
1288 }
1289 
1290 ////////////////////////////////////////////////////////////////////////////////
1291 // cross product
1292 ////////////////////////////////////////////////////////////////////////////////
1293 
1294 inline __host__ __device__ float3 cross(float3 a, float3 b)
1295 {
1296  return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
1297 }
1298 
1299 ////////////////////////////////////////////////////////////////////////////////
1300 // smoothstep
1301 // - returns 0 if x < a
1302 // - returns 1 if x > b
1303 // - otherwise returns smooth interpolation between 0 and 1 based on x
1304 ////////////////////////////////////////////////////////////////////////////////
1305 
1306 inline __device__ __host__ float smoothstep(float a, float b, float x)
1307 {
1308  float y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1309  return (y*y*(3.0f - (2.0f*y)));
1310 }
1311 inline __device__ __host__ float2 smoothstep(float2 a, float2 b, float2 x)
1312 {
1313  float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1314  return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y)));
1315 }
1316 inline __device__ __host__ float3 smoothstep(float3 a, float3 b, float3 x)
1317 {
1318  float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1319  return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y)));
1320 }
1321 inline __device__ __host__ float4 smoothstep(float4 a, float4 b, float4 x)
1322 {
1323  float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
1324  return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y)));
1325 }