OptiX  3.9
NVIDIA OptiX Acceleration Engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
optixu_math_namespace.h
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 1993 - 2010 NVIDIA Corporation. All rights reserved.
4  *
5  * NOTICE TO USER:
6  *
7  * This source code is subject to NVIDIA ownership rights under U.S. and
8  * international Copyright laws. Users and possessors of this source code
9  * are hereby granted a nonexclusive, royalty-free license to use this code
10  * in individual and commercial software.
11  *
12  * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
13  * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
14  * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
15  * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
17  * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
18  * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
20  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
21  * OR PERFORMANCE OF THIS SOURCE CODE.
22  *
23  * U.S. Government End Users. This source code is a "commercial item" as
24  * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
25  * "commercial computer software" and "commercial computer software
26  * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
27  * and is provided to the U.S. Government only as a commercial end item.
28  * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
29  * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
30  * source code with only those rights set forth herein.
31  *
32  * Any use of this source code in individual and commercial software must
33  * include, in the user documentation and internal comments to the code,
34  * the above Disclaimer and U.S. Government End Users Notice.
35  */
36 
37 
53 #ifndef __optixu_optixu_math_namespace_h__
54 #define __optixu_optixu_math_namespace_h__
55 
56 #include "../optix.h" // For RT_HOSTDEVICE
57 #include "../internal/optix_datatypes.h" // For optix::Ray
58 #include "optixu_vector_functions.h"
59 #include "../optix_sizet.h"
60 
61 #if !defined(_WIN32)
62 // On posix systems uint and ushort are defined when including this file, so we need to
63 // guarantee this file gets included in order to get these typedefs.
64 # include <sys/types.h>
65 #endif
66 
69 // #define these constants such that we are sure
70 // 32b floats are emitted in ptx
71 #ifndef M_Ef
72 #define M_Ef 2.71828182845904523536f
73 #endif
74 #ifndef M_LOG2Ef
75 #define M_LOG2Ef 1.44269504088896340736f
76 #endif
77 #ifndef M_LOG10Ef
78 #define M_LOG10Ef 0.434294481903251827651f
79 #endif
80 #ifndef M_LN2f
81 #define M_LN2f 0.693147180559945309417f
82 #endif
83 #ifndef M_LN10f
84 #define M_LN10f 2.30258509299404568402f
85 #endif
86 #ifndef M_PIf
87 #define M_PIf 3.14159265358979323846f
88 #endif
89 #ifndef M_PI_2f
90 #define M_PI_2f 1.57079632679489661923f
91 #endif
92 #ifndef M_PI_4f
93 #define M_PI_4f 0.785398163397448309616f
94 #endif
95 #ifndef M_1_PIf
96 #define M_1_PIf 0.318309886183790671538f
97 #endif
98 #ifndef M_2_PIf
99 #define M_2_PIf 0.636619772367581343076f
100 #endif
101 #ifndef M_2_SQRTPIf
102 #define M_2_SQRTPIf 1.12837916709551257390f
103 #endif
104 #ifndef M_SQRT2f
105 #define M_SQRT2f 1.41421356237309504880f
106 #endif
107 #ifndef M_SQRT1_2f
108 #define M_SQRT1_2f 0.707106781186547524401f
109 #endif
110 
113 // __forceinline__ works in cuda, VS, and with gcc. Leave it as macro in case
114 // we need to make this per-platform or we want to switch off inlining globally.
115 #ifndef OPTIXU_INLINE
116 # define OPTIXU_INLINE_DEFINED 1
117 # define OPTIXU_INLINE __forceinline__
118 #endif // OPTIXU_INLINE
119 
120 /******************************************************************************/
121 namespace optix {
122 #if defined(_WIN32) && !defined(RT_UINT_USHORT_DEFINED)
123  // uint and ushort are not already defined on Windows systems or they could have been
124  // defined in optixu_math.h.
125  typedef unsigned int uint;
126  typedef unsigned short ushort;
127 #else
128  // On Posix systems these typedefs are defined in the global namespace, and to avoid
129  // conflicts, we'll pull them into this namespace for consistency.
130  using ::uint;
131  using ::ushort;
132 #endif //defined(_WIN32)
133 } // end namespace optix
134 
135 #if !defined(__CUDACC__)
136 /* Functions that CUDA provides for device code but are lacking on some host platform */
137 
138 #include <math.h>
139 
140 // On systems that declare (but not define) these functions we need to define them here.
141 // The system versions are not inlinable and cause slower perforance. In addition we
142 // can't define them in a namespace, because we need to override the one declared extern
143 // in the global namespace and subsequent overloaded versions need to qualify their call
144 // with the global namespace to avoid auto-casting from float to float3 and friends.
145 // Later we pull in the definitions into the optix namespace.
146 //
147 // On systems that don't have any version of these functions declared, we go ahead and
148 // define them in the optix namespace.
149 
150 // On Windows pre VS 2013 these functions were not declared or defined.
151 // Define them in optix namespace.
152 #if defined(_WIN32) && (_MSC_VER < 1800)
153 # define OPTIXU_MATH_DEFINE_IN_NAMESPACE
154 #endif
155 // On Windows VS 2013+ these functions are declared extern in global namespace.
156 // Override them by defining them in global namespace.
157 // Bring them in optix namespace
158 #if defined(_WIN32) && (_MSC_VER >= 1800)
159 # define OPTIXU_MATH_BRING_IN_NAMESPACE
160 #endif
161 // On non-windows systems (POSIX) these are declared extern in global namespace.
162 // Override them by defining them in global namespace.
163 // Bring them in optix namespace.
164 #if !defined(_WIN32)
165 # define OPTIXU_MATH_BRING_IN_NAMESPACE
166 #endif
167 
168 #if defined(OPTIXU_MATH_DEFINE_IN_NAMESPACE)
169 namespace optix {
170 #endif
171 
172 OPTIXU_INLINE float fminf(const float a, const float b)
173 {
174  return a < b ? a : b;
175 }
176 
177 OPTIXU_INLINE float fmaxf(const float a, const float b)
178 {
179  return a > b ? a : b;
180 }
181 
183 OPTIXU_INLINE float copysignf(const float dst, const float src)
184 {
185  union {
186  float f;
187  unsigned int i;
188  } v1, v2, v3;
189  v1.f = src;
190  v2.f = dst;
191  v3.i = (v2.i & 0x7fffffff) | (v1.i & 0x80000000);
192 
193  return v3.f;
194 }
195 
196 #if defined(OPTIXU_MATH_DEFINE_IN_NAMESPACE)
197 } // end namespace optix
198 #endif
199 
200 #if defined(OPTIXU_MATH_BRING_IN_NAMESPACE)
201 namespace optix {
202  using ::fminf;
203  using ::fmaxf;
204  using ::copysignf;
205 } // end namespace optix
206 #endif
207 
208 // Remove these definitions as they are no longer needed, and we don't want them escaping
209 // this header file.
210 #undef OPTIXU_MATH_BRING_IN_NAMESPACE
211 #undef OPTIXU_MATH_DEFINE_IN_NAMESPACE
212 
213 #endif // #ifndef __CUDACC__
214 
215 namespace optix {
216  // On Posix systems these functions are defined in the global namespace, but we need to
217  // pull them into the optix namespace in order for them to be on the same level as
218  // the other overloaded functions in optix::.
219 
220 #if !defined(_WIN32) || defined (__CUDACC__)
221  // These functions are in the global namespace on POSIX (not _WIN32) and in CUDA C.
222  using ::fminf;
223  using ::fmaxf;
224  using ::copysignf;
225 #endif
226  using ::expf;
227  using ::floorf;
228 
229  // These are defined by CUDA in the global namespace.
230 #ifdef __CUDACC__
231  using ::min;
232  using ::max;
233 #else
234 #if defined(_WIN32) && !defined(NOMINMAX)
235 # error "optixu_math_namespace.h needs NOMINMAX defined on windows."
236 #endif
237  OPTIXU_INLINE int max(int a, int b)
238  {
239  return a > b ? a : b;
240  }
241 
242  OPTIXU_INLINE int min(int a, int b)
243  {
244  return a < b ? a : b;
245  }
246 #endif
247 
248 } // end namespace optix
249 
250 
251 namespace optix {
252 
253 /* Bit preserving casting functions */
254 /******************************************************************************/
255 
256 #ifdef __CUDACC__
257 
258  using ::float_as_int;
259  using ::int_as_float;
260 
261 #else
262 
264 OPTIXU_INLINE int float_as_int(const float f)
265 {
266  union {
267  float f;
268  int i;
269  } v1;
270 
271  v1.f = f;
272  return v1.i;
273 }
274 
276 OPTIXU_INLINE float int_as_float(int i)
277 {
278  union {
279  float f;
280  int i;
281  } v1;
282 
283  v1.i = i;
284  return v1.f;
285 }
286 
287 #endif
288 
289 
290 /* float functions */
291 /******************************************************************************/
292 
294 OPTIXU_INLINE RT_HOSTDEVICE float lerp(const float a, const float b, const float t)
295 {
296  return a + t*(b-a);
297 }
298 
300 OPTIXU_INLINE RT_HOSTDEVICE float bilerp(const float x00, const float x10, const float x01, const float x11,
301  const float u, const float v)
302 {
303  return lerp( lerp( x00, x10, u ), lerp( x01, x11, u ), v );
304 }
305 
307 OPTIXU_INLINE RT_HOSTDEVICE float clamp(const float f, const float a, const float b)
308 {
309  return fmaxf(a, fminf(f, b));
310 }
311 
313 OPTIXU_INLINE RT_HOSTDEVICE float getByIndex(const float1& v, int i)
314 {
315  return ((float*)(&v))[i];
316 }
317 
319 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(float1& v, int i, float x)
320 {
321  ((float*)(&v))[i] = x;
322 }
323 
324 /* float2 functions */
325 /******************************************************************************/
326 
330 OPTIXU_INLINE RT_HOSTDEVICE float2 make_float2(const float s)
331 {
332  return make_float2(s, s);
333 }
334 OPTIXU_INLINE RT_HOSTDEVICE float2 make_float2(const int2& a)
335 {
336  return make_float2(float(a.x), float(a.y));
337 }
338 OPTIXU_INLINE RT_HOSTDEVICE float2 make_float2(const uint2& a)
339 {
340  return make_float2(float(a.x), float(a.y));
341 }
345 OPTIXU_INLINE RT_HOSTDEVICE float2 operator-(const float2& a)
346 {
347  return make_float2(-a.x, -a.y);
348 }
349 
353 OPTIXU_INLINE RT_HOSTDEVICE float2 fminf(const float2& a, const float2& b)
354 {
355  return make_float2(fminf(a.x,b.x), fminf(a.y,b.y));
356 }
357 OPTIXU_INLINE RT_HOSTDEVICE float fminf(const float2& a)
358 {
359  return fminf(a.x, a.y);
360 }
366 OPTIXU_INLINE RT_HOSTDEVICE float2 fmaxf(const float2& a, const float2& b)
367 {
368  return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y));
369 }
370 OPTIXU_INLINE RT_HOSTDEVICE float fmaxf(const float2& a)
371 {
372  return fmaxf(a.x, a.y);
373 }
379 OPTIXU_INLINE RT_HOSTDEVICE float2 operator+(const float2& a, const float2& b)
380 {
381  return make_float2(a.x + b.x, a.y + b.y);
382 }
383 OPTIXU_INLINE RT_HOSTDEVICE float2 operator+(const float2& a, const float b)
384 {
385  return make_float2(a.x + b, a.y + b);
386 }
387 OPTIXU_INLINE RT_HOSTDEVICE float2 operator+(const float a, const float2& b)
388 {
389  return make_float2(a + b.x, a + b.y);
390 }
391 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(float2& a, const float2& b)
392 {
393  a.x += b.x; a.y += b.y;
394 }
400 OPTIXU_INLINE RT_HOSTDEVICE float2 operator-(const float2& a, const float2& b)
401 {
402  return make_float2(a.x - b.x, a.y - b.y);
403 }
404 OPTIXU_INLINE RT_HOSTDEVICE float2 operator-(const float2& a, const float b)
405 {
406  return make_float2(a.x - b, a.y - b);
407 }
408 OPTIXU_INLINE RT_HOSTDEVICE float2 operator-(const float a, const float2& b)
409 {
410  return make_float2(a - b.x, a - b.y);
411 }
412 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(float2& a, const float2& b)
413 {
414  a.x -= b.x; a.y -= b.y;
415 }
421 OPTIXU_INLINE RT_HOSTDEVICE float2 operator*(const float2& a, const float2& b)
422 {
423  return make_float2(a.x * b.x, a.y * b.y);
424 }
425 OPTIXU_INLINE RT_HOSTDEVICE float2 operator*(const float2& a, const float s)
426 {
427  return make_float2(a.x * s, a.y * s);
428 }
429 OPTIXU_INLINE RT_HOSTDEVICE float2 operator*(const float s, const float2& a)
430 {
431  return make_float2(a.x * s, a.y * s);
432 }
433 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(float2& a, const float2& s)
434 {
435  a.x *= s.x; a.y *= s.y;
436 }
437 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(float2& a, const float s)
438 {
439  a.x *= s; a.y *= s;
440 }
446 OPTIXU_INLINE RT_HOSTDEVICE float2 operator/(const float2& a, const float2& b)
447 {
448  return make_float2(a.x / b.x, a.y / b.y);
449 }
450 OPTIXU_INLINE RT_HOSTDEVICE float2 operator/(const float2& a, const float s)
451 {
452  float inv = 1.0f / s;
453  return a * inv;
454 }
455 OPTIXU_INLINE RT_HOSTDEVICE float2 operator/(const float s, const float2& a)
456 {
457  return make_float2( s/a.x, s/a.y );
458 }
459 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(float2& a, const float s)
460 {
461  float inv = 1.0f / s;
462  a *= inv;
463 }
467 OPTIXU_INLINE RT_HOSTDEVICE float2 lerp(const float2& a, const float2& b, const float t)
468 {
469  return a + t*(b-a);
470 }
471 
473 OPTIXU_INLINE RT_HOSTDEVICE float2 bilerp(const float2& x00, const float2& x10, const float2& x01, const float2& x11,
474  const float u, const float v)
475 {
476  return lerp( lerp( x00, x10, u ), lerp( x01, x11, u ), v );
477 }
478 
482 OPTIXU_INLINE RT_HOSTDEVICE float2 clamp(const float2& v, const float a, const float b)
483 {
484  return make_float2(clamp(v.x, a, b), clamp(v.y, a, b));
485 }
486 
487 OPTIXU_INLINE RT_HOSTDEVICE float2 clamp(const float2& v, const float2& a, const float2& b)
488 {
489  return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
490 }
494 OPTIXU_INLINE RT_HOSTDEVICE float dot(const float2& a, const float2& b)
495 {
496  return a.x * b.x + a.y * b.y;
497 }
498 
500 OPTIXU_INLINE RT_HOSTDEVICE float length(const float2& v)
501 {
502  return sqrtf(dot(v, v));
503 }
504 
506 OPTIXU_INLINE RT_HOSTDEVICE float2 normalize(const float2& v)
507 {
508  float invLen = 1.0f / sqrtf(dot(v, v));
509  return v * invLen;
510 }
511 
513 OPTIXU_INLINE RT_HOSTDEVICE float2 floor(const float2& v)
514 {
515  return make_float2(::floorf(v.x), ::floorf(v.y));
516 }
517 
519 OPTIXU_INLINE RT_HOSTDEVICE float2 reflect(const float2& i, const float2& n)
520 {
521  return i - 2.0f * n * dot(n,i);
522 }
523 
528 OPTIXU_INLINE RT_HOSTDEVICE float2 faceforward(const float2& n, const float2& i, const float2& nref)
529 {
530  return n * copysignf( 1.0f, dot(i, nref) );
531 }
532 
534 OPTIXU_INLINE RT_HOSTDEVICE float2 expf(const float2& v)
535 {
536  return make_float2(::expf(v.x), ::expf(v.y));
537 }
538 
540 OPTIXU_INLINE RT_HOSTDEVICE float getByIndex(const float2& v, int i)
541 {
542  return ((float*)(&v))[i];
543 }
544 
546 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(float2& v, int i, float x)
547 {
548  ((float*)(&v))[i] = x;
549 }
550 
551 
552 /* float3 functions */
553 /******************************************************************************/
554 
558 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const float s)
559 {
560  return make_float3(s, s, s);
561 }
562 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const float2& a)
563 {
564  return make_float3(a.x, a.y, 0.0f);
565 }
566 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const int3& a)
567 {
568  return make_float3(float(a.x), float(a.y), float(a.z));
569 }
570 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const uint3& a)
571 {
572  return make_float3(float(a.x), float(a.y), float(a.z));
573 }
577 OPTIXU_INLINE RT_HOSTDEVICE float3 operator-(const float3& a)
578 {
579  return make_float3(-a.x, -a.y, -a.z);
580 }
581 
585 OPTIXU_INLINE RT_HOSTDEVICE float3 fminf(const float3& a, const float3& b)
586 {
587  return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z));
588 }
589 OPTIXU_INLINE RT_HOSTDEVICE float fminf(const float3& a)
590 {
591  return fminf(fminf(a.x, a.y), a.z);
592 }
598 OPTIXU_INLINE RT_HOSTDEVICE float3 fmaxf(const float3& a, const float3& b)
599 {
600  return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z));
601 }
602 OPTIXU_INLINE RT_HOSTDEVICE float fmaxf(const float3& a)
603 {
604  return fmaxf(fmaxf(a.x, a.y), a.z);
605 }
611 OPTIXU_INLINE RT_HOSTDEVICE float3 operator+(const float3& a, const float3& b)
612 {
613  return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
614 }
615 OPTIXU_INLINE RT_HOSTDEVICE float3 operator+(const float3& a, const float b)
616 {
617  return make_float3(a.x + b, a.y + b, a.z + b);
618 }
619 OPTIXU_INLINE RT_HOSTDEVICE float3 operator+(const float a, const float3& b)
620 {
621  return make_float3(a + b.x, a + b.y, a + b.z);
622 }
623 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(float3& a, const float3& b)
624 {
625  a.x += b.x; a.y += b.y; a.z += b.z;
626 }
632 OPTIXU_INLINE RT_HOSTDEVICE float3 operator-(const float3& a, const float3& b)
633 {
634  return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
635 }
636 OPTIXU_INLINE RT_HOSTDEVICE float3 operator-(const float3& a, const float b)
637 {
638  return make_float3(a.x - b, a.y - b, a.z - b);
639 }
640 OPTIXU_INLINE RT_HOSTDEVICE float3 operator-(const float a, const float3& b)
641 {
642  return make_float3(a - b.x, a - b.y, a - b.z);
643 }
644 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(float3& a, const float3& b)
645 {
646  a.x -= b.x; a.y -= b.y; a.z -= b.z;
647 }
653 OPTIXU_INLINE RT_HOSTDEVICE float3 operator*(const float3& a, const float3& b)
654 {
655  return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
656 }
657 OPTIXU_INLINE RT_HOSTDEVICE float3 operator*(const float3& a, const float s)
658 {
659  return make_float3(a.x * s, a.y * s, a.z * s);
660 }
661 OPTIXU_INLINE RT_HOSTDEVICE float3 operator*(const float s, const float3& a)
662 {
663  return make_float3(a.x * s, a.y * s, a.z * s);
664 }
665 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(float3& a, const float3& s)
666 {
667  a.x *= s.x; a.y *= s.y; a.z *= s.z;
668 }
669 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(float3& a, const float s)
670 {
671  a.x *= s; a.y *= s; a.z *= s;
672 }
678 OPTIXU_INLINE RT_HOSTDEVICE float3 operator/(const float3& a, const float3& b)
679 {
680  return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
681 }
682 OPTIXU_INLINE RT_HOSTDEVICE float3 operator/(const float3& a, const float s)
683 {
684  float inv = 1.0f / s;
685  return a * inv;
686 }
687 OPTIXU_INLINE RT_HOSTDEVICE float3 operator/(const float s, const float3& a)
688 {
689  return make_float3( s/a.x, s/a.y, s/a.z );
690 }
691 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(float3& a, const float s)
692 {
693  float inv = 1.0f / s;
694  a *= inv;
695 }
699 OPTIXU_INLINE RT_HOSTDEVICE float3 lerp(const float3& a, const float3& b, const float t)
700 {
701  return a + t*(b-a);
702 }
703 
705 OPTIXU_INLINE RT_HOSTDEVICE float3 bilerp(const float3& x00, const float3& x10, const float3& x01, const float3& x11,
706  const float u, const float v)
707 {
708  return lerp( lerp( x00, x10, u ), lerp( x01, x11, u ), v );
709 }
710 
714 OPTIXU_INLINE RT_HOSTDEVICE float3 clamp(const float3& v, const float a, const float b)
715 {
716  return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
717 }
718 
719 OPTIXU_INLINE RT_HOSTDEVICE float3 clamp(const float3& v, const float3& a, const float3& b)
720 {
721  return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
722 }
726 OPTIXU_INLINE RT_HOSTDEVICE float dot(const float3& a, const float3& b)
727 {
728  return a.x * b.x + a.y * b.y + a.z * b.z;
729 }
730 
732 OPTIXU_INLINE RT_HOSTDEVICE float3 cross(const float3& a, const float3& b)
733 {
734  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);
735 }
736 
738 OPTIXU_INLINE RT_HOSTDEVICE float length(const float3& v)
739 {
740  return sqrtf(dot(v, v));
741 }
742 
744 OPTIXU_INLINE RT_HOSTDEVICE float3 normalize(const float3& v)
745 {
746  float invLen = 1.0f / sqrtf(dot(v, v));
747  return v * invLen;
748 }
749 
751 OPTIXU_INLINE RT_HOSTDEVICE float3 floor(const float3& v)
752 {
753  return make_float3(::floorf(v.x), ::floorf(v.y), ::floorf(v.z));
754 }
755 
757 OPTIXU_INLINE RT_HOSTDEVICE float3 reflect(const float3& i, const float3& n)
758 {
759  return i - 2.0f * n * dot(n,i);
760 }
761 
766 OPTIXU_INLINE RT_HOSTDEVICE float3 faceforward(const float3& n, const float3& i, const float3& nref)
767 {
768  return n * copysignf( 1.0f, dot(i, nref) );
769 }
770 
772 OPTIXU_INLINE RT_HOSTDEVICE float3 expf(const float3& v)
773 {
774  return make_float3(::expf(v.x), ::expf(v.y), ::expf(v.z));
775 }
776 
778 OPTIXU_INLINE RT_HOSTDEVICE float getByIndex(const float3& v, int i)
779 {
780  return ((float*)(&v))[i];
781 }
782 
784 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(float3& v, int i, float x)
785 {
786  ((float*)(&v))[i] = x;
787 }
788 
789 /* float4 functions */
790 /******************************************************************************/
791 
795 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float s)
796 {
797  return make_float4(s, s, s, s);
798 }
799 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float3& a)
800 {
801  return make_float4(a.x, a.y, a.z, 0.0f);
802 }
803 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const int4& a)
804 {
805  return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
806 }
807 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const uint4& a)
808 {
809  return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
810 }
814 OPTIXU_INLINE RT_HOSTDEVICE float4 operator-(const float4& a)
815 {
816  return make_float4(-a.x, -a.y, -a.z, -a.w);
817 }
818 
822 OPTIXU_INLINE RT_HOSTDEVICE float4 fminf(const float4& a, const float4& b)
823 {
824  return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w));
825 }
826 OPTIXU_INLINE RT_HOSTDEVICE float fminf(const float4& a)
827 {
828  return fminf(fminf(a.x, a.y), fminf(a.z, a.w));
829 }
835 OPTIXU_INLINE RT_HOSTDEVICE float4 fmaxf(const float4& a, const float4& b)
836 {
837  return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w));
838 }
839 OPTIXU_INLINE RT_HOSTDEVICE float fmaxf(const float4& a)
840 {
841  return fmaxf(fmaxf(a.x, a.y), fmaxf(a.z, a.w));
842 }
848 OPTIXU_INLINE RT_HOSTDEVICE float4 operator+(const float4& a, const float4& b)
849 {
850  return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
851 }
852 OPTIXU_INLINE RT_HOSTDEVICE float4 operator+(const float4& a, const float b)
853 {
854  return make_float4(a.x + b, a.y + b, a.z + b, a.w + b);
855 }
856 OPTIXU_INLINE RT_HOSTDEVICE float4 operator+(const float a, const float4& b)
857 {
858  return make_float4(a + b.x, a + b.y, a + b.z, a + b.w);
859 }
860 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(float4& a, const float4& b)
861 {
862  a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
863 }
869 OPTIXU_INLINE RT_HOSTDEVICE float4 operator-(const float4& a, const float4& b)
870 {
871  return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
872 }
873 OPTIXU_INLINE RT_HOSTDEVICE float4 operator-(const float4& a, const float b)
874 {
875  return make_float4(a.x - b, a.y - b, a.z - b, a.w - b);
876 }
877 OPTIXU_INLINE RT_HOSTDEVICE float4 operator-(const float a, const float4& b)
878 {
879  return make_float4(a - b.x, a - b.y, a - b.z, a - b.w);
880 }
881 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(float4& a, const float4& b)
882 {
883  a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
884 }
890 OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const float4& a, const float4& s)
891 {
892  return make_float4(a.x * s.x, a.y * s.y, a.z * s.z, a.w * s.w);
893 }
894 OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const float4& a, const float s)
895 {
896  return make_float4(a.x * s, a.y * s, a.z * s, a.w * s);
897 }
898 OPTIXU_INLINE RT_HOSTDEVICE float4 operator*(const float s, const float4& a)
899 {
900  return make_float4(a.x * s, a.y * s, a.z * s, a.w * s);
901 }
902 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(float4& a, const float4& s)
903 {
904  a.x *= s.x; a.y *= s.y; a.z *= s.z; a.w *= s.w;
905 }
906 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(float4& a, const float s)
907 {
908  a.x *= s; a.y *= s; a.z *= s; a.w *= s;
909 }
915 OPTIXU_INLINE RT_HOSTDEVICE float4 operator/(const float4& a, const float4& b)
916 {
917  return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
918 }
919 OPTIXU_INLINE RT_HOSTDEVICE float4 operator/(const float4& a, const float s)
920 {
921  float inv = 1.0f / s;
922  return a * inv;
923 }
924 OPTIXU_INLINE RT_HOSTDEVICE float4 operator/(const float s, const float4& a)
925 {
926  return make_float4( s/a.x, s/a.y, s/a.z, s/a.w );
927 }
928 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(float4& a, const float s)
929 {
930  float inv = 1.0f / s;
931  a *= inv;
932 }
936 OPTIXU_INLINE RT_HOSTDEVICE float4 lerp(const float4& a, const float4& b, const float t)
937 {
938  return a + t*(b-a);
939 }
940 
942 OPTIXU_INLINE RT_HOSTDEVICE float4 bilerp(const float4& x00, const float4& x10, const float4& x01, const float4& x11,
943  const float u, const float v)
944 {
945  return lerp( lerp( x00, x10, u ), lerp( x01, x11, u ), v );
946 }
947 
951 OPTIXU_INLINE RT_HOSTDEVICE float4 clamp(const float4& v, const float a, const float b)
952 {
953  return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
954 }
955 
956 OPTIXU_INLINE RT_HOSTDEVICE float4 clamp(const float4& v, const float4& a, const float4& b)
957 {
958  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));
959 }
963 OPTIXU_INLINE RT_HOSTDEVICE float dot(const float4& a, const float4& b)
964 {
965  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
966 }
967 
969 OPTIXU_INLINE RT_HOSTDEVICE float length(const float4& r)
970 {
971  return sqrtf(dot(r, r));
972 }
973 
975 OPTIXU_INLINE RT_HOSTDEVICE float4 normalize(const float4& v)
976 {
977  float invLen = 1.0f / sqrtf(dot(v, v));
978  return v * invLen;
979 }
980 
982 OPTIXU_INLINE RT_HOSTDEVICE float4 floor(const float4& v)
983 {
984  return make_float4(::floorf(v.x), ::floorf(v.y), ::floorf(v.z), ::floorf(v.w));
985 }
986 
988 OPTIXU_INLINE RT_HOSTDEVICE float4 reflect(const float4& i, const float4& n)
989 {
990  return i - 2.0f * n * dot(n,i);
991 }
992 
999 OPTIXU_INLINE RT_HOSTDEVICE float4 faceforward(const float4& n, const float4& i, const float4& nref)
1000 {
1001  return n * copysignf( 1.0f, dot(i, nref) );
1002 }
1003 
1005 OPTIXU_INLINE RT_HOSTDEVICE float4 expf(const float4& v)
1006 {
1007  return make_float4(::expf(v.x), ::expf(v.y), ::expf(v.z), ::expf(v.w));
1008 }
1009 
1011 OPTIXU_INLINE RT_HOSTDEVICE float getByIndex(const float4& v, int i)
1012 {
1013  return ((float*)(&v))[i];
1014 }
1015 
1017 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(float4& v, int i, float x)
1018 {
1019  ((float*)(&v))[i] = x;
1020 }
1021 
1022 
1023 /* int functions */
1024 /******************************************************************************/
1025 
1027 OPTIXU_INLINE RT_HOSTDEVICE int clamp(const int f, const int a, const int b)
1028 {
1029  return max(a, min(f, b));
1030 }
1031 
1033 OPTIXU_INLINE RT_HOSTDEVICE int getByIndex(const int1& v, int i)
1034 {
1035  return ((int*)(&v))[i];
1036 }
1037 
1039 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(int1& v, int i, int x)
1040 {
1041  ((int*)(&v))[i] = x;
1042 }
1043 
1044 
1045 /* int2 functions */
1046 /******************************************************************************/
1047 
1051 OPTIXU_INLINE RT_HOSTDEVICE int2 make_int2(const int s)
1052 {
1053  return make_int2(s, s);
1054 }
1055 OPTIXU_INLINE RT_HOSTDEVICE int2 make_int2(const float2& a)
1056 {
1057  return make_int2(int(a.x), int(a.y));
1058 }
1062 OPTIXU_INLINE RT_HOSTDEVICE int2 operator-(const int2& a)
1063 {
1064  return make_int2(-a.x, -a.y);
1065 }
1066 
1068 OPTIXU_INLINE RT_HOSTDEVICE int2 min(const int2& a, const int2& b)
1069 {
1070  return make_int2(min(a.x,b.x), min(a.y,b.y));
1071 }
1072 
1074 OPTIXU_INLINE RT_HOSTDEVICE int2 max(const int2& a, const int2& b)
1075 {
1076  return make_int2(max(a.x,b.x), max(a.y,b.y));
1077 }
1078 
1082 OPTIXU_INLINE RT_HOSTDEVICE int2 operator+(const int2& a, const int2& b)
1083 {
1084  return make_int2(a.x + b.x, a.y + b.y);
1085 }
1086 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(int2& a, const int2& b)
1087 {
1088  a.x += b.x; a.y += b.y;
1089 }
1095 OPTIXU_INLINE RT_HOSTDEVICE int2 operator-(const int2& a, const int2& b)
1096 {
1097  return make_int2(a.x - b.x, a.y - b.y);
1098 }
1099 OPTIXU_INLINE RT_HOSTDEVICE int2 operator-(const int2& a, const int b)
1100 {
1101  return make_int2(a.x - b, a.y - b);
1102 }
1103 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(int2& a, const int2& b)
1104 {
1105  a.x -= b.x; a.y -= b.y;
1106 }
1112 OPTIXU_INLINE RT_HOSTDEVICE int2 operator*(const int2& a, const int2& b)
1113 {
1114  return make_int2(a.x * b.x, a.y * b.y);
1115 }
1116 OPTIXU_INLINE RT_HOSTDEVICE int2 operator*(const int2& a, const int s)
1117 {
1118  return make_int2(a.x * s, a.y * s);
1119 }
1120 OPTIXU_INLINE RT_HOSTDEVICE int2 operator*(const int s, const int2& a)
1121 {
1122  return make_int2(a.x * s, a.y * s);
1123 }
1124 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(int2& a, const int s)
1125 {
1126  a.x *= s; a.y *= s;
1127 }
1133 OPTIXU_INLINE RT_HOSTDEVICE int2 clamp(const int2& v, const int a, const int b)
1134 {
1135  return make_int2(clamp(v.x, a, b), clamp(v.y, a, b));
1136 }
1137 
1138 OPTIXU_INLINE RT_HOSTDEVICE int2 clamp(const int2& v, const int2& a, const int2& b)
1139 {
1140  return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1141 }
1147 OPTIXU_INLINE RT_HOSTDEVICE bool operator==(const int2& a, const int2& b)
1148 {
1149  return a.x == b.x && a.y == b.y;
1150 }
1151 
1152 OPTIXU_INLINE RT_HOSTDEVICE bool operator!=(const int2& a, const int2& b)
1153 {
1154  return a.x != b.x || a.y != b.y;
1155 }
1159 OPTIXU_INLINE RT_HOSTDEVICE int getByIndex(const int2& v, int i)
1160 {
1161  return ((int*)(&v))[i];
1162 }
1163 
1165 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(int2& v, int i, int x)
1166 {
1167  ((int*)(&v))[i] = x;
1168 }
1169 
1170 
1171 /* int3 functions */
1172 /******************************************************************************/
1173 
1177 OPTIXU_INLINE RT_HOSTDEVICE int3 make_int3(const int s)
1178 {
1179  return make_int3(s, s, s);
1180 }
1181 OPTIXU_INLINE RT_HOSTDEVICE int3 make_int3(const float3& a)
1182 {
1183  return make_int3(int(a.x), int(a.y), int(a.z));
1184 }
1188 OPTIXU_INLINE RT_HOSTDEVICE int3 operator-(const int3& a)
1189 {
1190  return make_int3(-a.x, -a.y, -a.z);
1191 }
1192 
1194 OPTIXU_INLINE RT_HOSTDEVICE int3 min(const int3& a, const int3& b)
1195 {
1196  return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
1197 }
1198 
1200 OPTIXU_INLINE RT_HOSTDEVICE int3 max(const int3& a, const int3& b)
1201 {
1202  return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
1203 }
1204 
1208 OPTIXU_INLINE RT_HOSTDEVICE int3 operator+(const int3& a, const int3& b)
1209 {
1210  return make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
1211 }
1212 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(int3& a, const int3& b)
1213 {
1214  a.x += b.x; a.y += b.y; a.z += b.z;
1215 }
1221 OPTIXU_INLINE RT_HOSTDEVICE int3 operator-(const int3& a, const int3& b)
1222 {
1223  return make_int3(a.x - b.x, a.y - b.y, a.z - b.z);
1224 }
1225 
1226 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(int3& a, const int3& b)
1227 {
1228  a.x -= b.x; a.y -= b.y; a.z -= b.z;
1229 }
1235 OPTIXU_INLINE RT_HOSTDEVICE int3 operator*(const int3& a, const int3& b)
1236 {
1237  return make_int3(a.x * b.x, a.y * b.y, a.z * b.z);
1238 }
1239 OPTIXU_INLINE RT_HOSTDEVICE int3 operator*(const int3& a, const int s)
1240 {
1241  return make_int3(a.x * s, a.y * s, a.z * s);
1242 }
1243 OPTIXU_INLINE RT_HOSTDEVICE int3 operator*(const int s, const int3& a)
1244 {
1245  return make_int3(a.x * s, a.y * s, a.z * s);
1246 }
1247 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(int3& a, const int s)
1248 {
1249  a.x *= s; a.y *= s; a.z *= s;
1250 }
1256 OPTIXU_INLINE RT_HOSTDEVICE int3 operator/(const int3& a, const int3& b)
1257 {
1258  return make_int3(a.x / b.x, a.y / b.y, a.z / b.z);
1259 }
1260 OPTIXU_INLINE RT_HOSTDEVICE int3 operator/(const int3& a, const int s)
1261 {
1262  return make_int3(a.x / s, a.y / s, a.z / s);
1263 }
1264 OPTIXU_INLINE RT_HOSTDEVICE int3 operator/(const int s, const int3& a)
1265 {
1266  return make_int3(s /a.x, s / a.y, s / a.z);
1267 }
1268 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(int3& a, const int s)
1269 {
1270  a.x /= s; a.y /= s; a.z /= s;
1271 }
1277 OPTIXU_INLINE RT_HOSTDEVICE int3 clamp(const int3& v, const int a, const int b)
1278 {
1279  return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1280 }
1281 
1282 OPTIXU_INLINE RT_HOSTDEVICE int3 clamp(const int3& v, const int3& a, const int3& b)
1283 {
1284  return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1285 }
1291 OPTIXU_INLINE RT_HOSTDEVICE bool operator==(const int3& a, const int3& b)
1292 {
1293  return a.x == b.x && a.y == b.y && a.z == b.z;
1294 }
1295 
1296 OPTIXU_INLINE RT_HOSTDEVICE bool operator!=(const int3& a, const int3& b)
1297 {
1298  return a.x != b.x || a.y != b.y || a.z != b.z;
1299 }
1303 OPTIXU_INLINE RT_HOSTDEVICE int getByIndex(const int3& v, int i)
1304 {
1305  return ((int*)(&v))[i];
1306 }
1307 
1309 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(int3& v, int i, int x)
1310 {
1311  ((int*)(&v))[i] = x;
1312 }
1313 
1314 
1315 /* int4 functions */
1316 /******************************************************************************/
1317 
1321 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int s)
1322 {
1323  return make_int4(s, s, s, s);
1324 }
1325 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const float4& a)
1326 {
1327  return make_int4((int)a.x, (int)a.y, (int)a.z, (int)a.w);
1328 }
1332 OPTIXU_INLINE RT_HOSTDEVICE int4 operator-(const int4& a)
1333 {
1334  return make_int4(-a.x, -a.y, -a.z, -a.w);
1335 }
1336 
1338 OPTIXU_INLINE RT_HOSTDEVICE int4 min(const int4& a, const int4& b)
1339 {
1340  return make_int4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w));
1341 }
1342 
1344 OPTIXU_INLINE RT_HOSTDEVICE int4 max(const int4& a, const int4& b)
1345 {
1346  return make_int4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w));
1347 }
1348 
1352 OPTIXU_INLINE RT_HOSTDEVICE int4 operator+(const int4& a, const int4& b)
1353 {
1354  return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
1355 }
1356 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(int4& a, const int4& b)
1357 {
1358  a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
1359 }
1365 OPTIXU_INLINE RT_HOSTDEVICE int4 operator-(const int4& a, const int4& b)
1366 {
1367  return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
1368 }
1369 
1370 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(int4& a, const int4& b)
1371 {
1372  a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
1373 }
1379 OPTIXU_INLINE RT_HOSTDEVICE int4 operator*(const int4& a, const int4& b)
1380 {
1381  return make_int4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
1382 }
1383 OPTIXU_INLINE RT_HOSTDEVICE int4 operator*(const int4& a, const int s)
1384 {
1385  return make_int4(a.x * s, a.y * s, a.z * s, a.w * s);
1386 }
1387 OPTIXU_INLINE RT_HOSTDEVICE int4 operator*(const int s, const int4& a)
1388 {
1389  return make_int4(a.x * s, a.y * s, a.z * s, a.w * s);
1390 }
1391 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(int4& a, const int s)
1392 {
1393  a.x *= s; a.y *= s; a.z *= s; a.w *= s;
1394 }
1400 OPTIXU_INLINE RT_HOSTDEVICE int4 operator/(const int4& a, const int4& b)
1401 {
1402  return make_int4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
1403 }
1404 OPTIXU_INLINE RT_HOSTDEVICE int4 operator/(const int4& a, const int s)
1405 {
1406  return make_int4(a.x / s, a.y / s, a.z / s, a.w / s);
1407 }
1408 OPTIXU_INLINE RT_HOSTDEVICE int4 operator/(const int s, const int4& a)
1409 {
1410  return make_int4(s / a.x, s / a.y, s / a.z, s / a.w);
1411 }
1412 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(int4& a, const int s)
1413 {
1414  a.x /= s; a.y /= s; a.z /= s; a.w /= s;
1415 }
1421 OPTIXU_INLINE RT_HOSTDEVICE int4 clamp(const int4& v, const int a, const int b)
1422 {
1423  return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1424 }
1425 
1426 OPTIXU_INLINE RT_HOSTDEVICE int4 clamp(const int4& v, const int4& a, const int4& b)
1427 {
1428  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));
1429 }
1435 OPTIXU_INLINE RT_HOSTDEVICE bool operator==(const int4& a, const int4& b)
1436 {
1437  return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
1438 }
1439 
1440 OPTIXU_INLINE RT_HOSTDEVICE bool operator!=(const int4& a, const int4& b)
1441 {
1442  return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
1443 }
1447 OPTIXU_INLINE RT_HOSTDEVICE int getByIndex(const int4& v, int i)
1448 {
1449  return ((int*)(&v))[i];
1450 }
1451 
1453 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(int4& v, int i, int x)
1454 {
1455  ((int*)(&v))[i] = x;
1456 }
1457 
1458 
1459 /* uint functions */
1460 /******************************************************************************/
1461 
1463 OPTIXU_INLINE RT_HOSTDEVICE unsigned int clamp(const unsigned int f, const unsigned int a, const unsigned int b)
1464 {
1465  return max(a, min(f, b));
1466 }
1467 
1469 OPTIXU_INLINE RT_HOSTDEVICE unsigned int getByIndex(const uint1& v, unsigned int i)
1470 {
1471  return ((unsigned int*)(&v))[i];
1472 }
1473 
1475 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(uint1& v, int i, unsigned int x)
1476 {
1477  ((unsigned int*)(&v))[i] = x;
1478 }
1479 
1480 
1481 /* uint2 functions */
1482 /******************************************************************************/
1483 
1487 OPTIXU_INLINE RT_HOSTDEVICE uint2 make_uint2(const unsigned int s)
1488 {
1489  return make_uint2(s, s);
1490 }
1491 OPTIXU_INLINE RT_HOSTDEVICE uint2 make_uint2(const float2& a)
1492 {
1493  return make_uint2((unsigned int)a.x, (unsigned int)a.y);
1494 }
1498 OPTIXU_INLINE RT_HOSTDEVICE uint2 min(const uint2& a, const uint2& b)
1499 {
1500  return make_uint2(min(a.x,b.x), min(a.y,b.y));
1501 }
1502 
1504 OPTIXU_INLINE RT_HOSTDEVICE uint2 max(const uint2& a, const uint2& b)
1505 {
1506  return make_uint2(max(a.x,b.x), max(a.y,b.y));
1507 }
1508 
1512 OPTIXU_INLINE RT_HOSTDEVICE uint2 operator+(const uint2& a, const uint2& b)
1513 {
1514  return make_uint2(a.x + b.x, a.y + b.y);
1515 }
1516 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(uint2& a, const uint2& b)
1517 {
1518  a.x += b.x; a.y += b.y;
1519 }
1525 OPTIXU_INLINE RT_HOSTDEVICE uint2 operator-(const uint2& a, const uint2& b)
1526 {
1527  return make_uint2(a.x - b.x, a.y - b.y);
1528 }
1529 OPTIXU_INLINE RT_HOSTDEVICE uint2 operator-(const uint2& a, const unsigned int b)
1530 {
1531  return make_uint2(a.x - b, a.y - b);
1532 }
1533 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(uint2& a, const uint2& b)
1534 {
1535  a.x -= b.x; a.y -= b.y;
1536 }
1542 OPTIXU_INLINE RT_HOSTDEVICE uint2 operator*(const uint2& a, const uint2& b)
1543 {
1544  return make_uint2(a.x * b.x, a.y * b.y);
1545 }
1546 OPTIXU_INLINE RT_HOSTDEVICE uint2 operator*(const uint2& a, const unsigned int s)
1547 {
1548  return make_uint2(a.x * s, a.y * s);
1549 }
1550 OPTIXU_INLINE RT_HOSTDEVICE uint2 operator*(const unsigned int s, const uint2& a)
1551 {
1552  return make_uint2(a.x * s, a.y * s);
1553 }
1554 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(uint2& a, const unsigned int s)
1555 {
1556  a.x *= s; a.y *= s;
1557 }
1563 OPTIXU_INLINE RT_HOSTDEVICE uint2 clamp(const uint2& v, const unsigned int a, const unsigned int b)
1564 {
1565  return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b));
1566 }
1567 
1568 OPTIXU_INLINE RT_HOSTDEVICE uint2 clamp(const uint2& v, const uint2& a, const uint2& b)
1569 {
1570  return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
1571 }
1577 OPTIXU_INLINE RT_HOSTDEVICE bool operator==(const uint2& a, const uint2& b)
1578 {
1579  return a.x == b.x && a.y == b.y;
1580 }
1581 
1582 OPTIXU_INLINE RT_HOSTDEVICE bool operator!=(const uint2& a, const uint2& b)
1583 {
1584  return a.x != b.x || a.y != b.y;
1585 }
1589 OPTIXU_INLINE RT_HOSTDEVICE unsigned int getByIndex(const uint2& v, unsigned int i)
1590 {
1591  return ((unsigned int*)(&v))[i];
1592 }
1593 
1595 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(uint2& v, int i, unsigned int x)
1596 {
1597  ((unsigned int*)(&v))[i] = x;
1598 }
1599 
1600 
1601 /* uint3 functions */
1602 /******************************************************************************/
1603 
1607 OPTIXU_INLINE RT_HOSTDEVICE uint3 make_uint3(const unsigned int s)
1608 {
1609  return make_uint3(s, s, s);
1610 }
1611 OPTIXU_INLINE RT_HOSTDEVICE uint3 make_uint3(const float3& a)
1612 {
1613  return make_uint3((unsigned int)a.x, (unsigned int)a.y, (unsigned int)a.z);
1614 }
1618 OPTIXU_INLINE RT_HOSTDEVICE uint3 min(const uint3& a, const uint3& b)
1619 {
1620  return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
1621 }
1622 
1624 OPTIXU_INLINE RT_HOSTDEVICE uint3 max(const uint3& a, const uint3& b)
1625 {
1626  return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
1627 }
1628 
1632 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator+(const uint3& a, const uint3& b)
1633 {
1634  return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z);
1635 }
1636 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(uint3& a, const uint3& b)
1637 {
1638  a.x += b.x; a.y += b.y; a.z += b.z;
1639 }
1645 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator-(const uint3& a, const uint3& b)
1646 {
1647  return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z);
1648 }
1649 
1650 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(uint3& a, const uint3& b)
1651 {
1652  a.x -= b.x; a.y -= b.y; a.z -= b.z;
1653 }
1659 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator*(const uint3& a, const uint3& b)
1660 {
1661  return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z);
1662 }
1663 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator*(const uint3& a, const unsigned int s)
1664 {
1665  return make_uint3(a.x * s, a.y * s, a.z * s);
1666 }
1667 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator*(const unsigned int s, const uint3& a)
1668 {
1669  return make_uint3(a.x * s, a.y * s, a.z * s);
1670 }
1671 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(uint3& a, const unsigned int s)
1672 {
1673  a.x *= s; a.y *= s; a.z *= s;
1674 }
1680 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator/(const uint3& a, const uint3& b)
1681 {
1682  return make_uint3(a.x / b.x, a.y / b.y, a.z / b.z);
1683 }
1684 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator/(const uint3& a, const unsigned int s)
1685 {
1686  return make_uint3(a.x / s, a.y / s, a.z / s);
1687 }
1688 OPTIXU_INLINE RT_HOSTDEVICE uint3 operator/(const unsigned int s, const uint3& a)
1689 {
1690  return make_uint3(s / a.x, s / a.y, s / a.z);
1691 }
1692 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(uint3& a, const unsigned int s)
1693 {
1694  a.x /= s; a.y /= s; a.z /= s;
1695 }
1701 OPTIXU_INLINE RT_HOSTDEVICE uint3 clamp(const uint3& v, const unsigned int a, const unsigned int b)
1702 {
1703  return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
1704 }
1705 
1706 OPTIXU_INLINE RT_HOSTDEVICE uint3 clamp(const uint3& v, const uint3& a, const uint3& b)
1707 {
1708  return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
1709 }
1715 OPTIXU_INLINE RT_HOSTDEVICE bool operator==(const uint3& a, const uint3& b)
1716 {
1717  return a.x == b.x && a.y == b.y && a.z == b.z;
1718 }
1719 
1720 OPTIXU_INLINE RT_HOSTDEVICE bool operator!=(const uint3& a, const uint3& b)
1721 {
1722  return a.x != b.x || a.y != b.y || a.z != b.z;
1723 }
1728 OPTIXU_INLINE RT_HOSTDEVICE unsigned int getByIndex(const uint3& v, unsigned int i)
1729 {
1730  return ((unsigned int*)(&v))[i];
1731 }
1732 
1735 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(uint3& v, int i, unsigned int x)
1736 {
1737  ((unsigned int*)(&v))[i] = x;
1738 }
1739 
1740 
1741 /* uint4 functions */
1742 /******************************************************************************/
1743 
1747 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const unsigned int s)
1748 {
1749  return make_uint4(s, s, s, s);
1750 }
1751 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const float4& a)
1752 {
1753  return make_uint4((unsigned int)a.x, (unsigned int)a.y, (unsigned int)a.z, (unsigned int)a.w);
1754 }
1760 OPTIXU_INLINE RT_HOSTDEVICE uint4 min(const uint4& a, const uint4& b)
1761 {
1762  return make_uint4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w));
1763 }
1769 OPTIXU_INLINE RT_HOSTDEVICE uint4 max(const uint4& a, const uint4& b)
1770 {
1771  return make_uint4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w));
1772 }
1778 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator+(const uint4& a, const uint4& b)
1779 {
1780  return make_uint4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
1781 }
1782 OPTIXU_INLINE RT_HOSTDEVICE void operator+=(uint4& a, const uint4& b)
1783 {
1784  a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
1785 }
1791 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator-(const uint4& a, const uint4& b)
1792 {
1793  return make_uint4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
1794 }
1795 
1796 OPTIXU_INLINE RT_HOSTDEVICE void operator-=(uint4& a, const uint4& b)
1797 {
1798  a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
1799 }
1805 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator*(const uint4& a, const uint4& b)
1806 {
1807  return make_uint4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
1808 }
1809 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator*(const uint4& a, const unsigned int s)
1810 {
1811  return make_uint4(a.x * s, a.y * s, a.z * s, a.w * s);
1812 }
1813 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator*(const unsigned int s, const uint4& a)
1814 {
1815  return make_uint4(a.x * s, a.y * s, a.z * s, a.w * s);
1816 }
1817 OPTIXU_INLINE RT_HOSTDEVICE void operator*=(uint4& a, const unsigned int s)
1818 {
1819  a.x *= s; a.y *= s; a.z *= s; a.w *= s;
1820 }
1826 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator/(const uint4& a, const uint4& b)
1827 {
1828  return make_uint4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
1829 }
1830 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator/(const uint4& a, const unsigned int s)
1831 {
1832  return make_uint4(a.x / s, a.y / s, a.z / s, a.w / s);
1833 }
1834 OPTIXU_INLINE RT_HOSTDEVICE uint4 operator/(const unsigned int s, const uint4& a)
1835 {
1836  return make_uint4(s / a.x, s / a.y, s / a.z, s / a.w);
1837 }
1838 OPTIXU_INLINE RT_HOSTDEVICE void operator/=(uint4& a, const unsigned int s)
1839 {
1840  a.x /= s; a.y /= s; a.z /= s; a.w /= s;
1841 }
1847 OPTIXU_INLINE RT_HOSTDEVICE uint4 clamp(const uint4& v, const unsigned int a, const unsigned int b)
1848 {
1849  return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
1850 }
1851 
1852 OPTIXU_INLINE RT_HOSTDEVICE uint4 clamp(const uint4& v, const uint4& a, const uint4& b)
1853 {
1854  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));
1855 }
1861 OPTIXU_INLINE RT_HOSTDEVICE bool operator==(const uint4& a, const uint4& b)
1862 {
1863  return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
1864 }
1865 
1866 OPTIXU_INLINE RT_HOSTDEVICE bool operator!=(const uint4& a, const uint4& b)
1867 {
1868  return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
1869 }
1874 OPTIXU_INLINE RT_HOSTDEVICE unsigned int getByIndex(const uint4& v, unsigned int i)
1875 {
1876  return ((unsigned int*)(&v))[i];
1877 }
1878 
1881 OPTIXU_INLINE RT_HOSTDEVICE void setByIndex(uint4& v, int i, unsigned int x)
1882 {
1883  ((unsigned int*)(&v))[i] = x;
1884 }
1885 
1886 
1887 /******************************************************************************/
1888 
1892 OPTIXU_INLINE RT_HOSTDEVICE int2 make_int2(const int3& v0) { return make_int2( v0.x, v0.y ); }
1893 OPTIXU_INLINE RT_HOSTDEVICE int2 make_int2(const int4& v0) { return make_int2( v0.x, v0.y ); }
1894 OPTIXU_INLINE RT_HOSTDEVICE int3 make_int3(const int4& v0) { return make_int3( v0.x, v0.y, v0.z ); }
1895 OPTIXU_INLINE RT_HOSTDEVICE uint2 make_uint2(const uint3& v0) { return make_uint2( v0.x, v0.y ); }
1896 OPTIXU_INLINE RT_HOSTDEVICE uint2 make_uint2(const uint4& v0) { return make_uint2( v0.x, v0.y ); }
1897 OPTIXU_INLINE RT_HOSTDEVICE uint3 make_uint3(const uint4& v0) { return make_uint3( v0.x, v0.y, v0.z ); }
1898 OPTIXU_INLINE RT_HOSTDEVICE float2 make_float2(const float3& v0) { return make_float2( v0.x, v0.y ); }
1899 OPTIXU_INLINE RT_HOSTDEVICE float2 make_float2(const float4& v0) { return make_float2( v0.x, v0.y ); }
1900 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const float4& v0) { return make_float3( v0.x, v0.y, v0.z ); }
1906 OPTIXU_INLINE RT_HOSTDEVICE int3 make_int3(const int v0, const int2& v1) { return make_int3( v0, v1.x, v1.y ); }
1907 OPTIXU_INLINE RT_HOSTDEVICE int3 make_int3(const int2& v0, const int v1) { return make_int3( v0.x, v0.y, v1 ); }
1908 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int v0, const int v1, const int2& v2) { return make_int4( v0, v1, v2.x, v2.y ); }
1909 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int v0, const int2& v1, const int v2) { return make_int4( v0, v1.x, v1.y, v2 ); }
1910 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int2& v0, const int v1, const int v2) { return make_int4( v0.x, v0.y, v1, v2 ); }
1911 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int v0, const int3& v1) { return make_int4( v0, v1.x, v1.y, v1.z ); }
1912 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int3& v0, const int v1) { return make_int4( v0.x, v0.y, v0.z, v1 ); }
1913 OPTIXU_INLINE RT_HOSTDEVICE int4 make_int4(const int2& v0, const int2& v1) { return make_int4( v0.x, v0.y, v1.x, v1.y ); }
1914 OPTIXU_INLINE RT_HOSTDEVICE uint3 make_uint3(const unsigned int v0, const uint2& v1) { return make_uint3( v0, v1.x, v1.y ); }
1915 OPTIXU_INLINE RT_HOSTDEVICE uint3 make_uint3(const uint2& v0, const unsigned int v1) { return make_uint3( v0.x, v0.y, v1 ); }
1916 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const unsigned int v0, const unsigned int v1, const uint2& v2) { return make_uint4( v0, v1, v2.x, v2.y ); }
1917 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const unsigned int v0, const uint2& v1, const unsigned int v2) { return make_uint4( v0, v1.x, v1.y, v2 ); }
1918 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const uint2& v0, const unsigned int v1, const unsigned int v2) { return make_uint4( v0.x, v0.y, v1, v2 ); }
1919 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const unsigned int v0, const uint3& v1) { return make_uint4( v0, v1.x, v1.y, v1.z ); }
1920 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const uint3& v0, const unsigned int v1) { return make_uint4( v0.x, v0.y, v0.z, v1 ); }
1921 OPTIXU_INLINE RT_HOSTDEVICE uint4 make_uint4(const uint2& v0, const uint2& v1) { return make_uint4( v0.x, v0.y, v1.x, v1.y ); }
1922 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const float2& v0, const float v1) { return make_float3(v0.x, v0.y, v1); }
1923 OPTIXU_INLINE RT_HOSTDEVICE float3 make_float3(const float v0, const float2& v1) { return make_float3( v0, v1.x, v1.y ); }
1924 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float v0, const float v1, const float2& v2) { return make_float4( v0, v1, v2.x, v2.y ); }
1925 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float v0, const float2& v1, const float v2) { return make_float4( v0, v1.x, v1.y, v2 ); }
1926 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float2& v0, const float v1, const float v2) { return make_float4( v0.x, v0.y, v1, v2 ); }
1927 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float v0, const float3& v1) { return make_float4( v0, v1.x, v1.y, v1.z ); }
1928 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float3& v0, const float v1) { return make_float4( v0.x, v0.y, v0.z, v1 ); }
1929 OPTIXU_INLINE RT_HOSTDEVICE float4 make_float4(const float2& v0, const float2& v1) { return make_float4( v0.x, v0.y, v1.x, v1.y ); }
1933 /* Common helper functions */
1934 /******************************************************************************/
1935 
1939 OPTIXU_INLINE RT_HOSTDEVICE float smoothstep(const float edge0, const float edge1, const float x)
1940 {
1942  const float t = clamp( (x-edge0) / (edge1-edge0), 0.0f, 1.0f );
1943  return t*t * ( 3.0f - 2.0f*t );
1944 }
1945 
1948 OPTIXU_INLINE RT_HOSTDEVICE float3 temperature(const float t)
1949 {
1950  const float b = t < 0.25f ? smoothstep( -0.25f, 0.25f, t ) : 1.0f-smoothstep( 0.25f, 0.5f, t );
1951  const float g = t < 0.5f ? smoothstep( 0.0f, 0.5f, t ) : (t < 0.75f ? 1.0f : 1.0f-smoothstep( 0.75f, 1.0f, t ));
1952  const float r = smoothstep( 0.5f, 0.75f, t );
1953  return make_float3( r, g, b );
1954 }
1955 
1958 OPTIXU_INLINE RT_HOSTDEVICE bool intersect_triangle_branchless(const Ray& ray,
1959  const float3& p0,
1960  const float3& p1,
1961  const float3& p2,
1962  float3& n,
1963  float& t,
1964  float& beta,
1965  float& gamma)
1966 {
1967  const float3 e0 = p1 - p0;
1968  const float3 e1 = p0 - p2;
1969  n = cross( e1, e0 );
1970 
1971  const float3 e2 = ( 1.0f / dot( n, ray.direction ) ) * ( p0 - ray.origin );
1972  const float3 i = cross( ray.direction, e2 );
1973 
1974  beta = dot( i, e1 );
1975  gamma = dot( i, e0 );
1976  t = dot( n, e2 );
1977 
1978  return ( (t<ray.tmax) & (t>ray.tmin) & (beta>=0.0f) & (gamma>=0.0f) & (beta+gamma<=1) );
1979 }
1980 
1983 OPTIXU_INLINE RT_HOSTDEVICE bool intersect_triangle_earlyexit(const Ray& ray,
1984  const float3& p0,
1985  const float3& p1,
1986  const float3& p2,
1987  float3& n,
1988  float& t,
1989  float& beta,
1990  float& gamma)
1991 {
1992  float3 e0 = p1 - p0;
1993  float3 e1 = p0 - p2;
1994  n = cross( e0, e1 );
1995 
1996  float v = dot( n, ray.direction );
1997  float r = 1.0f / v;
1998 
1999  float3 e2 = p0 - ray.origin;
2000  float va = dot( n, e2 );
2001  t = r*va;
2002 
2003  // Initialize these to reduce their liveness when we leave the function without
2004  // computing their value.
2005  beta = 0;
2006  gamma = 0;
2007 
2008  if(t < ray.tmax && t > ray.tmin) {
2009  float3 i = cross( e2, ray.direction );
2010  float v1 = dot( i, e1 );
2011  beta = r*v1;
2012  if(beta >= 0.0f){
2013  float v2 = dot( i, e0 );
2014  gamma = r*v2;
2015  n = -n;
2016  return ( (v1+v2)*v <= v*v && gamma >= 0.0f );
2017  }
2018  }
2019  return false;
2020 }
2021 
2023 OPTIXU_INLINE RT_HOSTDEVICE bool intersect_triangle(const Ray& ray,
2024  const float3& p0,
2025  const float3& p1,
2026  const float3& p2,
2027  float3& n,
2028  float& t,
2029  float& beta,
2030  float& gamma)
2031 {
2032  return intersect_triangle_branchless(ray, p0, p1, p2, n, t, beta, gamma);
2033 }
2034 
2035 
2045 OPTIXU_INLINE RT_HOSTDEVICE bool refract(float3& r, const float3& i, const float3& n, const float ior)
2046 {
2047  float3 nn = n;
2048  float negNdotV = dot(i,nn);
2049  float eta;
2050 
2051  if (negNdotV > 0.0f)
2052  {
2053  eta = ior;
2054  nn = -n;
2055  negNdotV = -negNdotV;
2056  }
2057  else
2058  {
2059  eta = 1.f / ior;
2060  }
2061 
2062  const float k = 1.f - eta*eta * (1.f - negNdotV * negNdotV);
2063 
2064  if (k < 0.0f) {
2065  // Initialize this value, so that r always leaves this function initialized.
2066  r = make_float3(0.f);
2067  return false;
2068  } else {
2069  r = normalize(eta*i - (eta*negNdotV + sqrtf(k)) * nn);
2070  return true;
2071  }
2072 }
2073 
2076 OPTIXU_INLINE RT_HOSTDEVICE float fresnel_schlick(const float cos_theta, const float exponent = 5.0f,
2077  const float minimum = 0.0f, const float maximum = 1.0f)
2078 {
2089  return clamp(minimum + (maximum - minimum) * powf(fmaxf(0.0f,1.0f - cos_theta), exponent),
2090  minimum, maximum);
2091 }
2092 
2093 OPTIXU_INLINE RT_HOSTDEVICE float3 fresnel_schlick(const float cos_theta, const float exponent,
2094  const float3& minimum, const float3& maximum)
2095 {
2096  return make_float3(fresnel_schlick(cos_theta, exponent, minimum.x, maximum.x),
2097  fresnel_schlick(cos_theta, exponent, minimum.y, maximum.y),
2098  fresnel_schlick(cos_theta, exponent, minimum.z, maximum.z));
2099 }
2100 
2101 
2104 OPTIXU_INLINE RT_HOSTDEVICE float luminance(const float3& rgb)
2105 {
2106  const float3 ntsc_luminance = { 0.30f, 0.59f, 0.11f };
2107  return dot( rgb, ntsc_luminance );
2108 }
2109 
2112 OPTIXU_INLINE RT_HOSTDEVICE float luminanceCIE(const float3& rgb)
2113 {
2114  const float3 cie_luminance = { 0.2126f, 0.7152f, 0.0722f };
2115  return dot( rgb, cie_luminance );
2116 }
2117 
2118 OPTIXU_INLINE RT_HOSTDEVICE void cosine_sample_hemisphere(const float u1, const float u2, float3& p)
2119 {
2120  // Uniformly sample disk.
2121  const float r = sqrtf( u1 );
2122  const float phi = 2.0f*M_PIf * u2;
2123  p.x = r * cosf( phi );
2124  p.y = r * sinf( phi );
2125 
2126  // Project up to hemisphere.
2127  p.z = sqrtf( fmaxf( 0.0f, 1.0f - p.x*p.x - p.y*p.y ) );
2128 }
2129 
2132 OPTIXU_INLINE RT_HOSTDEVICE float2 square_to_disk(const float2& sample)
2133 {
2134  float phi, r;
2135 
2136  const float a = 2.0f * sample.x - 1.0f;
2137  const float b = 2.0f * sample.y - 1.0f;
2138 
2139  if (a > -b)
2140  {
2141  if (a > b)
2142  {
2143  r = a;
2144  phi = (float)M_PI_4f * (b/a);
2145  }
2146  else
2147  {
2148  r = b;
2149  phi = (float)M_PI_4f * (2.0f - (a/b));
2150  }
2151  }
2152  else
2153  {
2154  if (a < b)
2155  {
2156  r = -a;
2157  phi = (float)M_PI_4f * (4.0f + (b/a));
2158  }
2159  else
2160  {
2161  r = -b;
2162  phi = (b) ? (float)M_PI_4f * (6.0f - (a/b)) : 0.0f;
2163  }
2164  }
2165 
2166  return make_float2( r * cosf(phi), r * sinf(phi) );
2167 }
2168 
2172 OPTIXU_INLINE RT_HOSTDEVICE float3 cart_to_pol(const float3& v)
2173 {
2174  float azimuth;
2175  float elevation;
2176  float radius = length(v);
2177 
2178  float r = sqrtf(v.x*v.x + v.y*v.y);
2179  if (r > 0.0f)
2180  {
2181  azimuth = atanf(v.y / v.x);
2182  elevation = atanf(v.z / r);
2183 
2184  if (v.x < 0.0f)
2185  azimuth += M_PIf;
2186  else if (v.y < 0.0f)
2187  azimuth += M_PIf * 2.0f;
2188  }
2189  else
2190  {
2191  azimuth = 0.0f;
2192 
2193  if (v.z > 0.0f)
2194  elevation = +M_PI_2f;
2195  else
2196  elevation = -M_PI_2f;
2197  }
2198 
2199  return make_float3(azimuth, elevation, radius);
2200 }
2201 
2205 struct Onb
2206 {
2207  OPTIXU_INLINE RT_HOSTDEVICE Onb(const float3& normal)
2208  {
2209  m_normal = normal;
2210 
2211  if( fabs(m_normal.x) > fabs(m_normal.z) )
2212  {
2213  m_binormal.x = -m_normal.y;
2214  m_binormal.y = m_normal.x;
2215  m_binormal.z = 0;
2216  }
2217  else
2218  {
2219  m_binormal.x = 0;
2220  m_binormal.y = -m_normal.z;
2221  m_binormal.z = m_normal.y;
2222  }
2223 
2224  m_binormal = normalize(m_binormal);
2225  m_tangent = cross( m_binormal, m_normal );
2226  }
2227 
2228  OPTIXU_INLINE RT_HOSTDEVICE void inverse_transform(float3& p) const
2229  {
2230  p = p.x*m_tangent + p.y*m_binormal + p.z*m_normal;
2231  }
2232 
2233  float3 m_tangent;
2234  float3 m_binormal;
2235  float3 m_normal;
2236 };
2237 
2238 } // end namespace optix
2239 
2240 /*
2241  * When looking for operators for a type, only the scope the type is defined in (plus the
2242  * global scope) is searched. In order to make the operators behave properly we are
2243  * pulling them into the global namespace.
2244  */
2245 #if defined(RT_PULL_IN_VECTOR_TYPES)
2246 using optix::operator-;
2247 using optix::operator-=;
2248 using optix::operator+;
2249 using optix::operator+=;
2250 using optix::operator*;
2251 using optix::operator*=;
2252 using optix::operator/;
2253 using optix::operator/=;
2254 using optix::operator==;
2255 #endif // #if defined(RT_PULL_IN_VECTOR_TYPES)
2256 
2257 /*
2258  * Here are a list of functions that are overloaded in both the global and optix
2259  * namespace. If they have a global namespace version, then the overloads in the optix
2260  * namespace need to be pulled in, so that all the overloads are on the same level.
2261  */
2262 
2263 /* These are defined by CUDA in the global namespace */
2264 #if defined(RT_PULL_IN_VECTOR_FUNCTIONS)
2265 #define RT_DEFINE_HELPER(type) \
2266  using optix::make_##type##1; \
2267  using optix::make_##type##2; \
2268  using optix::make_##type##3; \
2269  using optix::make_##type##4;
2270 
2271 /* Some types didn't exist until CUDA 3.0. CUDA_VERSION isn't defined while
2272  * building CUDA code, so we also need to check the CUDART_VERSION value. */
2273 #if (CUDA_VERSION >= 3000) || (CUDART_VERSION >= 3000)
2274 #define RT_DEFINE_HELPER2(type) RT_DEFINE_HELPER(type)
2275 #else
2276 #define RT_DEFINE_HELPER2(type) \
2277  using ::make_##type##1; \
2278  using ::make_##type##2;
2279 #endif
2280 
2281 
2282 RT_DEFINE_HELPER(char)
2283 RT_DEFINE_HELPER(uchar)
2284 RT_DEFINE_HELPER(short)
2285 RT_DEFINE_HELPER(ushort)
2286 RT_DEFINE_HELPER(int)
2287 RT_DEFINE_HELPER(uint)
2288 RT_DEFINE_HELPER(long)
2289 RT_DEFINE_HELPER(ulong)
2290 RT_DEFINE_HELPER(float)
2291 RT_DEFINE_HELPER2(longlong)
2292 RT_DEFINE_HELPER2(ulonglong)
2293 RT_DEFINE_HELPER2(double)
2294 
2295 #undef RT_DEFINE_HELPER
2296 #undef RT_DEFINE_HELPER2
2297 
2298 #endif // #if defined(RT_PULL_IN_VECTOR_FUNCTIONS)
2299 
2300 /* These are defined by CUDA and non-Windows platforms in the global namespace. */
2301 #if !defined(_WIN32) || defined (__CUDACC__)
2302 using optix::fmaxf;
2303 using optix::fminf;
2304 using optix::copysignf;
2305 #endif
2306 
2307 /* These are always in the global namespace. */
2308 using optix::expf;
2309 using optix::floor;
2310 
2311 #ifdef OPTIXU_INLINE_DEFINED
2312 # undef OPTIXU_INLINE_DEFINED
2313 # undef OPTIXU_INLINE
2314 #endif
2315 
2316 #endif // #ifndef __optixu_optixu_math_namespace_h__
float3 origin
Definition: optix_datatypes.h:139
float tmax
Definition: optix_datatypes.h:147
float tmin
Definition: optix_datatypes.h:145
float3 direction
Definition: optix_datatypes.h:141
Ray class.
Definition: optix_datatypes.h:120
Definition: optixu_math_namespace.h:2205