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

Raycast.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 #include <math.h>
00004 
00005 #include "vuColourRGBa.h"
00006 #include "vuCamera/vuParallelCamera.h"
00007 #include "vuCamera/vuPerspectiveCamera.h"
00008 
00009 #include "Raycast.h"
00010 
00011 //#define SPRC_SINGLEPROCESS    // force single process rendering
00012 
00014 #define DO_EXPALPHA
00015 
00018 #define EXPALPHA        3
00019 #define SHININESS       10
00020 #define GLOSS           0.2
00021 //----------------------------------------------------------------------------
00022 //------------------------- The default constructor --------------------------
00023 //----------------------------------------------------------------------------
00024 
00025 vu1112113::vu1112113() : lightdir(1,0,0), m_Specular(1,1,1,0)
00026 {
00027   m_Camera = new vuPerspectiveCamera();
00028   m_Camera->setHeight(240);
00029   m_Camera->setWidth(320);
00030   diffuse            = 1.f;
00031   brightness         = .5f;
00032   m_PreDraw          = false;
00033   m_DoSpecular       = false;
00034   m_SamplingDistance = 1.0f;
00035 }
00036 
00037 //----------------------------------------------------------------------------
00038 //------------------------- The copy constructor -----------------------------
00039 //----------------------------------------------------------------------------
00040 
00041 vu1112113::vu1112113(const vu1112113& inst) : vu111211(inst)
00042 {
00043   lightdir = inst.lightdir;
00044 }
00045 
00046 //----------------------------------------------------------------------------
00047 //------------------------- The destructor -----------------------------------
00048 //----------------------------------------------------------------------------
00049 
00050 vu1112113::~vu1112113()
00051 {
00052   if (m_Camera != NULL) {
00053     delete m_Camera;
00054     m_Camera = NULL;
00055   }
00056 }
00057 
00058 //----------------------------------------------------------------------------
00059 //------------------------- The assignment operator --------------------------
00060 //----------------------------------------------------------------------------
00061 
00062 vu1112113& vu1112113::operator=(const vu1112113& rhs)
00063 {
00064     if (this != &rhs)
00065     {
00066         vu111211::operator=(rhs);
00067     }
00068     m_rerendering = false;
00069     return *this;
00070 }
00071 
00072 //----------------------------------------------------------------------------
00073 void vu1112113::setImageSize(dword sx, dword sy)
00074 {
00075   if (m_Camera->getType() == vuCamera::vuPERSPECTIVE_CAMERA) {
00076     vuPerspectiveCamera *cptr = (vuPerspectiveCamera *)m_Camera;
00077     cptr->setAspect(float(sx)/sy);
00078   }
00079   m_Camera->setWidth(sx);
00080   m_Camera->setHeight(sy);
00081   m_Camera->init();
00082   m_Image.init(m_Camera->getWidth(),m_Camera->getHeight());
00083 }
00084 
00085 void vu1112113::getImageSize(dword &sx, dword &sy)
00086 {
00087   sx = m_Camera->getWidth();
00088   sy = m_Camera->getHeight();
00089 }
00090 
00091 //----------------------------------------------------------------------------
00092 //------------------------- public setViewVectors() --------------------------
00093 //----------------------------------------------------------------------------
00094 
00095 void vu1112113::setViewVectors(const vuVector& view,const vuVector& up,const vuVector& right)
00096 {
00097   m_Camera->setLookAtVector(view);
00098   m_Camera->setUpVector(up);
00099   // m_Camera->setRightVector(right);
00100   m_Camera->init();
00101 }
00102 
00103 /*
00104 void vu1112113::setViewVectors(const vuVector& pos,const vuVector& vrp,const vuVector& up)
00105 {
00106         m_Camera->setPosition(pos);
00107         m_Camera->setLookAtVector(pos+vrp);
00108         m_Camera->setUpVector(up);
00109         m_Camera->init();
00110 }
00111 */
00112 
00113 //----------------------------------------------------------------------------
00114 //------------------------- public initOpenGL() ------------------------------
00115 //----------------------------------------------------------------------------
00116 
00117 void vu1112113::initOpenGL(void)
00118 {
00119     glDisable(GL_LIGHTING);
00120 }
00121 
00122 //----------------------------------------------------------------------------
00123 //------------------------- public read() ------------------------------------
00124 //----------------------------------------------------------------------------
00125 
00126 bool vu1112113::read()
00127 {
00128     bool success = vu111211::read();
00129     if (!success) return false;
00130 
00131     m_Grid.copy_vol(m_Data, *this);
00132     center=vuVector((float)m_Dim1Size/2,(float)m_Dim2Size/2,(float)m_Dim3Size/2);
00133     m_Camera->setPosition(center);
00134     m_Camera->translateXYZ(0,0,-(float)m_Dim1Size);
00135     m_Camera->init();
00136 
00137     m_rerendering = false;
00138     pp_gradients  = false;
00139     preprocess();
00140     return true;
00141 }
00142 
00143 //----------------------------------------------------------------------------
00144 //------------------------- public readRaw() ---------------------------------
00145 //----------------------------------------------------------------------------
00146 
00147 bool vu1112113::readRaw(void)
00148 {
00149     dword len;
00150     ifstream in;
00151 
00152     in.open(m_FileName, ios::in|ios::binary
00153 #ifdef IS_NOCREATE_NEEDED
00154 |ios::nocreate
00155 #endif
00156 );
00157     if (!in.is_open()) return false;
00158 
00159     in.seekg(0, ios::end);
00160     len = in.tellg();
00161     in.seekg(0, ios::beg);
00162 
00163     in >> m_Dim1Size >> m_Dim2Size >> m_Dim3Size;
00164     if (in.fail()) return false;
00165     m_DataSize = m_Dim1Size*m_Dim2Size*m_Dim3Size;
00166 
00167     m_Data = new byte[m_DataSize];
00168     in.read((char *)m_Data, (int)m_DataSize);
00169     if (in.fail()) return false;
00170 
00171     in.close();
00172 
00173     m_Grid.copy_vol(m_Data, *this);
00174     center=vuVector((float)m_Dim1Size/2,(float)m_Dim2Size/2,(float)m_Dim3Size/2);
00175     m_Camera->setPosition(center);
00176     m_Camera->translateXYZ(0,0,-(float)m_Dim1Size);
00177     m_Camera->init();
00178     m_rerendering = false;
00179     pp_gradients  = false;
00180     preprocess();
00181 
00182     return true;
00183 }
00184 
00185 //----------------------------------------------------------------------------
00186 //------------------------- private preprocess() -----------------------------
00187 //----------------------------------------------------------------------------
00188 
00189 void vu1112113::preprocess(void)
00190 {
00191   // compute normals
00192   if(!pp_gradients)
00193     {
00194       cout<<"computing normals..."<<endl;
00195       m_Grid.calculate_gradients();
00196       m_Grid.shade(*this);
00197       pp_gradients=true;
00198     }
00199 }
00200 
00201 //----------------------------------------------------------------------------
00202 void vu1112113::run(int whatsup, void* data)
00203 {
00204   //cout<<"running as "<<whatsup<<endl;
00205   //shootRays(whatsup,2);
00206   dword oddheight = m_Camera->getHeight()-1;
00207 
00208   if(!(oddheight & 0x01)) oddheight--;
00209   if(whatsup)
00210     shootRays(0,1,oddheight,-2);
00211   else
00212     shootRays(0,1,0,2);
00213   
00214   m_Mutex[whatsup].unlock();
00215 }
00216 
00217 
00218 //----------------------------------------------------------------------------
00219 //------------------------- public render() ----------------------------------
00220 //----------------------------------------------------------------------------
00221 
00222 void vu1112113::render(void)
00223 {
00224     //OpenGL is already prepared to draw 2D on an Ortho screen
00225   vuVector pos = m_Camera->getPosition();
00226   vuVector dir = m_Camera->getLookAtVector();
00227 
00228   if(m_rerendering)
00229     {
00230         m_TFuncPI = m_TFunc;
00231         
00232         
00233 #ifdef SPRC_SINGLEPROCESS
00234         shootRays();
00235 #else
00236         m_Mutex[0].lock();      // will be unlocked by thread 0
00237         m_Mutex[1].lock();      // will be unlocked by thread 1
00238         
00239         if(startThread(0))
00240         {
00241                 startThread(1);
00242         } else shootRays();
00243 
00244         m_Mutex[0].lock();
00245         m_Mutex[1].lock();
00246         m_Mutex[0].unlock();
00247         m_Mutex[1].unlock();
00248 #endif
00249         m_rerendering = false;
00250     }
00251 
00252   // This method is for computation only, not for displaying!!! -ms-
00253   //int mx,my;
00254   //m_Image.get_extents(mx,my);
00255   //copy to screen
00256   //if(mx && my) {
00257   //   m_Image.blit();
00258   //}
00259 }
00260 
00261 //----------------------------------------------------------------------------
00262 void vu1112113::shootRays(int xofs, int xinc, int yofs, int yinc)
00263 {
00264     m_Image.init(m_Camera->getWidth(), m_Camera->getHeight());
00265     int i,j;
00266     int w = m_Camera->getWidth();
00267     int h = m_Camera->getHeight();
00268     glBegin(GL_POINTS);
00269     for(j=yofs;j<h && j>=0;j+=yinc)
00270     {
00271         for(i=xofs;i<w;i+=xinc)
00272         {
00273             vuSampleRay ray(m_Camera->getRay((float)i,(float)j));
00274             vuColourRGBa col = Cast(ray);
00275             
00276             m_Image.set_xy(i,h-j, col);
00277 
00278             if(!yofs && m_PreDraw) {
00279                 col.clampTo01();
00280                 col.glColor();
00281                 glVertex2i(i,h-j);      // coordinate system is upside down
00282             }
00283             
00284         }
00285     }
00286     glEnd();
00287 }
00288 
00289 //----------------------------------------------------------------------------
00290 // Cast a ray through the grid
00291 vuColourRGBa vu1112113::Cast(vuSampleRay& Sray)
00292 {
00293         Sray.SamplingDistance(m_SamplingDistance);
00294         if(!Sray.attachToGrid(m_Grid)) return m_Background;
00295         vuColourRGBa colour(0.0f);
00296         int steps=1;
00297         bool terminate = false;
00298         DatPnt sample;
00299         float aalpha = 1;               // 1 - accumulated alpha
00300         float lastvalue = 0;
00301         while(!terminate && Sray.advanceRay())
00302         {
00303             // get the interpolated value
00304             //float fdensity = rint(Sray.getSamplePoint(sample, m_DoSpecular));
00305             float fdensity = Sray.getSamplePoint(sample, m_DoSpecular);
00306             //use the position information
00307             
00308             vuColourRGBa scol;
00309             if(m_TFuncMethod == TFUNC_SMP)
00310                 scol = m_TFunc[sample.data];
00311             else
00312                 m_TFuncPI.integrate(lastvalue,fdensity,m_SamplingDistance, scol);
00313             if(scol.getAlpha() > 0.001)
00314             {
00315 #ifdef DO_EXPALPHA
00316                 scol.setAlpha(1-exp(-scol.getAlpha()*m_SamplingDistance*EXPALPHA));
00317 #endif          
00318                 scol *= sample.illum;
00319                 if(m_DoSpecular && sample.len>2)
00320                 {
00321                     vuVector normal = sample.normalVec();
00322                     vuVector r(Sray.m_Direction);
00323                     r -=  2*normal*normal.dot(r);
00324                     r.makeUnit();
00325                     float spec=r.dot(lightdir);
00326                     if(spec>0)
00327                     {
00328                         spec=(float)pow((r.dot(lightdir)),SHININESS)*GLOSS;
00329                         scol += m_Specular*spec;
00330                     }
00331                 }
00332                 
00333                 colour += scol*(scol.getAlpha()*aalpha);
00334                 aalpha *= 1-scol.getAlpha();
00335                 
00336                 if(aalpha<0.05)
00337                     terminate = true;
00338             }
00339             steps++;
00340             lastvalue = fdensity;
00341         } //end of while
00342         if(!terminate) 
00343           colour += m_Background*aalpha;
00344         return colour;
00345 }
00346 
00347 /*
00348 void vu1112113::adjust_camera(float px, float py, float pz, float ux, float uy, float uz)
00349 {
00350   m_Camera->setPosition(vuVector(px,py,pz));
00351   m_Camera->setUpVector(vuVector(ux,uy,uz));
00352   m_Camera->Init();
00353 }
00354 
00355 bool vu1112113::get_extents(int &mx, int &my, int &mz)
00356 {
00357 
00358         mx = Grid.m_Dim1Size;
00359         my = Grid.m_Dim2Size;
00360         mz = Grid.m_Dim3Size;
00361         return true;
00362 }
00363 */
00364 
00365 void vu1112113::doRefresh()
00366 {
00367   m_rerendering = true;
00368 }
00369 
00370 vuVector vu1112113::getCenter() const
00371 {
00372   return center;
00373 }
00374 
00375 
00376 /*-------------------------------------------------
00377 Functions required by vuKeyFramer
00378 ---------------------------------------------------*/
00379 
00380 vuImage* vu1112113::getImage ()
00381 
00382 {
00383         return &m_Image;
00384 }
00385 
00386 void vu1112113::displayFromImage ()
00387 
00388 {
00389   int mx, my;
00390 
00391   m_Image.get_extents (mx, my);
00392 
00393   if(mx && my)
00394       m_Image.blit();
00395   else
00396     cout << "bad" << endl;
00397 }
00398 

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