Material Definition Language API nvidia_logo_transpbg.gif 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 2020 NVIDIA Corporation. All rights reserved.
3  **************************************************************************************************/
8 
9 #ifndef MI_MATH_SPECTRUM_H
10 #define MI_MATH_SPECTRUM_H
11 
12 #include <mi/base/types.h>
13 #include <mi/math/assert.h>
14 #include <mi/math/function.h>
15 #include <mi/math/vector.h>
16 #include <mi/math/color.h>
17 
18 namespace mi {
19 
20 namespace math {
21 
33 //------ Spectrum Class ---------------------------------------------------------
34 
52 class Spectrum : public Spectrum_struct
53 {
54 public:
57  typedef Float32 value_type;
58  typedef Size size_type;
60  typedef Float32 * pointer;
61  typedef const Float32 * const_pointer;
62  typedef Float32 & reference;
63  typedef const Float32 & const_reference;
64 
65  static const Size SIZE = 3;
66 
68  static inline Size size() { return SIZE; }
69 
71  static inline Size max_size() { return SIZE; }
72 
74  inline Float32* begin() { return &c[0]; }
75 
77  inline const Float32* begin() const { return &c[0]; }
78 
82  inline Float32* end() { return begin() + SIZE; }
83 
87  inline const Float32* end() const { return begin() + SIZE; }
88 
90  inline Spectrum()
91  {
92 #if defined(DEBUG) || (defined(_MSC_VER) && _MSC_VER <= 1310)
93  // In debug mode, default-constructed spectra are initialized with signaling NaNs or, if not
94  // applicable, with a maximum value to increase the chances of diagnosing incorrect use of
95  // an uninitialized spectrum.
96  //
97  // When compiling with Visual C++ 7.1 or earlier, this code is enabled in all variants to
98  // work around a very obscure compiler bug that causes the compiler to crash.
99  typedef mi::base::numeric_traits<Float32> Traits;
100  Float32 v = (Traits::has_signaling_NaN)
101  ? Traits::signaling_NaN() : Traits::max MI_PREVENT_MACRO_EXPAND ();
102  for( Size i = 0; i < SIZE; ++i)
103  c[i] = v;
104 #endif
105  }
106 
108  inline Spectrum( const Spectrum_struct& s)
109  {
110  for( Size i = 0; i < SIZE; ++i)
111  c[i] = s.c[i];
112  }
113 
114 
116  inline explicit Spectrum( const Float32 s)
117  {
118  for( Size i = 0; i < SIZE; ++i)
119  c[i] = s;
120  }
121 
123  inline Spectrum( Float32 nr, Float32 ng, Float32 nb)
124  {
125  c[0] = nr;
126  c[1] = ng;
127  c[2] = nb;
128  }
129 
131  inline explicit Spectrum( const Vector<Float32,3>& v3)
132  {
133  c[0] = v3[0];
134  c[1] = v3[1];
135  c[2] = v3[2];
136  }
137 
139  inline explicit Spectrum( const Vector<Float32,4>& v4)
140  {
141  c[0] = v4[0];
142  c[1] = v4[1];
143  c[2] = v4[2];
144  }
145 
147  inline explicit Spectrum( const Color& col)
148  {
149  c[0] = col.r;
150  c[1] = col.g;
151  c[2] = col.b;
152  }
153 
156  {
157  Vector<Float32,3> result;
158  result[0] = c[0];
159  result[1] = c[1];
160  result[2] = c[2];
161  return result;
162  }
163 
166  {
167  Vector<Float32,4> result;
168  result[0] = c[0];
169  result[1] = c[1];
170  result[2] = c[2];
171  result[3] = 1.0;
172  return result;
173  }
174 
176  inline const Float32& operator[]( Size i) const
177  {
178  mi_math_assert_msg( i < SIZE, "precondition");
179  return c[i];
180  }
181 
183  inline Float32& operator[]( Size i)
184  {
185  mi_math_assert_msg( i < SIZE, "precondition");
186  return c[i];
187  }
188 
189 
191  inline Float32 get( Size i) const
192  {
193  mi_math_assert_msg( i < SIZE, "precondition");
194  return c[i];
195  }
196 
198  inline void set( Size i, Float32 value)
199  {
200  mi_math_assert_msg( i < SIZE, "precondition");
201  c[i] = value;
202  }
203 
205  inline bool is_black() const
206  {
207  for( Size i = 0; i < SIZE; ++i)
208  if( c[i] != 0.0f)
209  return false;
210  return true;
211  }
212 
214  inline Float32 linear_intensity() const
215  {
216  Float32 sum = 0.f;
217  for( Size i = 0; i < SIZE; ++i)
218  sum += c[i];
219  return sum / Float32( SIZE);
220  }
221 };
222 
223 //------ Free comparison operators ==, !=, <, <=, >, >= for spectra ------------
224 
226 inline bool operator==( const Spectrum& lhs, const Spectrum& rhs)
227 {
228  return is_equal( lhs, rhs);
229 }
230 
232 inline bool operator!=( const Spectrum& lhs, const Spectrum& rhs)
233 {
234  return is_not_equal( lhs, rhs);
235 }
236 
240 inline bool operator<( const Spectrum& lhs, const Spectrum& rhs)
241 {
242  return lexicographically_less( lhs, rhs);
243 }
244 
248 inline bool operator<=( const Spectrum& lhs, const Spectrum& rhs)
249 {
250  return lexicographically_less_or_equal( lhs, rhs);
251 }
252 
256 inline bool operator>( const Spectrum& lhs, const Spectrum& rhs)
257 {
258  return lexicographically_greater( lhs, rhs);
259 }
260 
264 inline bool operator>=( const Spectrum& lhs, const Spectrum& rhs)
265 {
266  return lexicographically_greater_or_equal( lhs, rhs);
267 }
268 
269 
270 
271 //------ Free operators +=, -=, *=, /=, +, -, *, and / for spectra --------------
272 
274 inline Spectrum& operator+=( Spectrum& lhs, const Spectrum& rhs)
275 {
276  mi_math_assert_msg( lhs.size() == 3, "precondition");
277  mi_math_assert_msg( rhs.size() == 3, "precondition");
278  lhs[0] += rhs[0];
279  lhs[1] += rhs[1];
280  lhs[2] += rhs[2];
281  return lhs;
282 }
283 
285 inline Spectrum& operator-=( Spectrum& lhs, const Spectrum& rhs)
286 {
287  mi_math_assert_msg( lhs.size() == 3, "precondition");
288  mi_math_assert_msg( rhs.size() == 3, "precondition");
289  lhs[0] -= rhs[0];
290  lhs[1] -= rhs[1];
291  lhs[2] -= rhs[2];
292  return lhs;
293 }
294 
296 inline Spectrum& operator*=( Spectrum& lhs, const Spectrum& rhs)
297 {
298  mi_math_assert_msg( lhs.size() == 3, "precondition");
299  mi_math_assert_msg( rhs.size() == 3, "precondition");
300  lhs[0] *= rhs[0];
301  lhs[1] *= rhs[1];
302  lhs[2] *= rhs[2];
303  return lhs;
304 }
305 
307 inline Spectrum& operator/=( Spectrum& lhs, const Spectrum& rhs)
308 {
309  mi_math_assert_msg( lhs.size() == 3, "precondition");
310  mi_math_assert_msg( rhs.size() == 3, "precondition");
311  lhs[0] /= rhs[0];
312  lhs[1] /= rhs[1];
313  lhs[2] /= rhs[2];
314  return lhs;
315 }
316 
318 inline Spectrum operator+( const Spectrum& lhs, const Spectrum& rhs)
319 {
320  mi_math_assert_msg( lhs.size() == 3, "precondition");
321  mi_math_assert_msg( rhs.size() == 3, "precondition");
322  return Spectrum( lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]);
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& c)
351 {
352  mi_math_assert_msg( c.size() == 3, "precondition");
353  return Spectrum( -c[0], -c[1], -c[2]);
354 }
355 
356 
357 
358 //------ Free operator *=, /=, *, and / definitions for scalars ---------------
359 
363 {
364  mi_math_assert_msg( c.size() == 3, "precondition");
365  c[0] *= s;
366  c[1] *= s;
367  c[2] *= s;
368  return c;
369 }
370 
373 {
374  mi_math_assert_msg( c.size() == 3, "precondition");
375  const Float32 f = 1.0f / s;
376  c[0] *= f;
377  c[1] *= f;
378  c[2] *= f;
379  return c;
380 }
381 
383 inline Spectrum operator*( const Spectrum& c, Float32 s)
384 {
385  mi_math_assert_msg( c.size() == 3, "precondition");
386  return Spectrum( c[0] * s, c[1] * s, c[2] * s);
387 }
388 
390 inline Spectrum operator*( Float32 s, const Spectrum& c)
391 {
392  mi_math_assert_msg( c.size() == 3, "precondition");
393  return Spectrum( s * c[0], s * c[1], s* c[2]);
394 }
395 
397 inline Spectrum operator/( const Spectrum& c, Float32 s)
398 {
399  mi_math_assert_msg( c.size() == 3, "precondition");
400  Float32 f = 1.0f / s;
401  return Spectrum( c[0] * f, c[1] * f, c[2] * f);
402 }
403 
404 
405 //------ Function Overloads for Spectrum Algorithms ------------------------------
406 
407 
409 inline Spectrum abs( const Spectrum& c)
410 {
411  mi_math_assert_msg( c.size() == 3, "precondition");
412  return Spectrum( abs( c[0]), abs( c[1]), abs( c[2]));
413 }
414 
416 inline Spectrum acos( const Spectrum& c)
417 {
418  mi_math_assert_msg( c.size() == 3, "precondition");
419  return Spectrum( acos( c[0]), acos( c[1]), acos( c[2]));
420 }
421 
423 inline bool all( const Spectrum& c)
424 {
425  mi_math_assert_msg( c.size() == 3, "precondition");
426  return (c[0] != 0.0f) && (c[1] != 0.0f) && (c[2] != 0.0f);
427 }
428 
430 inline bool any( const Spectrum& c)
431 {
432  mi_math_assert_msg( c.size() == 3, "precondition");
433  return (c[0] != 0.0f) || (c[1] != 0.0f) || (c[2] != 0.0f);
434 }
435 
437 inline Spectrum asin( const Spectrum& c)
438 {
439  mi_math_assert_msg( c.size() == 3, "precondition");
440  return Spectrum( asin( c[0]), asin( c[1]), asin( c[2]));
441 }
442 
444 inline Spectrum atan( const Spectrum& c)
445 {
446  mi_math_assert_msg( c.size() == 3, "precondition");
447  return Spectrum( atan( c[0]), atan( c[1]), atan( c[2]));
448 }
449 
453 inline Spectrum atan2( const Spectrum& c, const Spectrum& d)
454 {
455  mi_math_assert_msg( c.size() == 3 && d.size() == 3, "precondition");
456  return Spectrum( atan2( c[0], d[0]), atan2( c[1], d[1]), atan2( c[2], d[2]));
457 }
458 
461 inline Spectrum ceil( const Spectrum& c)
462 {
463  mi_math_assert_msg( c.size() == 3, "precondition");
464  return Spectrum( ceil( c[0]), ceil( c[1]), ceil( c[2]));
465 }
466 
468 inline Spectrum clamp( const Spectrum& c, const Spectrum& low, const Spectrum& high)
469 {
470  mi_math_assert_msg( c.size() == 3, "precondition");
471  mi_math_assert_msg( low.size() == 3, "precondition");
472  mi_math_assert_msg( high.size() == 3, "precondition");
473  return Spectrum( clamp( c[0], low[0], high[0]),
474  clamp( c[1], low[1], high[1]),
475  clamp( c[2], low[2], high[2]));
476 }
477 
479 inline Spectrum clamp( const Spectrum& c, const Spectrum& low, Float32 high)
480 {
481  mi_math_assert_msg( c.size() == 3, "precondition");
482  mi_math_assert_msg( low.size() == 3, "precondition");
483  return Spectrum( clamp( c[0], low[0], high),
484  clamp( c[1], low[1], high),
485  clamp( c[2], low[2], high));
486 }
487 
489 inline Spectrum clamp( const Spectrum& c, Float32 low, const Spectrum& high)
490 {
491  mi_math_assert_msg( c.size() == 3, "precondition");
492  mi_math_assert_msg( high.size() == 3, "precondition");
493  return Spectrum( clamp( c[0], low, high[0]),
494  clamp( c[1], low, high[1]),
495  clamp( c[2], low, high[2]));
496 }
497 
499 inline Spectrum clamp( const Spectrum& c, Float32 low, Float32 high)
500 {
501  mi_math_assert_msg( c.size() == 3, "precondition");
502  return Spectrum( clamp( c[0], low, high),
503  clamp( c[1], low, high),
504  clamp( c[2], low, high));
505 }
506 
508 inline Spectrum cos( const Spectrum& c)
509 {
510  mi_math_assert_msg( c.size() == 3, "precondition");
511  return Spectrum( cos( c[0]), cos( c[1]), cos( c[2]));
512 }
513 
515 inline Spectrum degrees( const Spectrum& c)
516 {
517  mi_math_assert_msg( c.size() == 3, "precondition");
518  return Spectrum( degrees( c[0]), degrees( c[1]), degrees( c[2]));
519 }
520 
523 inline Spectrum elementwise_max( const Spectrum& lhs, const Spectrum& rhs)
524 {
525  mi_math_assert_msg( lhs.size() == 3, "precondition");
526  mi_math_assert_msg( rhs.size() == 3, "precondition");
527  return Spectrum( base::max MI_PREVENT_MACRO_EXPAND ( lhs[0], rhs[0]),
528  base::max MI_PREVENT_MACRO_EXPAND ( lhs[1], rhs[1]),
529  base::max MI_PREVENT_MACRO_EXPAND ( lhs[2], rhs[2]));
530 }
531 
534 inline Spectrum elementwise_min( const Spectrum& lhs, const Spectrum& rhs)
535 {
536  mi_math_assert_msg( lhs.size() == 3, "precondition");
537  mi_math_assert_msg( rhs.size() == 3, "precondition");
538  return Spectrum( base::min MI_PREVENT_MACRO_EXPAND ( lhs[0], rhs[0]),
539  base::min MI_PREVENT_MACRO_EXPAND ( lhs[1], rhs[1]),
540  base::min MI_PREVENT_MACRO_EXPAND ( lhs[2], rhs[2]));
541 }
542 
544 inline Spectrum exp( const Spectrum& c)
545 {
546  mi_math_assert_msg( c.size() == 3, "precondition");
547  return Spectrum( exp( c[0]), exp( c[1]), exp( c[2]));
548 }
549 
551 inline Spectrum exp2( const Spectrum& c)
552 {
553  mi_math_assert_msg( c.size() == 3, "precondition");
554  return Spectrum( exp2( c[0]), exp2( c[1]), exp2( c[2]));
555 }
556 
559 inline Spectrum floor( const Spectrum& c)
560 {
561  mi_math_assert_msg( c.size() == 3, "precondition");
562  return Spectrum( floor( c[0]), floor( c[1]), floor( c[2]));
563 }
564 
568 inline Spectrum fmod( const Spectrum& a, const Spectrum& b)
569 {
570  mi_math_assert_msg( a.size() == 3, "precondition");
571  mi_math_assert_msg( b.size() == 3, "precondition");
572  return Spectrum( fmod( a[0], b[0]), fmod( a[1], b[1]), fmod( a[2], b[2]));
573 }
574 
578 inline Spectrum fmod( const Spectrum& a, Float32 b)
579 {
580  mi_math_assert_msg( a.size() == 3, "precondition");
581  return Spectrum( fmod( a[0], b), fmod( a[1], b), fmod( a[2], b));
582 }
583 
585 inline Spectrum frac( const Spectrum& c)
586 {
587  mi_math_assert_msg( c.size() == 3, "precondition");
588  return Spectrum( frac( c[0]), frac( c[1]), frac( c[2]));
589 }
590 
599  const Spectrum& spectrum,
600  Float32 gamma_factor)
601 {
602  mi_math_assert_msg( spectrum.size() == 3, "precondition");
603  mi_math_assert( gamma_factor > 0);
604  const Float32 f = Float32(1.0) / gamma_factor;
605  return Spectrum( fast_pow( spectrum[0], f),
606  fast_pow( spectrum[1], f),
607  fast_pow( spectrum[2], f));
608 }
609 
611 inline bool is_approx_equal(
612  const Spectrum& lhs,
613  const Spectrum& rhs,
614  Float32 e)
615 {
616  mi_math_assert_msg( lhs.size() == 3, "precondition");
617  mi_math_assert_msg( rhs.size() == 3, "precondition");
618  return is_approx_equal( lhs[0], rhs[0], e)
619  && is_approx_equal( lhs[1], rhs[1], e)
620  && is_approx_equal( lhs[2], rhs[2], e);
621 }
622 
625 inline Spectrum lerp(
626  const Spectrum& c1,
627  const Spectrum& c2,
628  const Spectrum& t)
629 {
630  mi_math_assert_msg( c1.size() == 3, "precondition");
631  mi_math_assert_msg( c2.size() == 3, "precondition");
632  mi_math_assert_msg( t.size() == 3, "precondition");
633  return Spectrum( lerp( c1[0], c2[0], t[0]),
634  lerp( c1[1], c2[1], t[1]),
635  lerp( c1[2], c2[2], t[2]));
636 }
637 
640 inline Spectrum lerp(
641  const Spectrum& c1,
642  const Spectrum& c2,
643  Float32 t)
644 {
645  mi_math_assert_msg( c1.size() == 3, "precondition");
646  mi_math_assert_msg( c2.size() == 3, "precondition");
647  // equivalent to: return c1 * (Float32(1)-t) + c2 * t;
648  return Spectrum( lerp( c1[0], c2[0], t),
649  lerp( c1[1], c2[1], t),
650  lerp( c1[2], c2[2], t));
651 }
652 
654 inline Spectrum log( const Spectrum& c)
655 {
656  mi_math_assert_msg( c.size() == 3, "precondition");
657  return Spectrum( log( c[0]), log( c[1]), log( c[2]));
658 }
659 
662 {
663  mi_math_assert_msg( c.size() == 3, "precondition");
664  return Spectrum( log2 MI_PREVENT_MACRO_EXPAND (c[0]),
667 }
668 
670 inline Spectrum log10( const Spectrum& c)
671 {
672  mi_math_assert_msg( c.size() == 3, "precondition");
673  return Spectrum( log10( c[0]), log10( c[1]), log10( c[2]));
674 }
675 
680 inline Spectrum modf( const Spectrum& c, Spectrum& i)
681 {
682  mi_math_assert_msg( c.size() == 3, "precondition");
683  mi_math_assert_msg( i.size() == 3, "precondition");
684  return Spectrum( modf( c[0], i[0]), modf( c[1], i[1]), modf( c[2], i[2]));
685 }
686 
688 inline Spectrum pow( const Spectrum& a, const Spectrum& b)
689 {
690  mi_math_assert_msg( a.size() == 3, "precondition");
691  mi_math_assert_msg( b.size() == 3, "precondition");
692  return Spectrum( pow( a[0], b[0]), pow( a[1], b[1]), pow( a[2], b[2]));
693 }
694 
696 inline Spectrum pow( const Spectrum& a, Float32 b)
697 {
698  mi_math_assert_msg( a.size() == 3, "precondition");
699  return Spectrum( pow( a[0], b), pow( a[1], b), pow( a[2], b));
700 }
701 
703 inline Spectrum radians( const Spectrum& c)
704 {
705  mi_math_assert_msg( c.size() == 3, "precondition");
706  return Spectrum( radians( c[0]), radians( c[1]), radians( c[2]));
707 }
708 
710 inline Spectrum round( const Spectrum& c)
711 {
712  mi_math_assert_msg( c.size() == 3, "precondition");
713  return Spectrum( round( c[0]), round( c[1]), round( c[2]));
714 }
715 
717 inline Spectrum rsqrt( const Spectrum& c)
718 {
719  mi_math_assert_msg( c.size() == 3, "precondition");
720  return Spectrum( rsqrt( c[0]), rsqrt( c[1]), rsqrt( c[2]));
721 }
722 
724 inline Spectrum saturate( const Spectrum& c)
725 {
726  mi_math_assert_msg( c.size() == 3, "precondition");
727  return Spectrum( saturate( c[0]), saturate( c[1]), saturate( c[2]));
728 }
729 
731 inline Spectrum sign( const Spectrum& c)
732 {
733  mi_math_assert_msg( c.size() == 3, "precondition");
734  return Spectrum( sign( c[0]), sign( c[1]), sign( c[2]));
735 }
736 
738 inline Spectrum sin( const Spectrum& c)
739 {
740  mi_math_assert_msg( c.size() == 3, "precondition");
741  return Spectrum( sin( c[0]), sin( c[1]), sin( c[2]));
742 }
743 
747 inline void sincos( const Spectrum& a, Spectrum& s, Spectrum& c)
748 {
749  mi_math_assert_msg( a.size() == 3, "precondition");
750  mi_math_assert_msg( s.size() == 3, "precondition");
751  mi_math_assert_msg( c.size() == 3, "precondition");
752  sincos( a[0], s[0], c[0]);
753  sincos( a[1], s[1], c[1]);
754  sincos( a[2], s[2], c[2]);
755 }
756 
762 inline Spectrum smoothstep( const Spectrum& a, const Spectrum& b, const Spectrum& c)
763 {
764  mi_math_assert_msg( a.size() == 3, "precondition");
765  mi_math_assert_msg( b.size() == 3, "precondition");
766  mi_math_assert_msg( c.size() == 3, "precondition");
767  return Spectrum( smoothstep( a[0], b[0], c[0]),
768  smoothstep( a[1], b[1], c[1]),
769  smoothstep( a[2], b[2], c[2]));
770 }
771 
777 inline Spectrum smoothstep( const Spectrum& a, const Spectrum& b, Float32 x)
778 {
779  mi_math_assert_msg( a.size() == 3, "precondition");
780  mi_math_assert_msg( b.size() == 3, "precondition");
781  return Spectrum( smoothstep( a[0], b[0], x),
782  smoothstep( a[1], b[1], x),
783  smoothstep( a[2], b[2], x));
784 }
785 
787 inline Spectrum sqrt( const Spectrum& c)
788 {
789  mi_math_assert_msg( c.size() == 3, "precondition");
790  return Spectrum( sqrt( c[0]), sqrt( c[1]), sqrt( c[2]));
791 }
792 
794 inline Spectrum step( const Spectrum& a, const Spectrum& c)
795 {
796  mi_math_assert_msg( a.size() == 3, "precondition");
797  mi_math_assert_msg( c.size() == 3, "precondition");
798  return Spectrum( step( a[0], c[0]), step( a[1], c[1]), step( a[1], c[2]));
799 }
800 
802 inline Spectrum tan( const Spectrum& c)
803 {
804  mi_math_assert_msg( c.size() == 3, "precondition");
805  return Spectrum( tan( c[0]), tan( c[1]), tan( c[2]));
806 }
807 
810 {
811  mi_math_assert_msg( c.size() == 3, "precondition");
812  return isfinite MI_PREVENT_MACRO_EXPAND (c[0])
815 }
816 
819 {
820  mi_math_assert_msg( c.size() == 3, "precondition");
821  return isinfinite MI_PREVENT_MACRO_EXPAND (c[0])
824 }
825 
827 inline bool isnan MI_PREVENT_MACRO_EXPAND (const Spectrum& c)
828 {
829  mi_math_assert_msg( c.size() == 3, "precondition");
830  return isnan MI_PREVENT_MACRO_EXPAND (c[0])
832  || isnan MI_PREVENT_MACRO_EXPAND (c[2]);
833 }
834 
836 inline void to_rgbe( const Spectrum& c, Uint32& rgbe)
837 {
838  mi_math_assert_msg( c.size() == 3, "precondition");
839  to_rgbe( &c[0], rgbe);
840 }
841 
843 inline void to_rgbe( const Spectrum& c, Uint8 rgbe[4])
844 {
845  mi_math_assert_msg( c.size() == 3, "precondition");
846  to_rgbe( &c[0], rgbe);
847 }
848 
850 inline void from_rgbe( const Uint8 rgbe[4], Spectrum& c)
851 {
852  mi_math_assert_msg( c.size() == 3, "precondition");
853  from_rgbe( rgbe, &c[0]);
854 }
855 
857 inline void from_rgbe( const Uint32 rgbe, Spectrum& c)
858 {
859  mi_math_assert_msg( c.size() == 3, "precondition");
860  from_rgbe( rgbe, &c[0]);
861 }
862  // end group mi_math_spectrum
864 
865 } // namespace math
866 
867 } // namespace mi
868 
869 #endif // MI_MATH_SPECTRUM_H