00001 #include "spectral.h"
00002 #include <fstream.h>
00003 #include <math.h>
00004
00005 #include "DatGrid.h"
00006 #include "Parser.h"
00007 #include "vuColourRGBa.h"
00008 #include "vuColourXYZa.h"
00009 #include "Util.h"
00010
00011
00012 namespace ns_vu1112112 {
00013 using namespace ns_vu1112112;
00014
00015 float ambient[]={
00016 82.8f, 91.6f, 93.5f, 86.8f, 104.9f, 117.1f,
00017 117.8f, 114.9f, 115.9f, 108.8f, 109.4f,
00018 107.8f, 104.9f, 107.7f, 104.4f, 104.0f,
00019 100.0f, 96.4f, 95.7f, 88.6f, 90.0f, 89.6f,
00020 87.6f, 83.3f, 83.7f, 80.0f, 80.2f, 82.2f,
00021 78.3f, 69.7f, 71.6f
00022 };
00023
00024
00025
00026
00027
00028
00029 vu1112112::vu1112112()
00030 {
00031 m_Camera = new vuPerspectiveCamera();
00032
00033 m_Camera->setHeight(240);
00034 m_Camera->setWidth(320);
00035 numlights = 0;
00036 nummat = 0;
00037 diffuse = 2.0f;
00038 brightness = 2.0f;
00039 light_scale = 1.0f;
00040 m_LightDir = vuVector(1,0,0);
00041 m_ObserverLight = false;
00042 imgbuf = NULL;
00043 re_light = re_render = false;
00044 ColourType c;
00045 m_TFunc.resize(c.nComponents(),256);
00046 m_DrawPreview = true;
00047 m_DoSpecular = false;
00048 m_Shininess = 20;
00049 m_Gloss = 3;
00050 }
00051
00052
00053
00054
00055
00056 vu1112112::vu1112112(const vu1112112& inst) : vu111211(inst)
00057 {
00058 operator=(inst);
00059 }
00060
00061
00062
00063
00064
00065 vu1112112::~vu1112112()
00066 {
00067 if(imgbuf) delete [] imgbuf;
00068 imgbuf = NULL;
00069 if (m_Camera != NULL) {
00070 delete m_Camera;
00071 m_Camera = NULL;
00072 }
00073 }
00074
00075
00076
00077
00078
00079 vu1112112& vu1112112::operator=(const vu1112112& rhs)
00080 {
00081 if (this != &rhs)
00082 {
00083 vu111211::operator=(rhs);
00084 Grid = rhs.Grid;
00085 }
00086 re_light = re_render = false;
00087 return *this;
00088 }
00089
00090
00091 void vu1112112::setImageSize(dword sx, dword sy)
00092 {
00093 m_Camera->setWidth(sx);
00094 m_Camera->setHeight(sy);
00095
00096 ((vuPerspectiveCamera *)m_Camera)->setAspect(float(sx)/sy);
00097 m_Camera->init();
00098 spimg.init(m_Camera->getWidth(),m_Camera->getHeight());
00099
00100 if(imgbuf) delete [] imgbuf;
00101 imgbuf = new byte[3*m_Camera->getWidth()*m_Camera->getHeight()];
00102 }
00103
00104
00105
00106
00107
00108 void vu1112112::setViewVectors(const vuVector& pos,const vuVector& vrp,
00109 const vuVector& up)
00110 {
00111 m_Camera->setPosition(pos);
00112 m_Camera->setLookAtVector(pos+vrp);
00113 m_Camera->setUpVector(up);
00114 m_Camera->init();
00115 }
00116
00117
00118
00119
00120
00121 bool vu1112112::read()
00122 {
00123 bool success = vu111211::read();
00124 if (!success) return false;
00125
00126 bool ret = Grid.load_vol(m_Data,*this);
00127 if(ret)
00128 {
00129 if (imgbuf) delete [] imgbuf;
00130 imgbuf = NULL;
00131
00132 center=vuVector((float)m_Dim1Size/2,(float)m_Dim2Size/2,
00133 (float)m_Dim3Size/2);
00134 m_Camera->setPosition(center);
00135 m_Camera->translateXYZ(0,0,-(float)m_Dim1Size);
00136 setImageSize(320,200);
00137 }
00138
00139 re_light = re_render = false;
00140
00141 pp_gradients = false;
00142 preprocess();
00143 return true;
00144 }
00145
00146
00147
00148
00149
00150 bool vu1112112::readRaw(void)
00151 {
00152 dword len;
00153 ifstream in;
00154
00155 in.open(m_FileName, ios::in|ios::binary);
00156 if (!in.is_open()) return false;
00157
00158 in.seekg(0, ios::end);
00159 len = in.tellg();
00160 in.seekg(0, ios::beg);
00161
00162 in >> m_Dim1Size >> m_Dim2Size >> m_Dim3Size;
00163 if (in.fail()) return false;
00164 m_DataSize = m_Dim1Size*m_Dim2Size*m_Dim3Size;
00165
00166 m_Data = new byte[m_DataSize];
00167 in.read((char*)m_Data, m_DataSize);
00168 if (in.fail()) return false;
00169
00170 in.close();
00171
00172 bool ret = Grid.load_vol(m_Data,*this);
00173 if(ret)
00174 {
00175 if(imgbuf) delete [] imgbuf;
00176 imgbuf = NULL;
00177
00178 center=vuVector((float)m_Dim1Size/2,(float)m_Dim2Size/2,
00179 (float)m_Dim3Size/2);
00180 m_Camera->setPosition(center);
00181 m_Camera->translateXYZ(0,0,-(float)m_Dim1Size);
00182 m_Camera->init();
00183 setImageSize(320,200);
00184 }
00185 re_light = re_render = false;
00186
00187 pp_gradients = false;
00188 preprocess();
00189
00190 return true;
00191 }
00192
00193
00194
00195
00196
00197 void vu1112112::preprocess(void)
00198 {
00199
00200 if(!pp_gradients)
00201 {
00202 cout<<"computing normals..."<<endl;
00203 Grid.calculate_gradients();
00204 pp_gradients=true;
00205 }
00206
00207 cout<<"classifying..."<<endl;
00208
00209 #ifdef USE_VUTFUNC
00210 #elif defined(DO_POST_CLASSIFICATION)
00211 int data;
00212 for(data=0;data<256;data++)
00213 {
00214 float density=0;
00215 int m;
00216 TFLUT_scatt[data] = ColourType(0.0f);
00217 TFLUT_absor[data] = ColourType(0.0f);
00218 for(m=0;m<nummat;m++)
00219 {
00220 if (data>mat[m].low_th &&
00221 data<=mat[m].high_th )
00222 {
00223 int d =((mat[m].high_th + mat[m].low_th)>>1)-data;
00224 density = (.5f-(float)fabs((float)d/(mat[m].high_th
00225 -mat[m].low_th)))*2.f;
00226 }
00227 else density = 0.f;
00228 TFLUT_scatt[data] += mat[m].scattering*density;
00229 TFLUT_absor[data] += mat[m].absorption*density;
00230 }
00231 }
00232 #endif
00233
00234 Grid.classify(*this);
00235 cout << "shading..." << endl;
00236 Grid.shade(*this);
00237
00238 }
00239
00240
00241
00242 void vu1112112::shootRays(int xofs, int xinc, int yofs, int yinc)
00243 {
00244 vuColourXYZa xyza;
00245 vuColourRGBa rgba;
00246
00247
00248 ColourType col;
00249 ColourType ill(spimg.get_light());
00250 glBegin(GL_POINTS);
00251 int i,j;
00252 int w=m_Camera->getWidth();
00253 int h=m_Camera->getHeight();
00254 for(j=yofs;j<h && j>=0;j+=yinc)
00255 {
00256 for(i=xofs;i<w;i+=xinc)
00257 {
00258 vuSampleRay ray(m_Camera->getRay((float)i,(float)j));
00259 col = Cast(ray);
00260
00261 spimg.set_xy(i,h-j,col);
00262
00263 #if defined USE_RGBA
00264
00265
00266
00267 xyza.from(col);
00268
00269 rgba.from(xyza);
00270 rgba.clampTo01();
00271
00272 #elif defined USE_SPECTRUM9A
00273 col *= ill;
00274 col.to(rgba);
00275 rgba.clampTo01();
00276 #else
00277 col *= ill;
00278
00279
00280
00281 rgba.from(col);
00282 rgba.clampTo01();
00283 #endif
00284 if(m_DrawPreview)
00285 if(!yofs) {
00286
00287 rgba.glColor();
00288 glVertex2f(i,h-j);
00289 }
00290
00291 }
00292
00293 }
00294 glEnd();
00295
00296 re_light = true;
00297 }
00298
00299
00300 void vu1112112::run(int whatsup, void* data)
00301 {
00302
00303
00304 dword oddheight = (m_Camera->getHeight()-1);
00305 if(!(oddheight & 0x01)) oddheight--;
00306 if(whatsup)
00307 shootRays(0,1,oddheight,-2);
00308 else
00309 shootRays(0,1,0,2);
00310
00311 m_Mutex[whatsup].unlock();
00312 }
00313
00314
00315
00316
00317
00318
00319 void vu1112112::render(void)
00320 {
00321 vuVector pos = m_Camera->getPosition();
00322 vuVector dir = m_Camera->getLookAtVector();
00323
00324 if(re_render)
00325 {
00326 use_flat_absorption = true;
00327 #ifndef USE_VUTFUNC
00328 int m;
00329 for(m=0;m<nummat && use_flat_absorption;m++)
00330 use_flat_absorption = mat[m].flat_absorption;
00331 if(!use_flat_absorption) cout<<"using spectral absorption."<<endl;
00332 #else
00333 Grid.classify(*this);
00334 #endif
00335
00336 #ifdef SPRC_SINGLEPROCESS
00337 shootRays();
00338 #else
00339 m_Mutex[0].lock();
00340 m_Mutex[1].lock();
00341
00342 if(!startThread(0))
00343 shootRays();
00344 else startThread(1);
00345
00346 m_Mutex[0].lock();
00347 m_Mutex[1].lock();
00348 m_Mutex[0].unlock();
00349 m_Mutex[1].unlock();
00350 #endif
00351 spimg.create_black_mask();
00352 re_render = false;
00353 }
00354
00355 int mx,my;
00356 spimg.get_extents(mx,my);
00357
00358 if(re_light)
00359 {
00360
00361 if(mx&&my)
00362 {
00363 if(!imgbuf)
00364 imgbuf = new byte[3*mx*my];
00365
00366 if(!spimg.get_rgb(imgbuf,3*mx*my)) return;
00367 } else delete [] imgbuf;
00368 re_light = false;
00369 }
00370
00371
00372 if(imgbuf) {
00373 glRasterPos2i(0,0);
00374 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00375 glDrawPixels(mx, my, GL_RGB, GL_UNSIGNED_BYTE, (void*)imgbuf );
00376 }
00377 }
00378
00379
00380
00381
00382
00383 void vu1112112::initOpenGL(void)
00384 {
00385
00386 }
00387
00388
00389 ColourType vu1112112::Cast(vuSampleRay& Sray)
00390 {
00391
00392 Sray.SamplingDistance(1.0f);
00393 if(!Sray.attachToGrid(Grid)) return Background;
00394 ColourType colour(0.0f);
00395 ColourType aabsorption(1.0f);
00396 DatPnt sample;
00397 int steps=1;
00398 bool terminate = false;
00399
00400 while(!terminate && Sray.advanceRay())
00401 {
00402 if(m_DoSpecular)
00403 Sray.getSamplePointWithGradient(sample);
00404 else
00405 Sray.getSamplePoint(sample);
00406 if(!(sample.data == 0))
00407 {
00408
00409 bool matters, xray=false;
00410 #ifdef USE_VUTFUNC
00411 ColourType emissive(m_TFunc[sample.data]);
00412
00413 ColourType absorption(emissive.getAlpha());
00414 if(absorption[0] < 0.0001)
00415 matters = false;
00416 else
00417 matters = true;
00418 #elif defined(DO_POST_CLASSIFICATION)
00419 ColourType& emissive = TFLUT_scatt[sample.data];
00420 ColourType& absorption = TFLUT_absor[sample.data];
00421
00422 if(use_flat_absorption && absorption[0] < 0.001)
00423 matters = false;
00424 else
00425 matters = true;
00426 #else
00427 ColourType emissive(0.0f);
00428 ColourType absorption(0.0f);
00429 matters=false;
00430 int m;
00431 for(m=0;m<MAT_NUM_MATERIALS;m++)
00432 {
00433 if(sample.density[m] > 0.01)
00434 {
00435 emissive += mat[m].scattering*(sample.density[m]);
00436 if(use_flat_absorption)
00437 absorption[0] += mat[m].absorption[0]*
00438 (sample.density[m]);
00439 else
00440 absorption += mat[m].absorption*(sample.density[m]);
00441 matters=true;
00442 if(mat[m].xray) {
00443 xray=true;
00444 }
00445 }
00446 }
00447 #endif
00448 if(matters)
00449 {
00450 #ifdef USE_SMPDST
00451 if(use_flat_absorption)
00452 absorption[0] *= 1;
00453 else
00454 absorption *= Sray.SamplingDistance();
00455 #endif
00456
00457 if(m_DoSpecular && sample.length>1)
00458 {
00459
00460 vuVector h((float)sample.grad[0],
00461 (float)sample.grad[1],
00462 (float)sample.grad[2]);
00463 vuVector v(Sray.m_Direction);
00464 h*=h.dot(v);
00465 h*=(2.0/(128*128));
00466 vuVector r = v - h;
00467 r.makeUnit();
00468 float spec=r.dot(m_LightDir);
00469
00470
00471 if(spec>0)
00472 {
00473 spec=(float)pow((r.dot(m_LightDir)), m_Shininess);
00474 sample.illum += spec*m_Gloss;
00475 }
00476 }
00477
00478 if(use_flat_absorption) {
00479 colour += emissive*absorption[0]*aabsorption[0]*sample.illum;
00480 if(!xray)
00481 aabsorption[0] *= 1-absorption[0];
00482 } else {
00483 colour += emissive*absorption*aabsorption*sample.illum;
00484 if(!xray)
00485 aabsorption *= absorption.oneMinus();
00486 }
00487
00488 float mabso;
00489 if(use_flat_absorption)
00490 mabso = aabsorption[0];
00491 else
00492 mabso = aabsorption.maxComponent();
00493 if(mabso<0.05)
00494 {
00495
00496 terminate = true;
00497 }
00498
00499 }
00500 steps++;
00501 }
00502 }
00503 if(!terminate)
00504 if(use_flat_absorption)
00505 colour += Background*(aabsorption[0]);
00506 else
00507 colour += Background*(aabsorption);
00508 return colour;
00509 }
00510
00511 void vu1112112::setLight(const vuColour31a &light)
00512 {
00513 ColourType lc(light);
00514 spimg.set_light(lc);
00515 re_light = true;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 bool vu1112112::load_scene(const char *filename)
00536 {
00537 numlights = 0;
00538 nummat = 0;
00539 Parser parser;
00540 cout << "loading scene setup: "<<filename<<endl;
00541 if(!parser.Parse(filename, *this)) return false;
00542
00543
00544 preprocess();
00545 delete [] imgbuf;
00546 imgbuf = NULL;
00547 m_Camera->setPosition(center);
00548 m_Camera->translateXYZ(0,0,-(float)m_Dim1Size);
00549 m_Camera->init();
00550 return true;
00551 }
00552
00553 bool vu1112112::add_light(ColourType &lc)
00554 {
00555 if(numlights<NUM_LIGHTS)
00556 {
00557 m_Light[numlights++] = lc;
00558 return true;
00559 } else return false;
00560 }
00561
00562 bool vu1112112::add_material(Material &mat)
00563 {
00564 if(nummat<MAT_NUM_MATERIALS)
00565 {
00566 this->mat[nummat++] = mat;
00567 return true;
00568 } else return false;
00569 }
00570
00571 void vu1112112::doRefresh()
00572 {
00573 re_render = true;
00574 }
00575
00576 vuVector vu1112112::getCenter()
00577 {
00578 return center;
00579 }
00580
00581 vuImage* vu1112112::getImage ()
00582
00583 {
00584 rgbimg.set_data (imgbuf);
00585
00586 return &rgbimg;
00587 }
00588
00589 }