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 PBRT_COLOR_H
00025 #define PBRT_COLOR_H
00026
00027 #include "pbrt.h"
00028
00029 class COREDLL Spectrum {
00030 public:
00031
00032 Spectrum(float v = 0.f) {
00033 for (int i = 0; i < COLOR_SAMPLES; ++i)
00034 c[i] = v;
00035 }
00036 Spectrum(float cs[COLOR_SAMPLES]) {
00037 for (int i = 0; i < COLOR_SAMPLES; ++i)
00038 c[i] = cs[i];
00039 }
00040 friend ostream &operator<<(ostream &, const Spectrum &);
00041 Spectrum &operator+=(const Spectrum &s2) {
00042 for (int i = 0; i < COLOR_SAMPLES; ++i)
00043 c[i] += s2.c[i];
00044 return *this;
00045 }
00046 Spectrum operator+(const Spectrum &s2) const {
00047 Spectrum ret = *this;
00048 for (int i = 0; i < COLOR_SAMPLES; ++i)
00049 ret.c[i] += s2.c[i];
00050 return ret;
00051 }
00052 Spectrum operator-(const Spectrum &s2) const {
00053 Spectrum ret = *this;
00054 for (int i = 0; i < COLOR_SAMPLES; ++i)
00055 ret.c[i] -= s2.c[i];
00056 return ret;
00057 }
00058 Spectrum operator/(const Spectrum &s2) const {
00059 Spectrum ret = *this;
00060 for (int i = 0; i < COLOR_SAMPLES; ++i)
00061 ret.c[i] /= s2.c[i];
00062 return ret;
00063 }
00064 Spectrum operator*(const Spectrum &sp) const {
00065 Spectrum ret = *this;
00066 for (int i = 0; i < COLOR_SAMPLES; ++i)
00067 ret.c[i] *= sp.c[i];
00068 return ret;
00069 }
00070 Spectrum &operator*=(const Spectrum &sp) {
00071 for (int i = 0; i < COLOR_SAMPLES; ++i)
00072 c[i] *= sp.c[i];
00073 return *this;
00074 }
00075 Spectrum operator*(float a) const {
00076 Spectrum ret = *this;
00077 for (int i = 0; i < COLOR_SAMPLES; ++i)
00078 ret.c[i] *= a;
00079 return ret;
00080 }
00081 Spectrum &operator*=(float a) {
00082 for (int i = 0; i < COLOR_SAMPLES; ++i)
00083 c[i] *= a;
00084 return *this;
00085 }
00086 friend inline
00087 Spectrum operator*(float a, const Spectrum &s) {
00088 return s * a;
00089 }
00090 Spectrum operator/(float a) const {
00091 return *this * (1.f / a);
00092 }
00093 Spectrum &operator/=(float a) {
00094 float inv = 1.f / a;
00095 for (int i = 0; i < COLOR_SAMPLES; ++i)
00096 c[i] *= inv;
00097 return *this;
00098 }
00099 void AddWeighted(float w, const Spectrum &s) {
00100 for (int i = 0; i < COLOR_SAMPLES; ++i)
00101 c[i] += w * s.c[i];
00102 }
00103 bool operator==(const Spectrum &sp) const {
00104 for (int i = 0; i < COLOR_SAMPLES; ++i)
00105 if (c[i] != sp.c[i]) return false;
00106 return true;
00107 }
00108 bool operator!=(const Spectrum &sp) const {
00109 return !(*this == sp);
00110 }
00111 bool Black() const {
00112 for (int i = 0; i < COLOR_SAMPLES; ++i)
00113 if (c[i] != 0.) return false;
00114 return true;
00115 }
00116 Spectrum Sqrt() const {
00117 Spectrum ret;
00118 for (int i = 0; i < COLOR_SAMPLES; ++i)
00119 ret.c[i] = sqrtf(c[i]);
00120 return ret;
00121 }
00122 Spectrum Pow(const Spectrum &e) const {
00123 Spectrum ret;
00124 for (int i = 0; i < COLOR_SAMPLES; ++i)
00125 ret.c[i] = c[i] > 0 ? powf(c[i], e.c[i]) : 0.f;
00126 return ret;
00127 }
00128 Spectrum operator-() const {
00129 Spectrum ret;
00130 for (int i = 0; i < COLOR_SAMPLES; ++i)
00131 ret.c[i] = -c[i];
00132 return ret;
00133 }
00134 friend Spectrum Exp(const Spectrum &s) {
00135 Spectrum ret;
00136 for (int i = 0; i < COLOR_SAMPLES; ++i)
00137 ret.c[i] = expf(s.c[i]);
00138 return ret;
00139 }
00140 Spectrum Clamp(float low = 0.f,
00141 float high = INFINITY) const {
00142 Spectrum ret;
00143 for (int i = 0; i < COLOR_SAMPLES; ++i)
00144 ret.c[i] = ::Clamp(c[i], low, high);
00145 return ret;
00146 }
00147 bool IsNaN() const {
00148 for (int i = 0; i < COLOR_SAMPLES; ++i)
00149 if (isnan(c[i])) return true;
00150 return false;
00151 }
00152 void Print(FILE *f) const {
00153 for (int i = 0; i < COLOR_SAMPLES; ++i)
00154 fprintf(f, "%f ", c[i]);
00155 }
00156 void XYZ(float xyz[3]) const {
00157 xyz[0] = xyz[1] = xyz[2] = 0.;
00158 for (int i = 0; i < COLOR_SAMPLES; ++i) {
00159 xyz[0] += XWeight[i] * c[i];
00160 xyz[1] += YWeight[i] * c[i];
00161 xyz[2] += ZWeight[i] * c[i];
00162 }
00163 }
00164 float y() const {
00165 float v = 0.;
00166 for (int i = 0; i < COLOR_SAMPLES; ++i)
00167 v += YWeight[i] * c[i];
00168 return v;
00169 }
00170 bool operator<(const Spectrum &s2) const {
00171 return y() < s2.y();
00172 }
00173 friend class ParamSet;
00174
00175
00176 static const int CIEstart = 360;
00177 static const int CIEend = 830;
00178 static const int nCIE = CIEend-CIEstart+1;
00179 static const float CIE_X[nCIE];
00180 static const float CIE_Y[nCIE];
00181 static const float CIE_Z[nCIE];
00182 private:
00183
00184 float c[COLOR_SAMPLES];
00185 static float XWeight[COLOR_SAMPLES];
00186 static float YWeight[COLOR_SAMPLES];
00187 static float ZWeight[COLOR_SAMPLES];
00188 friend Spectrum FromXYZ(float x, float y, float z);
00189 };
00190 #endif // PBRT_COLOR_H