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
1.5.6