00001 #include "vuColour31a.h"
00002 #include "vuColour7a.h"
00003 #include "vuColour9a.h"
00004 #include "vuColourXYZa.h"
00005 #include "vuTFDesignSpec.h"
00006
00007
00008
00009
00010
00011
00012
00013 void vuTFDesignSpec::generateFunction()
00014 {
00015 vuTFDesign::generateFunction();
00016
00017 }
00018
00019
00020 void vuTFDesignSpec::generateOpacities()
00021 {
00022 dword index;
00023
00024 dword numOpacities = m_Opacities.getLength();
00025 if(false)
00026 {
00027
00028 }
00029
00030
00031
00032 index = 0;
00033 for (dword i = 0; i < numOpacities-1; i++)
00034 {
00035 float slope = float(m_Opacities[i+1].opacity - m_Opacities[i].opacity) /
00036 float(m_Opacities[i+1].intensity - m_Opacities[i].intensity);
00037
00038 for (; index <= m_Opacities[i+1].intensity; index ++)
00039 m_Table[index*m_NComp+(m_NComp-1)] = m_Opacities[i].opacity +
00040 slope * (index-m_Opacities[i].intensity);
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 }
00057
00058
00059
00060
00061
00062 dword vuTFDesignSpec::addLight(const float* _col)
00063 {
00064
00065 LightNode cp(0.f,m_NComp,_col);
00066
00067
00068 m_Lights.add(cp);
00069 return m_Lights.getLength()-1;
00070 }
00071
00072
00073
00074
00075
00076 dword vuTFDesignSpec::getNumLights() const
00077 {
00078 return m_Lights.getLength();
00079 }
00080
00081
00082
00083
00084
00085 const vuTFDesignSpec::LightNode&
00086 vuTFDesignSpec::getLightNode(dword index) const
00087 {
00088 return m_Lights[index];
00089 }
00090
00091
00092
00093
00094 void vuTFDesignSpec::setLightWeight(dword index, float _weight)
00095 {
00096 m_Lights[index].weight = _weight;
00097 }
00098
00099
00100
00101
00102
00103 void vuTFDesignSpec::weightLights(const float* weights)
00104 {
00105 dword llen = getNumLights();
00106 for(dword l=0;l<llen;l++) {
00107 setLightWeight(l, weights[l]);
00108 }
00109 generateLight();
00110 }
00111
00112
00113
00114
00115
00116 void vuTFDesignSpec::generateLight()
00117 {
00118 if(m_NComp == 32) {
00119 vuColour31a lcol(0.0f);
00120 dword llen = getNumLights();
00121 for(dword l=0;l<llen;l++) {
00122 vuColour31a lamp(m_Lights[l].col);
00123 lamp *= m_Lights[l].weight;
00124 lcol += lamp;
00125 }
00126
00127
00128 lcol*= m_LightIntensity;
00129
00130 const float *fpc=lcol.getData();
00131 for(dword c=0;c<32;c++,fpc++)
00132 m_Light[c] = *fpc;
00133
00134 } else if(m_NComp == 8) {
00135
00136 vuColour7a lcol(0.0f);
00137 dword llen = getNumLights();
00138 for(dword l=0;l<llen;l++) {
00139 vuColour7a lamp(m_Lights[l].col);
00140 lamp *= m_Lights[l].weight;
00141 lcol += lamp;
00142 }
00143 for(dword c=0;c<8;c++)
00144 m_Light[c] = lcol[c]*m_LightIntensity;
00145 } else if(m_NComp == 10) {
00146 vuColour9a lcol(0.0f);
00147 dword llen = getNumLights();
00148 for(dword l=0;l<llen;l++) {
00149 vuColour9a lamp(m_Lights[l].col);
00150 lamp *= m_Lights[l].weight;
00151 lcol += lamp;
00152 }
00153 for(dword c=0;c<10;c++)
00154 m_Light[c] = lcol[c]*m_LightIntensity;
00155 } else {
00156 cout<<"Transfer functions with inherent light sources only supported for 31 and 7 component model."
00157 <<endl<<"This transfer function has "<<m_NComp<<" components."<<endl;
00158 }
00159 }
00160
00161
00162 void vuTFDesignSpec::setLightOpacityNode(word lindex, int intensity)
00163 {
00164 if(lindex < getNumLights())
00165 {
00166 int oind;
00167 for(oind = int(getNumOpacities())-1;oind>=0;oind--)
00168 if(int(m_Opacities[oind].intensity) <= intensity) break;
00169
00170 if(oind > -1)
00171 {
00172 for(int lind = getNumLights()-1;lind>=0;lind--)
00173 if(m_Lights[lind].wopade == oind) m_Lights[lind].wopade = -1;
00174 }
00175 m_Lights[lindex].wopade = oind;
00176 }
00177 }
00178
00179
00180 void vuTFDesignSpec::setupMtlTriAlphaNodes()
00181 {
00182 word numOpacities = m_Opacities.getLength();
00183 word numColours = m_Colours.getLength();
00184 word nnumOpacities = numColours*3+2;
00185 if(numOpacities > nnumOpacities) m_Opacities.removeRange(nnumOpacities, numOpacities);
00186 else
00187 {
00188 for(word opac = numOpacities; opac < numColours*3+2; opac++)
00189 m_Opacities.insert(m_Opacities.getLength()-2,OpacityNode(0,0));
00190 }
00191
00192 numOpacities = m_Opacities.getLength();
00193
00194
00195
00196 word lint = 0;
00197 for(word c = 0; c < numColours; c++)
00198 {
00199 word cind = 1+3*c;
00200 word nint = m_Colours[c].intensity;
00201 word cint = (lint+nint)/2;
00202
00203
00204 word tmpint = word(0.9*lint + 0.1*cint);
00205 if(tmpint == lint) tmpint++;
00206 m_Opacities[cind].intensity = tmpint;
00207 m_Opacities[cind+1].intensity = cint;
00208 tmpint = word(0.1*cint + 0.9*nint);
00209 if(tmpint == nint) tmpint--;
00210 m_Opacities[cind+2].intensity = word(tmpint);
00211 lint = m_Colours[c].intensity;
00212 }
00213 m_Opacities[numOpacities-1].intensity = m_Range-1;
00214 }
00215
00216
00217 void vuTFDesignSpec::setAlphaByLight()
00218 {
00219 word numOpacities = m_Opacities.getLength();
00220 word numLights = m_Lights.getLength();
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 for(word l=0;l<numLights;l++)
00235 {
00236 int oind = m_Lights[l].wopade;
00237 if(oind >= 0 && oind<numOpacities)
00238 m_Opacities[oind].opacity = m_Lights[l].weight;
00239 }
00240
00241 }
00242
00243
00244
00245
00246 void vuTFDesignSpec::writeTFunc(ofstream &ofp) const
00247 {
00248 writeNComp(ofp);
00249 writeOpacities(ofp);
00250 writeColours(ofp);
00251 writeLights(ofp);
00252 }
00253
00254 bool vuTFDesignSpec::writeLights(ofstream &ofp) const
00255 {
00256
00257 word ncol = getNumLights();
00258 for(dword o=0;o<ncol;o++) {
00259 ofp<<"light(";
00260 for(dword c=0;c<m_NComp-1;c++) {
00261 if(c)ofp<<", ";
00262 ofp<<getLightNode(o).col[c];
00263 }
00264 ofp<<")"<<endl<<endl;
00265 }
00266 return true;
00267 }
00268
00269 void vuTFDesignSpec::clearAllNodes()
00270 {
00271 m_Lights.removeRange(0,m_Lights.getLength());
00272 vuTFDesign::clearAllNodes();
00273 }
00274
00275
00276
00277
00278
00279 void vuTFDesignSpec::parseTFunc()
00280 {
00281 clearAllNodes();
00282
00283 bool read = true;
00284 while (read) {
00285 read = false;
00286 if ( readOpacity() ) { read = true; }
00287 else if ( readColour() ) { read = true; }
00288 else if ( readLight() ) { read = true; }
00289 else if ( readNComp() ) { read = true; };
00290 }
00291
00292 m_Palette.reset();
00293 updatePalette();
00294 }
00295
00296
00297 bool vuTFDesignSpec::readLight()
00298 {
00299 if( readString("light") ) {
00300 float col[32];
00301 if(!readNumber(" ( ",col[0])) throw "Error reading light.";
00302 bool read = true;
00303 dword c = 1;
00304 while (read && c<32) {
00305 read = false;
00306 if(readNumber(" , ",col[c])) {
00307 read = true;
00308 c++;
00309 } else if(readString(" ) ")) read = false;
00310 }
00311 if(c==32) readString(" ) ");
00312 else if(c==0) throw "Error reading light components";
00313 while(c<32) col[c++] = 0.0f;
00314 addLight(col);
00315 return true;
00316 } else return false;
00317 }
00318
00319
00321 void vuTFDesignSpec::updatePalette()
00322 {
00323 while(m_Palette.getNLights() < getNumLights())
00324 m_Palette.addLight(vuColour31a());
00325 while(m_Palette.getNRefls() < getNumColours())
00326 m_Palette.addReflectance(vuColour31a());
00327
00328 for(dword i=0;i<getNumLights() && i<m_Palette.getNLights();i++)
00329 {
00330 vuColour31a light(m_Lights[i].col);
00331 #ifdef NORMALIZE_LIGHTS //we shouldn't do that
00332 light /= SVector(light).norm();
00333 #endif
00334 m_Palette.getSpec(-1,i) = light;
00335 }
00336
00337 for(dword i=0;i<getNumColours() && i<m_Palette.getNRefls();i++)
00338 m_Palette.getSpec(i,-1) = vuColour31a(m_Colours[i].col);
00339
00340 m_Palette.matchDesignColours();
00341 }
00342
00343
00345 void vuTFDesignSpec::updateFromPalette()
00346 {
00347 for(dword i=0;i<m_Palette.getNLights();i++)
00348 {
00349 if(i<getNumLights())
00350 memcpy(m_Lights[i].col,m_Palette.getSpec(-1,i).getData(),
00351 sizeof(float)*31);
00352 else{
00353 addLight(m_Palette.getSpec(-1,i).getData());
00354 }
00355 }
00356
00357 for(dword i=0;i<m_Palette.getNRefls() && i<getNumColours();i++)
00358 {
00359 memcpy(m_Colours[i].col,m_Palette.getSpec(i,-1).getData(),
00360 sizeof(float)*31);
00361 }
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371