SpectralSampleSet.inl

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   SpectralSampleSet.inl
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Fall 2008
00006    
00007    @brief
00008       Templated set of spectral values (wavelength-dependeht), sampled at N 
00009    distinct wavelengths. Specific SpectralSampleSet instances include 
00010    SpectralRadianceSet, in which each sample represents the radiance at a single
00011    wavelength with units Watts / (m^2 sr), and SpectralScalarSet, where each 
00012    wavelength-dependent sample represents a unitless scalar that can be used 
00013    to attenuate SpectralRadianceSet.
00014    
00015    @note
00016       Throughout Milton, currently only RGB spectra are used, but this 
00017    abstraction is in place and used ubiquitously s.t. we can eventually come 
00018    back and implement spectrally-aware rendering with the majority of the 
00019    changes taking place in this one class.
00020   <!-------------------------------------------------------------------->**/
00021 
00022 #ifndef SPECTRAL_SAMPLE_SET_INL_
00023 #define SPECTRAL_SAMPLE_SET_INL_
00024 
00025 #include <iostream>
00026 using namespace std;
00027 
00028 // Constructors
00029 // ------------
00030 
00031 // Constructs a SpectralSampleSet sampled at the three canonical RGB 
00032 // wavelengths, with the sample values specified in the given 
00033 // 3-element array
00034 inline SpectralSampleSet::SpectralSampleSet(const real_t *data)
00035    : m_data(new SpectralSample[NO_DEFAULT_WAVELENGTHS]), 
00036      m_n(NO_DEFAULT_WAVELENGTHS)
00037 {
00038    for(unsigned i = m_n; i--;) {
00039       m_data[i].value      = data[i];
00040       m_data[i].wavelength = SpectralSampleSet::s_defaultWavelengths[i];
00041    }
00042 }
00043 
00044 // Constructs a SpectralSampleSet sampled at the three canonical RGB 
00045 // wavelengths, with zero values
00046 inline SpectralSampleSet::SpectralSampleSet() 
00047    : m_data(new SpectralSample[NO_DEFAULT_WAVELENGTHS]), 
00048      m_n(NO_DEFAULT_WAVELENGTHS)
00049 {
00050    for(unsigned i = m_n; i--;) {
00051       m_data[i].value      = 0;
00052       m_data[i].wavelength = SpectralSampleSet::s_defaultWavelengths[i];
00053    }
00054 }
00055 
00056 // Constructs a SpectralSampleSet sampled at the three canonical RGB 
00057 // wavelengths, with the sample values given
00058 inline SpectralSampleSet::SpectralSampleSet(const real_t &r, 
00059                                                const real_t &g, 
00060                                                const real_t &b)
00061    : m_data(new SpectralSample[3]), m_n(3)
00062 {
00063    m_data[0].value      = r;
00064    m_data[0].wavelength = SpectralSampleSet::s_defaultWavelengths[0];
00065    
00066    m_data[1].value      = g;
00067    m_data[1].wavelength = SpectralSampleSet::s_defaultWavelengths[1];
00068    
00069    m_data[2].value      = b;
00070    m_data[2].wavelength = SpectralSampleSet::s_defaultWavelengths[2];
00071 }
00072 
00073 // Constructs a SpectralSampleSet sampled at the three canonical RGB 
00074 // wavelengths, with the sample values specified in the given 3-
00075 // element vector
00076 inline SpectralSampleSet::SpectralSampleSet(const Vector3 &v)
00077    : m_data(new SpectralSample[NO_DEFAULT_WAVELENGTHS]), 
00078      m_n(NO_DEFAULT_WAVELENGTHS)
00079 {
00080    for(unsigned i = m_n; i--;) {
00081       m_data[i].value      = v[i];
00082       m_data[i].wavelength = SpectralSampleSet::s_defaultWavelengths[i];
00083    }
00084 }
00085 
00086 // Constructs a SpectralSampleSet sampled at the three canonical RGB 
00087 // wavelengths, with the sample values specified by the given RgbaHDR
00088 inline SpectralSampleSet::SpectralSampleSet(const RgbaHDR &rgba)
00089    : m_data(new SpectralSample[NO_DEFAULT_WAVELENGTHS]), 
00090      m_n(NO_DEFAULT_WAVELENGTHS)
00091 {
00092    m_data[0].value      = rgba.r;
00093    m_data[0].wavelength = SpectralSampleSet::s_defaultWavelengths[0];
00094    
00095    m_data[1].value      = rgba.g;
00096    m_data[1].wavelength = SpectralSampleSet::s_defaultWavelengths[1];
00097    
00098    m_data[2].value      = rgba.b;
00099    m_data[2].wavelength = SpectralSampleSet::s_defaultWavelengths[2];
00100 }
00101 
00102 // Copy Constructor
00103 inline SpectralSampleSet::SpectralSampleSet(const SpectralSampleSet &v) 
00104    : m_data(new SpectralSample[v.m_n]), m_n(v.m_n)
00105 {
00106    for(unsigned i = m_n; i--;)
00107       m_data[i] = v[i];
00108 }
00109 
00110 
00111 // Accessor Operators
00112 // ------------------
00113 
00114 // @returns a reference to the element at the given index
00115 inline const SpectralSample &SpectralSampleSet::operator[](
00116    const unsigned index) const
00117 {
00118    ASSERT(index >= 0 && index < m_n);
00119    
00120    return m_data[index];
00121 }
00122 
00123 // @returns a reference to the element at the given index
00124 // @note changes to the returned element will affect this spectrum
00125 inline       SpectralSample &SpectralSampleSet::operator[](
00126    const unsigned index)
00127 {
00128    ASSERT(index >= 0 && index < m_n);
00129    
00130    return m_data[index];
00131 }
00132 
00133 // @returns the number of spectral samples contained in this set
00134 inline unsigned SpectralSampleSet::getN() const {
00135    return m_n;
00136 }
00137 
00138 
00139 // Equality Operators
00140 // ------------------
00141 inline       bool       SpectralSampleSet::operator==(
00142    const SpectralSampleSet &v) const
00143 {
00144    if (m_n != v.m_n)
00145       return false;
00146    
00147    for(unsigned i = m_n; i--;) {
00148       if (m_data[i] != v[i])
00149          return false;
00150    }
00151    
00152    return true;
00153 }
00154 
00155 inline       bool       SpectralSampleSet::operator!=(
00156    const SpectralSampleSet &v) const 
00157 {
00158    return !((*this) == v);
00159 }
00160 
00161 
00162 // Relational Operators
00163 // ------------------
00164 inline       bool       SpectralSampleSet::operator>=(
00165    const SpectralSampleSet &v) const
00166 {
00167    ASSERT(m_n == v.m_n);
00168    
00169    for(unsigned i = m_n; i--;) {
00170       ASSERT(m_data[i].wavelength == v[i].wavelength);
00171       
00172       if (!(m_data[i].value >= v[i].value))
00173          return false;
00174    }
00175    
00176    return true;
00177 }
00178 
00179 inline       bool       SpectralSampleSet::operator<=(
00180    const SpectralSampleSet &v) const 
00181 {
00182    ASSERT(m_n == v.m_n);
00183    
00184    for(unsigned i = m_n; i--;) {
00185       ASSERT(m_data[i].wavelength == v[i].wavelength);
00186       
00187       if (!(m_data[i].value <= v[i].value))
00188          return false;
00189    }
00190    
00191    return true;
00192 }
00193 
00194 
00195 // Mutator Operators
00196 // -----------------
00197 inline       SpectralSampleSet &SpectralSampleSet::operator =(
00198    const SpectralSampleSet &v)
00199 {
00200    SpectralSample *old = m_data;
00201    
00202    m_n    = v.m_n;
00203    m_data = new SpectralSample[m_n];
00204    safeDeleteArray(old);
00205    
00206    for(unsigned i = m_n; i--;)
00207       m_data[i] = v[i];
00208    
00209    return *this;
00210 }
00211 
00212 inline       SpectralSampleSet &SpectralSampleSet::operator+=(
00213    const SpectralSampleSet &rhs)
00214 {
00215    ASSERT(m_n == rhs.m_n);
00216    
00217    for(unsigned i = m_n; i--;) {
00218       ASSERT(m_data[i].wavelength == rhs[i].wavelength);
00219       
00220       m_data[i].value += rhs.m_data[i].value;
00221    }
00222    
00223    return *this;
00224 }
00225 
00226 inline       SpectralSampleSet &SpectralSampleSet::operator-=(
00227    const SpectralSampleSet &rhs)
00228 {
00229    ASSERT(m_n == rhs.m_n);
00230    
00231    for(unsigned i = m_n; i--;) {
00232       ASSERT(m_data[i].wavelength == rhs[i].wavelength);
00233       
00234       m_data[i].value -= rhs.m_data[i].value;
00235    }
00236    
00237    return *this;
00238 }
00239 
00240 
00241 // Scalar Mutator Operators
00242 // ------------------------
00243 inline       SpectralSampleSet &SpectralSampleSet::operator*=(const real_t &scale) {
00244    for(unsigned i = m_n; i--;)
00245       m_data[i].value *= scale;
00246    
00247    return *this;
00248 }
00249 
00250 inline       SpectralSampleSet &SpectralSampleSet::operator/=(const real_t &scale) {
00251    ASSERT(scale != 0);
00252    
00253    for(unsigned i = m_n; i--;)
00254       m_data[i].value /= scale;
00255    
00256    return *this;
00257 }
00258 
00259 
00260 // Arithmetic Operators
00261 // --------------------
00262 
00263 inline       SpectralSampleSet  SpectralSampleSet::operator+ (const SpectralSampleSet &rhs) const
00264 {
00265    SpectralSampleSet s(*this);
00266    s += rhs;
00267    
00268    return s;
00269 }
00270 
00271 inline       SpectralSampleSet  SpectralSampleSet::operator- (const SpectralSampleSet &rhs) const
00272 {
00273    SpectralSampleSet s(*this);
00274    s -= rhs;
00275    
00276    return s;
00277 }
00278 
00279 inline       SpectralSampleSet  SpectralSampleSet::operator/ (const SpectralSampleSet &rhs) const
00280 {
00281    SpectralSampleSet s(*this);
00282    ASSERT(m_n == rhs.m_n);
00283    
00284    for(unsigned i = m_n; i--;) {
00285       ASSERT(m_data[i].wavelength == rhs.m_data[i].wavelength);
00286       ASSERT(rhs.m_data[i].value != 0);
00287       
00288       s.m_data[i].value /= rhs.m_data[i].value;
00289    } 
00290    
00291    return s;
00292 }
00293 
00294 inline       SpectralSampleSet  SpectralSampleSet::operator* (const SpectralSampleSet &rhs) const
00295 {
00296    SpectralSampleSet s(*this);
00297    ASSERT(m_n == rhs.m_n);
00298    
00299    for(unsigned i = m_n; i--;) {
00300       ASSERT(m_data[i].wavelength == rhs.m_data[i].wavelength);
00301       
00302       s.m_data[i].value *= rhs.m_data[i].value;
00303    }
00304    
00305    return s;
00306 }
00307 
00308 
00309 // Scalar Arithmetic Operators
00310 inline       SpectralSampleSet  SpectralSampleSet::operator* (const real_t &scale) const {
00311    SpectralSampleSet s(*this);
00312    s *= scale;
00313    
00314    return s;
00315 }
00316 
00317 inline       SpectralSampleSet  SpectralSampleSet::operator/ (const real_t &scale) const {
00318    SpectralSampleSet s(*this);
00319    s /= scale;
00320    
00321    return s;
00322 }
00323 
00324 
00325 // Misc Functionality
00326 // --------------------------
00327 
00328 // @returns whether or not all samples in this set are zero
00329 inline bool SpectralSampleSet::isZero() const {
00330    for(unsigned i = m_n; i--;)
00331       if (NEQ(m_data[i].value, 0))
00332          return false;
00333    
00334    return true;
00335 }
00336 
00337 // @returns the sum of the components in this SpectralSampleSet
00338 inline real_t SpectralSampleSet::getSum() const {
00339    real_t sum = 0;
00340    
00341    for(unsigned i = m_n; i--;)
00342       sum += m_data[i].value;
00343    
00344    return sum;
00345 }
00346 
00347 // @returns the average of the components in this SpectralSampleSet
00348 inline real_t SpectralSampleSet::getAverage() const {
00349    return getSum() / m_n;
00350 }
00351 
00352 
00353 // Extra operators where SpectralSampleSet is on right-hand side
00354 // --------------------------------------------------
00355 
00356 // @returns the @p v, with each spectral sample scaled by @p scale
00357 inline       SpectralSampleSet  operator* (const real_t &scale, 
00358                                            const SpectralSampleSet &rhs)
00359 {
00360    return rhs * scale;
00361 }
00362 
00363 // Prints a SpectralSampleSet to an output stream
00364 inline       std::ostream      &operator<<(std::ostream &os, 
00365                                            const SpectralSampleSet &v)
00366 {
00367    const unsigned n = v.getN();
00368    
00369    os << "{ ";
00370    for(unsigned i = 0; i < n; ++i) {
00371       os << v[i].value << " (" << v[i].wavelength << ")" << 
00372          (i < n - 1 ? ", " : "");
00373    }
00374    os << " }";
00375    
00376    return os;
00377 }
00378 
00379 // @returns dimension (0,1,...,N) of maximum value
00380 inline unsigned SpectralSampleSet::getMaxSample() const {
00381    real_t maxValue = m_data[0].value;
00382    unsigned maxIndex = 0;
00383    
00384    for(unsigned i = 1; i < m_n; ++i) {
00385       if (m_data[i].value > maxValue) {
00386          maxValue = m_data[i].value;
00387          maxIndex = i;
00388       }
00389    }
00390    
00391    return maxIndex;
00392 }
00393 
00394 // @returns dimension (0,1,...,N) of minimum value
00395 inline unsigned SpectralSampleSet::getMinSample() const {
00396    real_t minValue = m_data[0].value;
00397    unsigned minIndex = 0;
00398    
00399    for(unsigned i = 1; i < m_n; ++i) {
00400       if (m_data[i].value < minValue) {
00401          minValue = m_data[i].value;
00402          minIndex = i;
00403       }
00404    }
00405    
00406    return minIndex;
00407 }
00408 
00409 // @returns this SpectralSampleSet converted to RGB format
00410 inline RgbaHDR SpectralSampleSet::getRGB() const {
00411    return RgbaHDR::fromVector(Vector3(m_data[0].value, m_data[1].value, 
00412                                       m_data[2].value));
00413 }
00414 
00415 // @returns this SpectralSampleSet as a HDR floating-point rgba struct (implicit conversion)
00416 inline SpectralSampleSet::operator RgbaHDR() const {
00417    return RgbaHDR::fromVector(Vector3(m_data[0].value, m_data[1].value, 
00418                                       m_data[2].value));
00419 }
00420 
00421 #endif // SPECTRAL_SAMPLE_SET_INL_
00422 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6