NVIDIA Iray: Math API Home  Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
spectrum.h
Go to the documentation of this file.
1 //*****************************************************************************
2 // Copyright 1986, 2016 NVIDIA Corporation. All rights reserved.
3 //*****************************************************************************
8 //*****************************************************************************
9 
10 #ifndef MI_MATH_SPECTRUM_H
11 #define MI_MATH_SPECTRUM_H
12 
13 #include <mi/base/types.h>
14 #include <mi/math/assert.h>
15 #include <mi/math/function.h>
16 #include <mi/math/vector.h>
17 #include <mi/math/color.h>
18 
19 namespace mi {
20 
21 namespace math {
22 
34 //------ Spectrum Class ---------------------------------------------------------
35 
53 class Spectrum : public Spectrum_struct
54 {
55 public:
58  typedef Float32 value_type;
59  typedef Size size_type;
61  typedef Float32 * pointer;
62  typedef const Float32 * const_pointer;
63  typedef Float32 & reference;
64  typedef const Float32 & const_reference;
65 
66  static const Size SIZE = 3;
67 
69  static inline Size size() { return SIZE; }
70 
72  static inline Size max_size() { return SIZE; }
73 
75  inline Float32* begin() { return &c[0]; }
76 
78  inline const Float32* begin() const { return &c[0]; }
79 
83  inline Float32* end() { return begin() + SIZE; }
84 
88  inline const Float32* end() const { return begin() + SIZE; }
89 
91  inline Spectrum()
92  {
93 #if defined(DEBUG) || (defined(_MSC_VER) && _MSC_VER <= 1310)
94  // In debug mode, default-constructed spectra are initialized with signaling NaNs or, if not
95  // applicable, with a maximum value to increase the chances of diagnosing incorrect use of
96  // an uninitialized spectrum.
97  //
98  // When compiling with Visual C++ 7.1 or earlier, this code is enabled in all variants to
99  // work around a very obscure compiler bug that causes the compiler to crash.
100  typedef mi::base::numeric_traits<Float32> Traits;
101  Float32 v = (Traits::has_signaling_NaN)
102  ? Traits::signaling_NaN() : Traits::max MI_PREVENT_MACRO_EXPAND ();
103  for( Size i = 0; i < SIZE; ++i)
104  c[i] = v;
105 #endif
106  }
107 
109  inline Spectrum( const Spectrum_struct& s)
110  {
111  for( Size i = 0; i < SIZE; ++i)
112  c[i] = s.c[i];
113  }
114 
115 
117  inline explicit Spectrum( const Float32 s)
118  {
119  for( Size i = 0; i < SIZE; ++i)
120  c[i] = s;
121  }
122 
124  inline Spectrum( Float32 nr, Float32 ng, Float32 nb)
125  {
126  c[0] = nr;
127  c[1] = ng;
128  c[2] = nb;
129  }
130 
132  inline explicit Spectrum( const Vector<Float32,3>& v3)
133  {
134  c[0] = v3[0];
135  c[1] = v3[1];
136  c[2] = v3[2];
137  }
138 
140  inline explicit Spectrum( const Vector<Float32,4>& v4)
141  {
142  c[0] = v4[0];
143  c[1] = v4[1];
144  c[2] = v4[2];
145  }
146 
148  inline explicit Spectrum( const Color& col)
149  {
150  c[0] = col.r;
151  c[1] = col.g;
152  c[2] = col.b;
153  }
154 
157  {
158  Vector<Float32,3> result;
159  result[0] = c[0];
160  result[1] = c[1];
161  result[2] = c[2];
162  return result;
163  }
164 
167  {
168  Vector<Float32,4> result;
169  result[0] = c[0];
170  result[1] = c[1];
171  result[2] = c[2];
172  result[3] = 1.0;
173  return result;
174  }
175 
177  inline Spectrum& operator=( const Spectrum& s)
178  {
179  Spectrum_struct::operator=( s);
180  return *this;
181  }
182 
184  inline const Float32& operator[]( Size i) const
185  {
186  mi_math_assert_msg( i < SIZE, "precondition");
187  return c[i];
188  }
189 
191  inline Float32& operator[]( Size i)
192  {
193  mi_math_assert_msg( i < SIZE, "precondition");
194  return c[i];
195  }
196 
197 
199  inline Float32 get( Size i) const
200  {
201  mi_math_assert_msg( i < SIZE, "precondition");
202  return c[i];
203  }
204 
206  inline void set( Size i, Float32 value)
207  {
208  mi_math_assert_msg( i < SIZE, "precondition");
209  c[i] = value;
210  }
211 
213  inline bool is_black() const
214  {
215  for( Size i = 0; i < SIZE; ++i)
216  if( c[i] != 0.0f)
217  return false;
218  return true;
219  }
220 
222  inline Float32 linear_intensity() const
223  {
224  Float32 sum = 0.f;
225  for( Size i = 0; i < SIZE; ++i)
226  sum += c[i];
227  return sum / Float32( SIZE);
228  }
229 };
230 
231 //------ Free comparison operators ==, !=, <, <=, >, >= for spectra ------------
232 
234 inline bool operator==( const Spectrum& lhs, const Spectrum& rhs)
235 {
236  return is_equal( lhs, rhs);
237 }
238 
240 inline bool operator!=( const Spectrum& lhs, const Spectrum& rhs)
241 {
242  return is_not_equal( lhs, rhs);
243 }
244 
248 inline bool operator<( const Spectrum& lhs, const Spectrum& rhs)
249 {
250  return lexicographically_less( lhs, rhs);
251 }
252 
256 inline bool operator<=( const Spectrum& lhs, const Spectrum& rhs)
257 {
258  return lexicographically_less_or_equal( lhs, rhs);
259 }
260 
264 inline bool operator>( const Spectrum& lhs, const Spectrum& rhs)
265 {
266  return lexicographically_greater( lhs, rhs);
267 }
268 
272 inline bool operator>=( const Spectrum& lhs, const Spectrum& rhs)
273 {
274  return lexicographically_greater_or_equal( lhs, rhs);
275 }
276 
277 
278 
279 //------ Free operators +=, -=, *=, /=, +, -, *, and / for spectra --------------
280 
282 inline Spectrum& operator+=( Spectrum& lhs, const Spectrum& rhs)
283 {
284  mi_math_assert_msg( lhs.size() == 3, "precondition");
285  mi_math_assert_msg( rhs.size() == 3, "precondition");
286  lhs[0] += rhs[0];
287  lhs[1] += rhs[1];
288  lhs[2] += rhs[2];
289  return lhs;
290 }
291 
293 inline Spectrum& operator-=( Spectrum& lhs, const Spectrum& rhs)
294 {
295  mi_math_assert_msg( lhs.size() == 3, "precondition");
296  mi_math_assert_msg( rhs.size() == 3, "precondition");
297  lhs[0] -= rhs[0];
298  lhs[1] -= rhs[1];
299  lhs[2] -= rhs[2];
300  return lhs;
301 }
302 
304 inline Spectrum& operator*=( Spectrum& lhs, const Spectrum& rhs)
305 {
306  mi_math_assert_msg( lhs.size() == 3, "precondition");
307  mi_math_assert_msg( rhs.size() == 3, "precondition");
308  lhs[0] *= rhs[0];
309  lhs[1] *= rhs[1];
310  lhs[2] *= rhs[2];
311  return lhs;
312 }
313 
315 inline Spectrum& operator/=( Spectrum& lhs, const Spectrum& rhs)
316 {
317  mi_math_assert_msg( lhs.size() == 3, "precondition");
318  mi_math_assert_msg( rhs.size() == 3, "precondition");
319  lhs[0] /= rhs[0];
320  lhs[1] /= rhs[1];
321  lhs[2] /= rhs[2];
322  return lhs;
323 }
324 
326 inline Spectrum operator+( const Spectrum& lhs, const Spectrum& rhs)
327 {
328  mi_math_assert_msg( lhs.size() == 3, "precondition");
329  mi_math_assert_msg( rhs.size() == 3, "precondition");
330  return Spectrum( lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]);
331 }
332 
334 inline Spectrum operator-( const Spectrum& lhs, const Spectrum& rhs)
335 {
336  mi_math_assert_msg( lhs.size() == 3, "precondition");
337  mi_math_assert_msg( rhs.size() == 3, "precondition");
338  return Spectrum( lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2]);
339 }
340 
342 inline Spectrum operator*( const Spectrum& lhs, const Spectrum& rhs)
343 {
344  mi_math_assert_msg( lhs.size() == 3, "precondition");
345  mi_math_assert_msg( rhs.size() == 3, "precondition");
346  return Spectrum( lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2]);
347 }
348 
350 inline Spectrum operator/( const Spectrum& lhs, const Spectrum& rhs)
351 {
352  mi_math_assert_msg( lhs.size() == 3, "precondition");
353  mi_math_assert_msg( rhs.size() == 3, "precondition");
354  return Spectrum( lhs[0] / rhs[0], lhs[1] / rhs[1], lhs[2] / rhs[2]);
355 }
356 
358 inline Spectrum operator-( const Spectrum& c)
359 {
360  mi_math_assert_msg( c.size() == 3, "precondition");
361  return Spectrum( -c[0], -c[1], -c[2]);
362 }
363 
364 
365 
366 //------ Free operator *=, /=, *, and / definitions for scalars ---------------
367 
371 {
372  mi_math_assert_msg( c.size() == 3, "precondition");
373  c[0] *= s;
374  c[1] *= s;
375  c[2] *= s;
376  return c;
377 }
378 
381 {
382  mi_math_assert_msg( c.size() == 3, "precondition");
383  const Float32 f = 1.0f / s;
384  c[0] *= f;
385  c[1] *= f;
386  c[2] *= f;
387  return c;
388 }
389 
391 inline Spectrum operator*( const Spectrum& c, Float32 s)
392 {
393  mi_math_assert_msg( c.size() == 3, "precondition");
394  return Spectrum( c[0] * s, c[1] * s, c[2] * s);
395 }
396 
398 inline Spectrum operator*( Float32 s, const Spectrum& c)
399 {
400  mi_math_assert_msg( c.size() == 3, "precondition");
401  return Spectrum( s * c[0], s * c[1], s* c[2]);
402 }
403 
405 inline Spectrum operator/( const Spectrum& c, Float32 s)
406 {
407  mi_math_assert_msg( c.size() == 3, "precondition");
408  Float32 f = 1.0f / s;
409  return Spectrum( c[0] * f, c[1] * f, c[2] * f);
410 }
411 
412 
413 //------ Function Overloads for Spectrum Algorithms ------------------------------
414 
415 
417 inline Spectrum abs( const Spectrum& c)
418 {
419  mi_math_assert_msg( c.size() == 3, "precondition");
420  return Spectrum( abs( c[0]), abs( c[1]), abs( c[2]));
421 }
422 
424 inline Spectrum acos( const Spectrum& c)
425 {
426  mi_math_assert_msg( c.size() == 3, "precondition");
427  return Spectrum( acos( c[0]), acos( c[1]), acos( c[2]));
428 }
429 
431 inline bool all( const Spectrum& c)
432 {
433  mi_math_assert_msg( c.size() == 3, "precondition");
434  return (c[0] != 0.0f) && (c[1] != 0.0f) && (c[2] != 0.0f);
435 }
436 
438 inline bool any( const Spectrum& c)
439 {
440  mi_math_assert_msg( c.size() == 3, "precondition");
441  return (c[0] != 0.0f) || (c[1] != 0.0f) || (c[2] != 0.0f);
442 }
443 
445 inline Spectrum asin( const Spectrum& c)
446 {
447  mi_math_assert_msg( c.size() == 3, "precondition");
448  return Spectrum( asin( c[0]), asin( c[1]), asin( c[2]));
449 }
450 
452 inline Spectrum atan( const Spectrum& c)
453 {
454  mi_math_assert_msg( c.size() == 3, "precondition");
455  return Spectrum( atan( c[0]), atan( c[1]), atan( c[2]));
456 }
457 
461 inline Spectrum atan2( const Spectrum& c, const Spectrum& d)
462 {
463  mi_math_assert_msg( c.size() == 3 && d.size() == 3, "precondition");
464  return Spectrum( atan2( c[0], d[0]), atan2( c[1], d[1]), atan2( c[2], d[2]));
465 }
466 
469 inline Spectrum ceil( const Spectrum& c)
470 {
471  mi_math_assert_msg( c.size() == 3, "precondition");
472  return Spectrum( ceil( c[0]), ceil( c[1]), ceil( c[2]));
473 }
474 
476 inline Spectrum clamp( const Spectrum& c, const Spectrum& low, const Spectrum& high)
477 {
478  mi_math_assert_msg( c.size() == 3, "precondition");
479  mi_math_assert_msg( low.size() == 3, "precondition");
480  mi_math_assert_msg( high.size() == 3, "precondition");
481  return Spectrum( clamp( c[0], low[0], high[0]),
482  clamp( c[1], low[1], high[1]),
483  clamp( c[2], low[2], high[2]));
484 }
485 
487 inline Spectrum clamp( const Spectrum& c, const Spectrum& low, Float32 high)
488 {
489  mi_math_assert_msg( c.size() == 3, "precondition");
490  mi_math_assert_msg( low.size() == 3, "precondition");
491  return Spectrum( clamp( c[0], low[0], high),
492  clamp( c[1], low[1], high),
493  clamp( c[2], low[2], high));
494 }
495 
497 inline Spectrum clamp( const Spectrum& c, Float32 low, const Spectrum& high)
498 {
499  mi_math_assert_msg( c.size() == 3, "precondition");
500  mi_math_assert_msg( high.size() == 3, "precondition");
501  return Spectrum( clamp( c[0], low, high[0]),
502  clamp( c[1], low, high[1]),
503  clamp( c[2], low, high[2]));
504 }
505 
507 inline Spectrum clamp( const Spectrum& c, Float32 low, Float32 high)
508 {
509  mi_math_assert_msg( c.size() == 3, "precondition");
510  return Spectrum( clamp( c[0], low, high),
511  clamp( c[1], low, high),
512  clamp( c[2], low, high));
513 }
514 
516 inline Spectrum cos( const Spectrum& c)
517 {
518  mi_math_assert_msg( c.size() == 3, "precondition");
519  return Spectrum( cos( c[0]), cos( c[1]), cos( c[2]));
520 }
521 
523 inline Spectrum degrees( const Spectrum& c)
524 {
525  mi_math_assert_msg( c.size() == 3, "precondition");
526  return Spectrum( degrees( c[0]), degrees( c[1]), degrees( c[2]));
527 }
528 
531 inline Spectrum elementwise_max( const Spectrum& lhs, const Spectrum& rhs)
532 {
533  mi_math_assert_msg( lhs.size() == 3, "precondition");
534  mi_math_assert_msg( rhs.size() == 3, "precondition");
535  return Spectrum( base::max MI_PREVENT_MACRO_EXPAND ( lhs[0], rhs[0]),
536  base::max MI_PREVENT_MACRO_EXPAND ( lhs[1], rhs[1]),
537  base::max MI_PREVENT_MACRO_EXPAND ( lhs[2], rhs[2]));
538 }
539 
542 inline Spectrum elementwise_min( const Spectrum& lhs, const Spectrum& rhs)
543 {
544  mi_math_assert_msg( lhs.size() == 3, "precondition");
545  mi_math_assert_msg( rhs.size() == 3, "precondition");
546  return Spectrum( base::min MI_PREVENT_MACRO_EXPAND ( lhs[0], rhs[0]),
547  base::min MI_PREVENT_MACRO_EXPAND ( lhs[1], rhs[1]),
548  base::min MI_PREVENT_MACRO_EXPAND ( lhs[2], rhs[2]));
549 }
550 
552 inline Spectrum exp( const Spectrum& c)
553 {
554  mi_math_assert_msg( c.size() == 3, "precondition");
555  return Spectrum( exp( c[0]), exp( c[1]), exp( c[2]));
556 }
557 
559 inline Spectrum exp2( const Spectrum& c)
560 {
561  mi_math_assert_msg( c.size() == 3, "precondition");
562  return Spectrum( exp2( c[0]), exp2( c[1]), exp2( c[2]));
563 }
564 
567 inline Spectrum floor( const Spectrum& c)
568 {
569  mi_math_assert_msg( c.size() == 3, "precondition");
570  return Spectrum( floor( c[0]), floor( c[1]), floor( c[2]));
571 }
572 
576 inline Spectrum fmod( const Spectrum& a, const Spectrum& b)
577 {
578  mi_math_assert_msg( a.size() == 3, "precondition");
579  mi_math_assert_msg( b.size() == 3, "precondition");
580  return Spectrum( fmod( a[0], b[0]), fmod( a[1], b[1]), fmod( a[2], b[2]));
581 }
582 
586 inline Spectrum fmod( const Spectrum& a, Float32 b)
587 {
588  mi_math_assert_msg( a.size() == 3, "precondition");
589  return Spectrum( fmod( a[0], b), fmod( a[1], b), fmod( a[2], b));
590 }
591 
593 inline Spectrum frac( const Spectrum& c)
594 {
595  mi_math_assert_msg( c.size() == 3, "precondition");
596  return Spectrum( frac( c[0]), frac( c[1]), frac( c[2]));
597 }
598 
607  const Spectrum& spectrum,
608  Float32 gamma_factor)
609 {
610  mi_math_assert_msg( spectrum.size() == 3, "precondition");
611  mi_math_assert( gamma_factor > 0);
612  const Float32 f = Float32(1.0) / gamma_factor;
613  return Spectrum( fast_pow( spectrum[0], f),
614  fast_pow( spectrum[1], f),
615  fast_pow( spectrum[2], f));
616 }
617 
619 inline bool is_approx_equal(
620  const Spectrum& lhs,
621  const Spectrum& rhs,
622  Float32 e)
623 {
624  mi_math_assert_msg( lhs.size() == 3, "precondition");
625  mi_math_assert_msg( rhs.size() == 3, "precondition");
626  return is_approx_equal( lhs[0], rhs[0], e)
627  && is_approx_equal( lhs[1], rhs[1], e)
628  && is_approx_equal( lhs[2], rhs[2], e);
629 }
630 
633 inline Spectrum lerp(
634  const Spectrum& c1,
635  const Spectrum& c2,
636  const Spectrum& t)
637 {
638  mi_math_assert_msg( c1.size() == 3, "precondition");
639  mi_math_assert_msg( c2.size() == 3, "precondition");
640  mi_math_assert_msg( t.size() == 3, "precondition");
641  return Spectrum( lerp( c1[0], c2[0], t[0]),
642  lerp( c1[1], c2[1], t[1]),
643  lerp( c1[2], c2[2], t[2]));
644 }
645 
648 inline Spectrum lerp(
649  const Spectrum& c1,
650  const Spectrum& c2,
651  Float32 t)
652 {
653  mi_math_assert_msg( c1.size() == 3, "precondition");
654  mi_math_assert_msg( c2.size() == 3, "precondition");
655  // equivalent to: return c1 * (Float32(1)-t) + c2 * t;
656  return Spectrum( lerp( c1[0], c2[0], t),
657  lerp( c1[1], c2[1], t),
658  lerp( c1[2], c2[2], t));
659 }
660 
662 inline Spectrum log( const Spectrum& c)
663 {
664  mi_math_assert_msg( c.size() == 3, "precondition");
665  return Spectrum( log( c[0]), log( c[1]), log( c[2]));
666 }
667 
670 {
671  mi_math_assert_msg( c.size() == 3, "precondition");
672  return Spectrum( log2 MI_PREVENT_MACRO_EXPAND (c[0]),
675 }
676 
678 inline Spectrum log10( const Spectrum& c)
679 {
680  mi_math_assert_msg( c.size() == 3, "precondition");
681  return Spectrum( log10( c[0]), log10( c[1]), log10( c[2]));
682 }
683 
688 inline Spectrum modf( const Spectrum& c, Spectrum& i)
689 {
690  mi_math_assert_msg( c.size() == 3, "precondition");
691  mi_math_assert_msg( i.size() == 3, "precondition");
692  return Spectrum( modf( c[0], i[0]), modf( c[1], i[1]), modf( c[2], i[2]));
693 }
694 
696 inline Spectrum pow( const Spectrum& a, const Spectrum& b)
697 {
698  mi_math_assert_msg( a.size() == 3, "precondition");
699  mi_math_assert_msg( b.size() == 3, "precondition");
700  return Spectrum( pow( a[0], b[0]), pow( a[1], b[1]), pow( a[2], b[2]));
701 }
702 
704 inline Spectrum pow( const Spectrum& a, Float32 b)
705 {
706  mi_math_assert_msg( a.size() == 3, "precondition");
707  return Spectrum( pow( a[0], b), pow( a[1], b), pow( a[2], b));
708 }
709 
711 inline Spectrum radians( const Spectrum& c)
712 {
713  mi_math_assert_msg( c.size() == 3, "precondition");
714  return Spectrum( radians( c[0]), radians( c[1]), radians( c[2]));
715 }
716 
718 inline Spectrum round( const Spectrum& c)
719 {
720  mi_math_assert_msg( c.size() == 3, "precondition");
721  return Spectrum( round( c[0]), round( c[1]), round( c[2]));
722 }
723 
725 inline Spectrum rsqrt( const Spectrum& c)
726 {
727  mi_math_assert_msg( c.size() == 3, "precondition");
728  return Spectrum( rsqrt( c[0]), rsqrt( c[1]), rsqrt( c[2]));
729 }
730 
732 inline Spectrum saturate( const Spectrum& c)
733 {
734  mi_math_assert_msg( c.size() == 3, "precondition");
735  return Spectrum( saturate( c[0]), saturate( c[1]), saturate( c[2]));
736 }
737 
739 inline Spectrum sign( const Spectrum& c)
740 {
741  mi_math_assert_msg( c.size() == 3, "precondition");
742  return Spectrum( sign( c[0]), sign( c[1]), sign( c[2]));
743 }
744 
746 inline Spectrum sin( const Spectrum& c)
747 {
748  mi_math_assert_msg( c.size() == 3, "precondition");
749  return Spectrum( sin( c[0]), sin( c[1]), sin( c[2]));
750 }
751 
755 inline void sincos( const Spectrum& a, Spectrum& s, Spectrum& c)
756 {
757  mi_math_assert_msg( a.size() == 3, "precondition");
758  mi_math_assert_msg( s.size() == 3, "precondition");
759  mi_math_assert_msg( c.size() == 3, "precondition");
760  sincos( a[0], s[0], c[0]);
761  sincos( a[1], s[1], c[1]);
762  sincos( a[2], s[2], c[2]);
763 }
764 
770 inline Spectrum smoothstep( const Spectrum& a, const Spectrum& b, const Spectrum& c)
771 {
772  mi_math_assert_msg( a.size() == 3, "precondition");
773  mi_math_assert_msg( b.size() == 3, "precondition");
774  mi_math_assert_msg( c.size() == 3, "precondition");
775  return Spectrum( smoothstep( a[0], b[0], c[0]),
776  smoothstep( a[1], b[1], c[1]),
777  smoothstep( a[2], b[2], c[2]));
778 }
779 
785 inline Spectrum smoothstep( const Spectrum& a, const Spectrum& b, Float32 x)
786 {
787  mi_math_assert_msg( a.size() == 3, "precondition");
788  mi_math_assert_msg( b.size() == 3, "precondition");
789  return Spectrum( smoothstep( a[0], b[0], x),
790  smoothstep( a[1], b[1], x),
791  smoothstep( a[2], b[2], x));
792 }
793 
795 inline Spectrum sqrt( const Spectrum& c)
796 {
797  mi_math_assert_msg( c.size() == 3, "precondition");
798  return Spectrum( sqrt( c[0]), sqrt( c[1]), sqrt( c[2]));
799 }
800 
802 inline Spectrum step( const Spectrum& a, const Spectrum& c)
803 {
804  mi_math_assert_msg( a.size() == 3, "precondition");
805  mi_math_assert_msg( c.size() == 3, "precondition");
806  return Spectrum( step( a[0], c[0]), step( a[1], c[1]), step( a[1], c[2]));
807 }
808 
810 inline Spectrum tan( const Spectrum& c)
811 {
812  mi_math_assert_msg( c.size() == 3, "precondition");
813  return Spectrum( tan( c[0]), tan( c[1]), tan( c[2]));
814 }
815 
818 {
819  mi_math_assert_msg( c.size() == 3, "precondition");
820  return isfinite MI_PREVENT_MACRO_EXPAND (c[0])
823 }
824 
827 {
828  mi_math_assert_msg( c.size() == 3, "precondition");
829  return isinfinite MI_PREVENT_MACRO_EXPAND (c[0])
832 }
833 
835 inline bool isnan MI_PREVENT_MACRO_EXPAND (const Spectrum& c)
836 {
837  mi_math_assert_msg( c.size() == 3, "precondition");
838  return isnan MI_PREVENT_MACRO_EXPAND (c[0])
840  || isnan MI_PREVENT_MACRO_EXPAND (c[2]);
841 }
842 
844 inline void to_rgbe( const Spectrum& c, Uint32& rgbe)
845 {
846  mi_math_assert_msg( c.size() == 3, "precondition");
847  to_rgbe( &c[0], rgbe);
848 }
849 
851 inline void to_rgbe( const Spectrum& c, Uint8 rgbe[4])
852 {
853  mi_math_assert_msg( c.size() == 3, "precondition");
854  to_rgbe( &c[0], rgbe);
855 }
856 
858 inline void from_rgbe( const Uint8 rgbe[4], Spectrum& c)
859 {
860  mi_math_assert_msg( c.size() == 3, "precondition");
861  from_rgbe( rgbe, &c[0]);
862 }
863 
865 inline void from_rgbe( const Uint32 rgbe, Spectrum& c)
866 {
867  mi_math_assert_msg( c.size() == 3, "precondition");
868  from_rgbe( rgbe, &c[0]);
869 }
870  // end group mi_math_spectrum
872 
873 } // namespace math
874 
875 } // namespace mi
876 
877 #endif // MI_MATH_SPECTRUM_H