00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "spd.h"
00026 #include "color.h"
00027 #include "memory.h"
00028 #include "data/xyzbasis.h"
00029
00030 using namespace lux;
00031
00032 void SPD::AllocateSamples(int n) {
00033
00034 samples = AllocAligned<float>(n);
00035 }
00036
00037 void SPD::FreeSamples() {
00038
00039 if (samples)
00040 FreeAligned(samples);
00041 }
00042
00043 void SPD::Normalize() {
00044 float max = 0.f;
00045
00046 for(int i=0; i<nSamples; i++)
00047 if(samples[i] > max)
00048 max = samples[i];
00049
00050 float scale = 1.f/max;
00051
00052 for(int i=0; i<nSamples; i++)
00053 samples[i] *= scale;
00054 }
00055
00056 void SPD::Clamp() {
00057 for(int i=0; i<nSamples; i++) {
00058 if(samples[i] < 0.f) samples[i] = 0.f;
00059 if(samples[i] > INFINITY) samples[i] = INFINITY;
00060 }
00061 }
00062
00063 void SPD::Scale(float s) {
00064 for(int i=0; i<nSamples; i++)
00065 samples[i] *= s;
00066 }
00067
00068 void SPD::Whitepoint(float temp) {
00069 vector<float> bbvals;
00070
00071
00072 for(int i=0; i<nSamples; i++) {
00073 float w = 1e-9f * (lambdaMin + (delta*i));
00074
00075 bbvals.push_back(4e-9f * (3.74183e-16f * powf(w, -5.f))
00076 / (expf(1.4388e-2f / (w * temp)) - 1.f));
00077 }
00078
00079
00080 float max = 0.f;
00081 for(int i=0; i<nSamples; i++)
00082 if(bbvals[i] > max)
00083 max = bbvals[i];
00084 float scale = 1.f/max;
00085 for(int i=0; i<nSamples; i++)
00086 bbvals[i] *= scale;
00087
00088
00089 for(int i=0; i<nSamples; i++)
00090 samples[i] *= bbvals[i];
00091
00092 bbvals.clear();
00093 }
00094
00095 float SPD::Y() const
00096 {
00097 float y = 0.f;
00098 for (int i = 0; i < nCIE; ++i)
00099 y += sample(i + CIEstart) * CIE_Y[i];
00100 return y * 683.f;
00101 }
00102 XYZColor SPD::ToXYZ() const
00103 {
00104 XYZColor c(0.f);
00105 for (int i = 0; i < nCIE; ++i) {
00106 float s = sample(i + CIEstart);
00107 c.c[0] += s * CIE_X[i];
00108 c.c[1] += s * CIE_Y[i];
00109 c.c[2] += s * CIE_Z[i];
00110 }
00111 return c * 683.f;
00112 }