Point Cloud Library (PCL)  1.9.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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 #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 
38 inline float fminf(float a, float b)
39 {
40  return a < b ? a : b;
41 }
42 
43 inline float fmaxf(float a, float b)
44 {
45  return a > b ? a : b;
46 }
47 
48 inline int max(int a, int b)
49 {
50  return a > b ? a : b;
51 }
52 
53 inline int min(int a, int b)
54 {
55  return a < b ? a : b;
56 }
57 
58 inline float rsqrtf(float x)
59 {
60  return 1.0f / sqrtf(x);
61 }
62 #endif
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 // constructors
66 ////////////////////////////////////////////////////////////////////////////////
67 
68 inline __host__ __device__ float2 make_float2(float s)
69 {
70  return make_float2(s, s);
71 }
72 inline __host__ __device__ float2 make_float2(float3 a)
73 {
74  return make_float2(a.x, a.y);
75 }
76 inline __host__ __device__ float2 make_float2(int2 a)
77 {
78  return make_float2(float(a.x), float(a.y));
79 }
80 inline __host__ __device__ float2 make_float2(uint2 a)
81 {
82  return make_float2(float(a.x), float(a.y));
83 }
84 
85 inline __host__ __device__ int2 make_int2(int s)
86 {
87  return make_int2(s, s);
88 }
89 inline __host__ __device__ int2 make_int2(int3 a)
90 {
91  return make_int2(a.x, a.y);
92 }
93 inline __host__ __device__ int2 make_int2(uint2 a)
94 {
95  return make_int2(int(a.x), int(a.y));
96 }
97 inline __host__ __device__ int2 make_int2(float2 a)
98 {
99  return make_int2(int(a.x), int(a.y));
100 }
101 
102 inline __host__ __device__ uint2 make_uint2(uint s)
103 {
104  return make_uint2(s, s);
105 }
106 inline __host__ __device__ uint2 make_uint2(uint3 a)
107 {
108  return make_uint2(a.x, a.y);
109 }
110 inline __host__ __device__ uint2 make_uint2(int2 a)
111 {
112  return make_uint2(uint(a.x), uint(a.y));
113 }
114 
115 inline __host__ __device__ float3 make_float3(float s)
116 {
117  return make_float3(s, s, s);
118 }
119 inline __host__ __device__ float3 make_float3(float2 a)
120 {
121  return make_float3(a.x, a.y, 0.0f);
122 }
123 inline __host__ __device__ float3 make_float3(float2 a, float s)
124 {
125  return make_float3(a.x, a.y, s);
126 }
127 inline __host__ __device__ float3 make_float3(float4 a)
128 {
129  return make_float3(a.x, a.y, a.z);
130 }
131 inline __host__ __device__ float3 make_float3(int3 a)
132 {
133  return make_float3(float(a.x), float(a.y), float(a.z));
134 }
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 
140 inline __host__ __device__ int3 make_int3(int s)
141 {
142  return make_int3(s, s, s);
143 }
144 inline __host__ __device__ int3 make_int3(int2 a)
145 {
146  return make_int3(a.x, a.y, 0);
147 }
148 inline __host__ __device__ int3 make_int3(int2 a, int s)
149 {
150  return make_int3(a.x, a.y, s);
151 }
152 inline __host__ __device__ int3 make_int3(uint3 a)
153 {
154  return make_int3(int(a.x), int(a.y), int(a.z));
155 }
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 
161 inline __host__ __device__ uint3 make_uint3(uint s)
162 {
163  return make_uint3(s, s, s);
164 }
165 inline __host__ __device__ uint3 make_uint3(uint2 a)
166 {
167  return make_uint3(a.x, a.y, 0);
168 }
169 inline __host__ __device__ uint3 make_uint3(uint2 a, uint s)
170 {
171  return make_uint3(a.x, a.y, s);
172 }
173 inline __host__ __device__ uint3 make_uint3(uint4 a)
174 {
175  return make_uint3(a.x, a.y, a.z);
176 }
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 
182 inline __host__ __device__ float4 make_float4(float s)
183 {
184  return make_float4(s, s, s, s);
185 }
186 inline __host__ __device__ float4 make_float4(float3 a)
187 {
188  return make_float4(a.x, a.y, a.z, 0.0f);
189 }
190 inline __host__ __device__ float4 make_float4(float3 a, float w)
191 {
192  return make_float4(a.x, a.y, a.z, w);
193 }
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 }
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 
203 inline __host__ __device__ int4 make_int4(int s)
204 {
205  return make_int4(s, s, s, s);
206 }
207 inline __host__ __device__ int4 make_int4(int3 a)
208 {
209  return make_int4(a.x, a.y, a.z, 0);
210 }
211 inline __host__ __device__ int4 make_int4(int3 a, int w)
212 {
213  return make_int4(a.x, a.y, a.z, w);
214 }
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 }
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 
225 inline __host__ __device__ uint4 make_uint4(uint s)
226 {
227  return make_uint4(s, s, s, s);
228 }
229 inline __host__ __device__ uint4 make_uint4(uint3 a)
230 {
231  return make_uint4(a.x, a.y, a.z, 0);
232 }
233 inline __host__ __device__ uint4 make_uint4(uint3 a, uint w)
234 {
235  return make_uint4(a.x, a.y, a.z, w);
236 }
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 
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 }
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 }
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 
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 }
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 }
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 
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 }
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 }
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 
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 }
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 }
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 
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 }
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 }
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 
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 }
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 }
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 
1005 inline __device__ __host__ float lerp(float a, float b, float t)
1006 {
1007  return a + t*(b-a);
1008 }
1009 inline __device__ __host__ float2 lerp(float2 a, float2 b, float t)
1010 {
1011  return a + t*(b-a);
1012 }
1013 inline __device__ __host__ float3 lerp(float3 a, float3 b, float t)
1014 {
1015  return a + t*(b-a);
1016 }
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 
1027 inline __device__ __host__ float clamp(float f, float a, float b)
1028 {
1029  return fmaxf(a, fminf(f, b));
1030 }
1031 inline __device__ __host__ int clamp(int f, int a, int b)
1032 {
1033  return max(a, min(f, b));
1034 }
1035 inline __device__ __host__ uint clamp(uint f, uint a, uint b)
1036 {
1037  return max(a, min(f, b));
1038 }
1039 
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 }
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 }
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 }
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 }
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 }
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 
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 }
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 }
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 }
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 }
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 }
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 
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 }
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 }
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 }
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 }
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 }
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 
1119 inline __host__ __device__ float dot(float2 a, float2 b)
1120 {
1121  return a.x * b.x + a.y * b.y;
1122 }
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 }
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 
1132 inline __host__ __device__ int dot(int2 a, int2 b)
1133 {
1134  return a.x * b.x + a.y * b.y;
1135 }
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 }
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 
1145 inline __host__ __device__ uint dot(uint2 a, uint2 b)
1146 {
1147  return a.x * b.x + a.y * b.y;
1148 }
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 }
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 
1162 inline __host__ __device__ float length(float2 v)
1163 {
1164  return sqrtf(dot(v, v));
1165 }
1166 inline __host__ __device__ float length(float3 v)
1167 {
1168  return sqrtf(dot(v, v));
1169 }
1170 inline __host__ __device__ float length(float4 v)
1171 {
1172  return sqrtf(dot(v, v));
1173 }
1174 
1175 ////////////////////////////////////////////////////////////////////////////////
1176 // normalize
1177 ////////////////////////////////////////////////////////////////////////////////
1178 
1179 inline __host__ __device__ float2 normalize(float2 v)
1180 {
1181  float invLen = rsqrtf(dot(v, v));
1182  return v * invLen;
1183 }
1184 inline __host__ __device__ float3 normalize(float3 v)
1185 {
1186  float invLen = rsqrtf(dot(v, v));
1187  return v * invLen;
1188 }
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 
1199 inline __host__ __device__ float2 floorf(float2 v)
1200 {
1201  return make_float2(floorf(v.x), floorf(v.y));
1202 }
1203 inline __host__ __device__ float3 floorf(float3 v)
1204 {
1205  return make_float3(floorf(v.x), floorf(v.y), floorf(v.z));
1206 }
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 
1216 inline __host__ __device__ float fracf(float v)
1217 {
1218  return v - floorf(v);
1219 }
1220 inline __host__ __device__ float2 fracf(float2 v)
1221 {
1222  return make_float2(fracf(v.x), fracf(v.y));
1223 }
1224 inline __host__ __device__ float3 fracf(float3 v)
1225 {
1226  return make_float3(fracf(v.x), fracf(v.y), fracf(v.z));
1227 }
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 
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 }
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 }
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 
1254 inline __host__ __device__ float2 fabs(float2 v)
1255 {
1256  return make_float2(fabs(v.x), fabs(v.y));
1257 }
1258 inline __host__ __device__ float3 fabs(float3 v)
1259 {
1260  return make_float3(fabs(v.x), fabs(v.y), fabs(v.z));
1261 }
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 
1267 inline __host__ __device__ int2 abs(int2 v)
1268 {
1269  return make_int2(abs(v.x), abs(v.y));
1270 }
1271 inline __host__ __device__ int3 abs(int3 v)
1272 {
1273  return make_int3(abs(v.x), abs(v.y), abs(v.z));
1274 }
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 
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 
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 
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 }
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 }
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 }
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