00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _LUXRAYS_SDL_SPD_H
00025 #define _LUXRAYS_SDL_SPD_H
00026
00027 #include <cstddef>
00028
00029 #include "luxrays/luxrays.h"
00030 #include "luxrays/utils/sdl/mc.h"
00031
00032 namespace luxrays { namespace sdl {
00033
00034 class SPD {
00035 public:
00036 SPD() {
00037 nSamples = 0U;
00038 lambdaMin = lambdaMax = delta = invDelta = 0.f;
00039 samples = NULL;
00040 }
00041 virtual ~SPD() { FreeSamples(); }
00042
00043
00044 inline float sample(const float lambda) const {
00045 if (nSamples <= 1 || lambda < lambdaMin || lambda > lambdaMax)
00046 return 0.f;
00047
00048
00049 const float x = (lambda - lambdaMin) * invDelta;
00050 const unsigned int b0 = Floor2UInt(x);
00051 const unsigned int b1 = Min(b0 + 1, nSamples - 1);
00052 const float dx = x - b0;
00053 return Lerp(dx, samples[b0], samples[b1]);
00054 }
00055
00056 inline void sample(unsigned int n, const float lambda[], float *p) const {
00057 for (unsigned int i = 0; i < n; ++i) {
00058 if (nSamples <= 1 || lambda[i] < lambdaMin ||
00059 lambda[i] > lambdaMax) {
00060 p[i] = 0.f;
00061 continue;
00062 }
00063
00064
00065 const float x = (lambda[i] - lambdaMin) * invDelta;
00066 const unsigned int b0 = Floor2UInt(x);
00067 const unsigned int b1 = Min(b0 + 1, nSamples - 1);
00068 const float dx = x - b0;
00069 p[i] = Lerp(dx, samples[b0], samples[b1]);
00070 }
00071 }
00072
00073 float Y() const;
00074 float Filter() const;
00075 void AllocateSamples(unsigned int n);
00076 void FreeSamples();
00077 void Normalize();
00078 void Clamp();
00079 void Scale(float s);
00080 void Whitepoint(float temp);
00081 Spectrum ToRGB();
00082
00083 protected:
00084 unsigned int nSamples;
00085 float lambdaMin, lambdaMax;
00086 float delta, invDelta;
00087 float *samples;
00088
00089 };
00090
00091
00092 class RegularSPD : public SPD {
00093 public:
00094 RegularSPD() : SPD() {}
00095
00096
00097
00098
00099
00100
00101 RegularSPD(const float* const s, float lMin, float lMax, unsigned int n) : SPD() {
00102 init(lMin, lMax, s, n);
00103 }
00104
00105 virtual ~RegularSPD() {}
00106
00107 protected:
00108 void init(float lMin, float lMax, const float* const s, unsigned int n);
00109 };
00110
00111
00112 enum SPDResamplingMethod { Linear, Spline };
00113
00114
00115
00116
00117 class IrregularSPD : public SPD {
00118 public:
00119
00120 IrregularSPD() : SPD() {}
00121
00122
00123
00124
00125
00126
00127
00128 IrregularSPD(const float* const wavelengths, const float* const samples,
00129 unsigned int n, float resolution = 5, SPDResamplingMethod resamplignMethod = Linear);
00130
00131 virtual ~IrregularSPD() {}
00132
00133 protected:
00134 void init(float lMin, float lMax, const float* const s, unsigned int n);
00135
00136 private:
00137
00138
00139 void calc_spline_data(const float* const wavelengths,
00140 const float* const amplitudes, unsigned int n, float *spline_data);
00141 };
00142
00143 } }
00144
00145 #endif