Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

spectral.cpp

Go to the documentation of this file.
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 //------------------------- The default constructor --------------------------
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 //------------------------- The copy constructor -----------------------------
00054 //----------------------------------------------------------------------------
00055 
00056 vu1112112::vu1112112(const vu1112112& inst) : vu111211(inst)
00057 {
00058   operator=(inst);
00059 }
00060 
00061 //----------------------------------------------------------------------------
00062 //------------------------- The destructor -----------------------------------
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 //------------------------- The assignment operator --------------------------
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     //m_Camera->setFOV(...);
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 //------------------------- public setViewVectors() --------------------------
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 //------------------------- public read() ------------------------------------
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           //scale_light(.5f,.5f);
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 //------------------------- public readRaw() ---------------------------------
00148 //----------------------------------------------------------------------------
00149 
00150 bool vu1112112::readRaw(void)
00151 {
00152     dword len;
00153     ifstream in;
00154 
00155     in.open(m_FileName, ios::in|ios::binary); //|ios::nocreate);
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 //------------------------- private preprocess() -----------------------------
00195 //----------------------------------------------------------------------------
00196 
00197 void vu1112112::preprocess(void)
00198 {
00199   // compute normals
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                 }                                                               // maybe we apply other distributions here
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       //xyza.setNormalSpectrum(m_Light[0]); //HERE-- fixed scaling
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);  //coordinate system is upside down
00262               
00263 #if defined USE_RGBA
00264               //col.ClampTo01();
00265               //rgba = col;
00266               //*
00267               xyza.from(col);
00268               //xyza.Normalize();
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               //xyza.from(col);
00279               //xyza.normalize();
00280               //rgba.from(xyza);
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           //cout << "."<<flush;
00293         }
00294       glEnd();
00295       
00296       re_light = true;
00297 }
00298 
00299 //----------------------------------------------------------------------------
00300 void vu1112112::run(int whatsup, void* data)
00301 {
00302   //cout<<"running as "<<whatsup<<endl;
00303   //shootRays(whatsup,2);
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 //------------------------- public render() ----------------------------------
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         //copy to framebuffer
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   //copy to screen
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 //------------------------- public initOpenGL() ------------------------------
00381 //----------------------------------------------------------------------------
00382 
00383 void vu1112112::initOpenGL(void)
00384 {
00385   //glEnable(GL_SECRET_FEATURE);
00386 }
00387 
00388 // Cast a ray through the grid
00389 ColourType vu1112112::Cast(vuSampleRay& Sray)
00390 {
00391     //#define USE_SMPDST                //enable if smpdst != 1.0f OR NOT???
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             //use the position information
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;//Sray.SamplingDistance();
00453                 else
00454                     absorption *= Sray.SamplingDistance();
00455 #endif
00456                 
00457                 if(m_DoSpecular && sample.length>1)
00458                 {
00459                     //grad has length 128
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                     //adding specular contribution to voxel intensity
00470                     //the two values need to be adjusted...
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                     //cout<<"t";
00496                     terminate = true;
00497                 }
00498                 //#endif
00499             }
00500             steps++;
00501         } //end of if skipCell
00502     } //end of while
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 void vu1112112::adjust_camera(float px, float py, float pz, float ux, float uy, float uz)
00520 {
00521   m_Camera->setPosition(vuVector(px,py,pz));
00522   m_Camera->setUpVector(vuVector(ux,uy,uz));
00523   m_Camera->Init();
00524 }
00525 
00526 bool vu1112112::get_extents(int &mx, int &my, int &mz)
00527 {
00528 
00529         mx = Grid.maxX;
00530         my = Grid.maxY;
00531         mz = Grid.maxZ;
00532         return true;
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         //Grid.classify(*this);
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 } // end of namespace

Generated on Wed Dec 15 21:20:31 2004 for vuVolume by  doxygen 1.3.9.1