NVIDIA Iray API
 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, 2014 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 (lhs[0] == rhs[0]) && (lhs[1] == rhs[1]) && (lhs[2] == rhs[2]);
237 }
238 
240 inline bool operator!=( const Spectrum& lhs, const Spectrum& rhs)
241 {
242  return (lhs[0] != rhs[0]) || (lhs[1] != rhs[1]) || (lhs[2] != rhs[2]);
243 }
244 
248 inline bool operator<( const Spectrum& lhs, const Spectrum& rhs)
249 {
250  if( lhs[0] != rhs[0])
251  return lhs[0] < rhs[0];
252  if( lhs[1] != rhs[1])
253  return lhs[1] < rhs[1];
254  return lhs[2] < rhs[2];
255 }
256 
260 inline bool operator<=( const Spectrum& lhs, const Spectrum& rhs)
261 {
262  return ! (rhs < lhs);
263 }
264 
268 inline bool operator>( const Spectrum& lhs, const Spectrum& rhs)
269 {
270  return rhs < lhs;
271 }
272 
276 inline bool operator>=( const Spectrum& lhs, const Spectrum& rhs)
277 {
278  return ! (lhs < rhs);
279 }
280 
281 
282 
283 //------ Free operators +=, -=, *=, /=, +, -, *, and / for spectra --------------
284 
286 inline Spectrum& operator+=( Spectrum& lhs, const Spectrum& rhs)
287 {
288  mi_math_assert_msg( lhs.size() == 3, "precondition");
289  mi_math_assert_msg( rhs.size() == 3, "precondition");
290  lhs[0] += rhs[0];
291  lhs[1] += rhs[1];
292  lhs[2] += rhs[2];
293  return lhs;
294 }
295 
297 inline Spectrum& operator-=( Spectrum& lhs, const Spectrum& rhs)
298 {
299  mi_math_assert_msg( lhs.size() == 3, "precondition");
300  mi_math_assert_msg( rhs.size() == 3, "precondition");
301  lhs[0] -= rhs[0];
302  lhs[1] -= rhs[1];
303  lhs[2] -= rhs[2];
304  return lhs;
305 }
306 
308 inline Spectrum& operator*=( Spectrum& lhs, const Spectrum& rhs)
309 {
310  mi_math_assert_msg( lhs.size() == 3, "precondition");
311  mi_math_assert_msg( rhs.size() == 3, "precondition");
312  lhs[0] *= rhs[0];
313  lhs[1] *= rhs[1];
314  lhs[2] *= rhs[2];
315  return lhs;
316 }
317 
319 inline Spectrum& operator/=( Spectrum& lhs, const Spectrum& rhs)
320 {
321  mi_math_assert_msg( lhs.size() == 3, "precondition");
322  mi_math_assert_msg( rhs.size() == 3, "precondition");
323  lhs[0] /= rhs[0];
324  lhs[1] /= rhs[1];
325  lhs[2] /= rhs[2];
326  return lhs;
327 }
328 
330 inline Spectrum operator+( const Spectrum& lhs, const Spectrum& rhs)
331 {
332  mi_math_assert_msg( lhs.size() == 3, "precondition");
333  mi_math_assert_msg( rhs.size() == 3, "precondition");
334  return Spectrum( lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]);
335 }
336 
338 inline Spectrum operator-( const Spectrum& lhs, const Spectrum& rhs)
339 {
340  mi_math_assert_msg( lhs.size() == 3, "precondition");
341  mi_math_assert_msg( rhs.size() == 3, "precondition");
342  return Spectrum( lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2]);
343 }
344 
346 inline Spectrum operator*( const Spectrum& lhs, const Spectrum& rhs)
347 {
348  mi_math_assert_msg( lhs.size() == 3, "precondition");
349  mi_math_assert_msg( rhs.size() == 3, "precondition");
350  return Spectrum( lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2]);
351 }
352 
354 inline Spectrum operator/( const Spectrum& lhs, const Spectrum& rhs)
355 {
356  mi_math_assert_msg( lhs.size() == 3, "precondition");
357  mi_math_assert_msg( rhs.size() == 3, "precondition");
358  return Spectrum( lhs[0] / rhs[0], lhs[1] / rhs[1], lhs[2] / rhs[2]);
359 }
360 
362 inline Spectrum operator-( const Spectrum& c)
363 {
364  mi_math_assert_msg( c.size() == 3, "precondition");
365  return Spectrum( -c[0], -c[1], -c[2]);
366 }
367 
368 
369 
370 //------ Free operator *=, /=, *, and / definitions for scalars ---------------
371 
375 {
376  mi_math_assert_msg( c.size() == 3, "precondition");
377  c[0] *= s;
378  c[1] *= s;
379  c[2] *= s;
380  return c;
381 }
382 
385 {
386  mi_math_assert_msg( c.size() == 3, "precondition");
387  const Float32 f = 1.0f / s;
388  c[0] *= f;
389  c[1] *= f;
390  c[2] *= f;
391  return c;
392 }
393 
395 inline Spectrum operator*( const Spectrum& c, Float32 s)
396 {
397  mi_math_assert_msg( c.size() == 3, "precondition");
398  return Spectrum( c[0] * s, c[1] * s, c[2] * s);
399 }
400 
402 inline Spectrum operator*( Float32 s, const Spectrum& c)
403 {
404  mi_math_assert_msg( c.size() == 3, "precondition");
405  return Spectrum( s * c[0], s * c[1], s* c[2]);
406 }
407 
409 inline Spectrum operator/( const Spectrum& c, Float32 s)
410 {
411  mi_math_assert_msg( c.size() == 3, "precondition");
412  Float32 f = 1.0f / s;
413  return Spectrum( c[0] * f, c[1] * f, c[2] * f);
414 }
415 
416 
417 //------ Function Overloads for Spectrum Algorithms ------------------------------
418 
419 
421 inline Spectrum abs( const Spectrum& c)
422 {
423  mi_math_assert_msg( c.size() == 3, "precondition");
424  return Spectrum( abs( c[0]), abs( c[1]), abs( c[2]));
425 }
426 
428 inline Spectrum acos( const Spectrum& c)
429 {
430  mi_math_assert_msg( c.size() == 3, "precondition");
431  return Spectrum( acos( c[0]), acos( c[1]), acos( c[2]));
432 }
433 
435 inline bool all( const Spectrum& c)
436 {
437  mi_math_assert_msg( c.size() == 3, "precondition");
438  return (c[0] != 0.0f) && (c[1] != 0.0f) && (c[2] != 0.0f);
439 }
440 
442 inline bool any( const Spectrum& c)
443 {
444  mi_math_assert_msg( c.size() == 3, "precondition");
445  return (c[0] != 0.0f) || (c[1] != 0.0f) || (c[2] != 0.0f);
446 }
447 
449 inline Spectrum asin( const Spectrum& c)
450 {
451  mi_math_assert_msg( c.size() == 3, "precondition");
452  return Spectrum( asin( c[0]), asin( c[1]), asin( c[2]));
453 }
454 
456 inline Spectrum atan( const Spectrum& c)
457 {
458  mi_math_assert_msg( c.size() == 3, "precondition");
459  return Spectrum( atan( c[0]), atan( c[1]), atan( c[2]));
460 }
461 
465 inline Spectrum atan2( const Spectrum& c, const Spectrum& d)
466 {
467  mi_math_assert_msg( c.size() == 3 && d.size() == 3, "precondition");
468  return Spectrum( atan2( c[0], d[0]), atan2( c[1], d[1]), atan2( c[2], d[2]));
469 }
470 
473 inline Spectrum ceil( const Spectrum& c)
474 {
475  mi_math_assert_msg( c.size() == 3, "precondition");
476  return Spectrum( ceil( c[0]), ceil( c[1]), ceil( c[2]));
477 }
478 
480 inline Spectrum clamp( const Spectrum& c, const Spectrum& low, const Spectrum& high)
481 {
482  mi_math_assert_msg( c.size() == 3, "precondition");
483  mi_math_assert_msg( low.size() == 3, "precondition");
484  mi_math_assert_msg( high.size() == 3, "precondition");
485  return Spectrum( clamp( c[0], low[0], high[0]),
486  clamp( c[1], low[1], high[1]),
487  clamp( c[2], low[2], high[2]));
488 }
489 
491 inline Spectrum clamp( const Spectrum& c, const Spectrum& low, Float32 high)
492 {
493  mi_math_assert_msg( c.size() == 3, "precondition");
494  mi_math_assert_msg( low.size() == 3, "precondition");
495  return Spectrum( clamp( c[0], low[0], high),
496  clamp( c[1], low[1], high),
497  clamp( c[2], low[2], high));
498 }
499 
501 inline Spectrum clamp( const Spectrum& c, Float32 low, const Spectrum& high)
502 {
503  mi_math_assert_msg( c.size() == 3, "precondition");
504  mi_math_assert_msg( high.size() == 3, "precondition");
505  return Spectrum( clamp( c[0], low, high[0]),
506  clamp( c[1], low, high[1]),
507  clamp( c[2], low, high[2]));
508 }
509 
511 inline Spectrum clamp( const Spectrum& c, Float32 low, Float32 high)
512 {
513  mi_math_assert_msg( c.size() == 3, "precondition");
514  return Spectrum( clamp( c[0], low, high),
515  clamp( c[1], low, high),
516  clamp( c[2], low, high));
517 }
518 
520 inline Spectrum cos( const Spectrum& c)
521 {
522  mi_math_assert_msg( c.size() == 3, "precondition");
523  return Spectrum( cos( c[0]), cos( c[1]), cos( c[2]));
524 }
525 
527 inline Spectrum degrees( const Spectrum& c)
528 {
529  mi_math_assert_msg( c.size() == 3, "precondition");
530  return Spectrum( degrees( c[0]), degrees( c[1]), degrees( c[2]));
531 }
532 
535 inline Spectrum elementwise_max( const Spectrum& lhs, const Spectrum& rhs)
536 {
537  mi_math_assert_msg( lhs.size() == 3, "precondition");
538  mi_math_assert_msg( rhs.size() == 3, "precondition");
539  return Spectrum( base::max MI_PREVENT_MACRO_EXPAND ( lhs[0], rhs[0]),
540  base::max MI_PREVENT_MACRO_EXPAND ( lhs[1], rhs[1]),
541  base::max MI_PREVENT_MACRO_EXPAND ( lhs[2], rhs[2]));
542 }
543 
546 inline Spectrum elementwise_min( const Spectrum& lhs, const Spectrum& rhs)
547 {
548  mi_math_assert_msg( lhs.size() == 3, "precondition");
549  mi_math_assert_msg( rhs.size() == 3, "precondition");
550  return Spectrum( base::min MI_PREVENT_MACRO_EXPAND ( lhs[0], rhs[0]),
551  base::min MI_PREVENT_MACRO_EXPAND ( lhs[1], rhs[1]),
552  base::min MI_PREVENT_MACRO_EXPAND ( lhs[2], rhs[2]));
553 }
554 
556 inline Spectrum exp( const Spectrum& c)
557 {
558  mi_math_assert_msg( c.size() == 3, "precondition");
559  return Spectrum( exp( c[0]), exp( c[1]), exp( c[2]));
560 }
561 
563 inline Spectrum exp2( const Spectrum& c)
564 {
565  mi_math_assert_msg( c.size() == 3, "precondition");
566  return Spectrum( exp2( c[0]), exp2( c[1]), exp2( c[2]));
567 }
568 
571 inline Spectrum floor( const Spectrum& c)
572 {
573  mi_math_assert_msg( c.size() == 3, "precondition");
574  return Spectrum( floor( c[0]), floor( c[1]), floor( c[2]));
575 }
576 
580 inline Spectrum fmod( const Spectrum& a, const Spectrum& b)
581 {
582  mi_math_assert_msg( a.size() == 3, "precondition");
583  mi_math_assert_msg( b.size() == 3, "precondition");
584  return Spectrum( fmod( a[0], b[0]), fmod( a[1], b[1]), fmod( a[2], b[2]));
585 }
586 
590 inline Spectrum fmod( const Spectrum& a, Float32 b)
591 {
592  mi_math_assert_msg( a.size() == 3, "precondition");
593  return Spectrum( fmod( a[0], b), fmod( a[1], b), fmod( a[2], b));
594 }
595 
597 inline Spectrum frac( const Spectrum& c)
598 {
599  mi_math_assert_msg( c.size() == 3, "precondition");
600  return Spectrum( frac( c[0]), frac( c[1]), frac( c[2]));
601 }
602 
611  const Spectrum& spectrum,
612  Float32 gamma_factor)
613 {
614  mi_math_assert_msg( spectrum.size() == 3, "precondition");
615  mi_math_assert( gamma_factor > 0);
616  const Float32 f = Float32(1.0) / gamma_factor;
617  return Spectrum( fast_pow( spectrum[0], f),
618  fast_pow( spectrum[1], f),
619  fast_pow( spectrum[2], f));
620 }
621 
623 inline bool is_approx_equal(
624  const Spectrum& lhs,
625  const Spectrum& rhs,
626  Float32 e)
627 {
628  mi_math_assert_msg( lhs.size() == 3, "precondition");
629  mi_math_assert_msg( rhs.size() == 3, "precondition");
630  return is_approx_equal( lhs[0], rhs[0], e)
631  && is_approx_equal( lhs[1], rhs[1], e)
632  && is_approx_equal( lhs[2], rhs[2], e);
633 }
634 
637 inline Spectrum lerp(
638  const Spectrum& c1,
639  const Spectrum& c2,
640  const Spectrum& t)
641 {
642  mi_math_assert_msg( c1.size() == 3, "precondition");
643  mi_math_assert_msg( c2.size() == 3, "precondition");
644  mi_math_assert_msg( t.size() == 3, "precondition");
645  return Spectrum( lerp( c1[0], c2[0], t[0]),
646  lerp( c1[1], c2[1], t[1]),
647  lerp( c1[2], c2[2], t[2]));
648 }
649 
652 inline Spectrum lerp(
653  const Spectrum& c1,
654  const Spectrum& c2,
655  Float32 t)
656 {
657  mi_math_assert_msg( c1.size() == 3, "precondition");
658  mi_math_assert_msg( c2.size() == 3, "precondition");
659  // equivalent to: return c1 * (Float32(1)-t) + c2 * t;
660  return Spectrum( lerp( c1[0], c2[0], t),
661  lerp( c1[1], c2[1], t),
662  lerp( c1[2], c2[2], t));
663 }
664 
666 inline Spectrum log( const Spectrum& c)
667 {
668  mi_math_assert_msg( c.size() == 3, "precondition");
669  return Spectrum( log( c[0]), log( c[1]), log( c[2]));
670 }
671 
674 {
675  mi_math_assert_msg( c.size() == 3, "precondition");
676  return Spectrum( log2 MI_PREVENT_MACRO_EXPAND (c[0]),
679 }
680 
682 inline Spectrum log10( const Spectrum& c)
683 {
684  mi_math_assert_msg( c.size() == 3, "precondition");
685  return Spectrum( log10( c[0]), log10( c[1]), log10( c[2]));
686 }
687 
692 inline Spectrum modf( const Spectrum& c, Spectrum& i)
693 {
694  mi_math_assert_msg( c.size() == 3, "precondition");
695  mi_math_assert_msg( i.size() == 3, "precondition");
696  return Spectrum( modf( c[0], i[0]), modf( c[1], i[1]), modf( c[2], i[2]));
697 }
698 
700 inline Spectrum pow( const Spectrum& a, const Spectrum& b)
701 {
702  mi_math_assert_msg( a.size() == 3, "precondition");
703  mi_math_assert_msg( b.size() == 3, "precondition");
704  return Spectrum( pow( a[0], b[0]), pow( a[1], b[1]), pow( a[2], b[2]));
705 }
706 
708 inline Spectrum pow( const Spectrum& a, Float32 b)
709 {
710  mi_math_assert_msg( a.size() == 3, "precondition");
711  return Spectrum( pow( a[0], b), pow( a[1], b), pow( a[2], b));
712 }
713 
715 inline Spectrum radians( const Spectrum& c)
716 {
717  mi_math_assert_msg( c.size() == 3, "precondition");
718  return Spectrum( radians( c[0]), radians( c[1]), radians( c[2]));
719 }
720 
722 inline Spectrum round( const Spectrum& c)
723 {
724  mi_math_assert_msg( c.size() == 3, "precondition");
725  return Spectrum( round( c[0]), round( c[1]), round( c[2]));
726 }
727 
729 inline Spectrum rsqrt( const Spectrum& c)
730 {
731  mi_math_assert_msg( c.size() == 3, "precondition");
732  return Spectrum( rsqrt( c[0]), rsqrt( c[1]), rsqrt( c[2]));
733 }
734 
736 inline Spectrum saturate( const Spectrum& c)
737 {
738  mi_math_assert_msg( c.size() == 3, "precondition");
739  return Spectrum( saturate( c[0]), saturate( c[1]), saturate( c[2]));
740 }
741 
743 inline Spectrum sign( const Spectrum& c)
744 {
745  mi_math_assert_msg( c.size() == 3, "precondition");
746  return Spectrum( sign( c[0]), sign( c[1]), sign( c[2]));
747 }
748 
750 inline Spectrum sin( const Spectrum& c)
751 {
752  mi_math_assert_msg( c.size() == 3, "precondition");
753  return Spectrum( sin( c[0]), sin( c[1]), sin( c[2]));
754 }
755 
759 inline void sincos( const Spectrum& a, Spectrum& s, Spectrum& c)
760 {
761  mi_math_assert_msg( a.size() == 3, "precondition");
762  mi_math_assert_msg( s.size() == 3, "precondition");
763  mi_math_assert_msg( c.size() == 3, "precondition");
764  sincos( a[0], s[0], c[0]);
765  sincos( a[1], s[1], c[1]);
766  sincos( a[2], s[2], c[2]);
767 }
768 
774 inline Spectrum smoothstep( const Spectrum& a, const Spectrum& b, const Spectrum& c)
775 {
776  mi_math_assert_msg( a.size() == 3, "precondition");
777  mi_math_assert_msg( b.size() == 3, "precondition");
778  mi_math_assert_msg( c.size() == 3, "precondition");
779  return Spectrum( smoothstep( a[0], b[0], c[0]),
780  smoothstep( a[1], b[1], c[1]),
781  smoothstep( a[2], b[2], c[2]));
782 }
783 
789 inline Spectrum smoothstep( const Spectrum& a, const Spectrum& b, Float32 x)
790 {
791  mi_math_assert_msg( a.size() == 3, "precondition");
792  mi_math_assert_msg( b.size() == 3, "precondition");
793  return Spectrum( smoothstep( a[0], b[0], x),
794  smoothstep( a[1], b[1], x),
795  smoothstep( a[2], b[2], x));
796 }
797 
799 inline Spectrum sqrt( const Spectrum& c)
800 {
801  mi_math_assert_msg( c.size() == 3, "precondition");
802  return Spectrum( sqrt( c[0]), sqrt( c[1]), sqrt( c[2]));
803 }
804 
806 inline Spectrum step( const Spectrum& a, const Spectrum& c)
807 {
808  mi_math_assert_msg( a.size() == 3, "precondition");
809  mi_math_assert_msg( c.size() == 3, "precondition");
810  return Spectrum( step( a[0], c[0]), step( a[1], c[1]), step( a[1], c[2]));
811 }
812 
814 inline Spectrum tan( const Spectrum& c)
815 {
816  mi_math_assert_msg( c.size() == 3, "precondition");
817  return Spectrum( tan( c[0]), tan( c[1]), tan( c[2]));
818 }
819 
822 {
823  mi_math_assert_msg( c.size() == 3, "precondition");
824  return isfinite MI_PREVENT_MACRO_EXPAND (c[0])
827 }
828 
831 {
832  mi_math_assert_msg( c.size() == 3, "precondition");
833  return isinfinite MI_PREVENT_MACRO_EXPAND (c[0])
836 }
837 
839 inline bool isnan MI_PREVENT_MACRO_EXPAND (const Spectrum& c)
840 {
841  mi_math_assert_msg( c.size() == 3, "precondition");
842  return isnan MI_PREVENT_MACRO_EXPAND (c[0])
844  || isnan MI_PREVENT_MACRO_EXPAND (c[2]);
845 }
846 
848 inline void to_rgbe( const Spectrum& c, Uint32& rgbe)
849 {
850  mi_math_assert_msg( c.size() == 3, "precondition");
851  to_rgbe( &c[0], rgbe);
852 }
853 
855 inline void to_rgbe( const Spectrum& c, Uint8 rgbe[4])
856 {
857  mi_math_assert_msg( c.size() == 3, "precondition");
858  to_rgbe( &c[0], rgbe);
859 }
860 
862 inline void from_rgbe( const Uint8 rgbe[4], Spectrum& c)
863 {
864  mi_math_assert_msg( c.size() == 3, "precondition");
865  from_rgbe( rgbe, &c[0]);
866 }
867 
869 inline void from_rgbe( const Uint32 rgbe, Spectrum& c)
870 {
871  mi_math_assert_msg( c.size() == 3, "precondition");
872  from_rgbe( rgbe, &c[0]);
873 }
874  // end group mi_math_spectrum
876 
877 } // namespace math
878 
879 } // namespace mi
880 
881 #endif // MI_MATH_SPECTRUM_H