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

Volume/BCC/Unimodal/3d/1B/Intensity/Raycaster/raycaster.cpp

Go to the documentation of this file.
00001 //plain bcc raycaster
00002 #include <GL/gl.h>
00003 #include <fstream.h>
00004 #include <math.h>
00005 #include "vuParallelCamera.h"
00006 #include "vuPerspectiveCamera.h"
00007 
00008 #include "raycaster.h"
00009 
00012 #define DO_EXPALPHA
00013 
00016 #define EXPALPHA        3
00017 #define SHININESS       10
00018 #define GLOSS           0.2
00019 //----------------------------------------------------------------------------
00020 //------------------------- The default constructor --------------------------
00021 //----------------------------------------------------------------------------
00022 
00023 vu1512113::vu1512113() : m_LightDir(0,0,0), m_Specular(1,1,1,0)
00024 {
00025   m_Camera = new vuPerspectiveCamera();
00026   m_Camera->setHeight(240);
00027   m_Camera->setWidth(320);
00028   refresh = false;
00029   m_SamplingDistance = 1.0f;
00030 }
00031 
00032 //----------------------------------------------------------------------------
00033 //------------------------- The copy constructor -----------------------------
00034 //----------------------------------------------------------------------------
00035 
00036 vu1512113::vu1512113(const vu1512113& inst) : vu151211(inst)
00037 {
00038 }
00039 
00040 //----------------------------------------------------------------------------
00041 //------------------------- The destructor -----------------------------------
00042 //----------------------------------------------------------------------------
00043 
00044 vu1512113::~vu1512113()
00045 {
00046 }
00047 
00048 //----------------------------------------------------------------------------
00049 //------------------------- The assignment operator --------------------------
00050 //----------------------------------------------------------------------------
00051 
00052 vu1512113& vu1512113::operator=(const vu1512113& rhs)
00053 {
00054     if (this != &rhs)
00055     {
00056         vu151211::operator=(rhs);
00057 
00058     }
00059     return *this;
00060 }
00061 
00062 void vu1512113::setImageSize(int sx, int sy) 
00063 {
00064   if(m_Camera == NULL) {
00065       cerr << "no camera set" << endl;
00066       return;
00067   }
00068   if (m_Camera->getType() == vuCamera::vuPERSPECTIVE_CAMERA) {
00069     vuPerspectiveCamera *cptr = (vuPerspectiveCamera *)m_Camera;
00070     cptr->setAspect(float(sx)/sy);
00071   }
00072   m_Camera->setWidth(sx);
00073   m_Camera->setHeight(sy);
00074   m_Camera->init();
00075   m_Image.init(m_Camera->getWidth(),m_Camera->getHeight());
00076 }
00077 
00078 //----------------------------------------------------------------------------
00079 //------------------------- public setViewVectors() --------------------------
00080 //----------------------------------------------------------------------------
00081 
00082 void vu1512113::setViewVectors(const vuVector& view,const vuVector& up,const vuVector& right)
00083 {
00084 //     m_View = view;
00085 //     m_Shift1 = right*3.2f;
00086 //     m_Shift2 = up*3.2f;
00087 //     m_Shift0 = (m_Shift1+m_Shift2)*(-0.5f);
00088 
00089     // maybe we use the camera at some point (so far it's not used)
00090     m_Camera->setLookAtVector(view);
00091     m_Camera->setUpVector(up);
00092     m_Camera->setRightVector(right);
00093     m_Camera->init();
00094 }
00095 
00096 //----------------------------------------------------------------------------
00097 //------------------------- public read() ------------------------------------
00098 //----------------------------------------------------------------------------
00099 
00100 bool vu1512113::read()
00101 {
00102     bool success = vu151211::read();
00103     if (!success) return false;
00104 
00105     vuVector center(getCenter());
00106     m_Camera->setPosition(center);
00107     m_Camera->translateXYZ(0,0,-1.5f*(float)m_Dim1Size);
00108     m_Camera->init();
00109 
00110     preprocess();
00111     return true;
00112 }
00113 
00114 //----------------------------------------------------------------------------
00115 //------------------------- public readRaw() ---------------------------------
00116 //----------------------------------------------------------------------------
00117 
00118 bool vu1512113::readRaw(void)
00119 {
00120     dword len;
00121     ifstream in;
00122 
00123 #ifdef IS_NOCREATE_NEEDED
00124     in.open(m_FileName, ios::in|ios::binary|ios::nocreate);
00125 #else
00126         // The nocreate is not available on the IRIX boxes that we were compiling
00127         // this code on, so we had to remove this part from
00128     in.open(m_FileName, ios::in|ios::binary);
00129 #endif
00130 
00131     if (!in.is_open()) return false;
00132 
00133     in.seekg(0, ios::end);
00134     len = in.tellg();
00135     in.seekg(0, ios::beg);
00136 
00137     in >> m_Dim1Size >> m_Dim2Size >> m_Dim3Size;
00138     if (in.fail()) return false;
00139     m_DataSize = m_Dim1Size*m_Dim2Size*m_Dim3Size;
00140 
00141     m_Data = new byte[m_DataSize];
00142     in.read((char *) (m_Data), int (m_DataSize));
00143     if (in.fail()) return false;
00144 
00145     in.close();
00146 
00147     preprocess();
00148 
00149     return true;
00150 }
00151 
00152 //----------------------------------------------------------------------------
00153 //------------------------- private preprocess() -----------------------------
00154 //----------------------------------------------------------------------------
00155 
00156 void vu1512113::preprocess(void)
00157 {
00158   // compute normals
00159   cout<<"preprocessing..."<<endl;
00160 }
00161 
00162 //----------------------------------------------------------------------------
00163 //------------------------- public render() ----------------------------------
00164 //----------------------------------------------------------------------------
00165 
00166 void vu1512113::render(void)
00167 {
00168   if (refresh)
00169     {
00170         glClearColor(0.0,0.0,0.0,0);
00171         glClear(GL_COLOR_BUFFER_BIT);
00172       
00173 
00174       renderImage();
00175 
00176       refresh = false;
00177     }
00178   displayFromImage();
00179   glFlush();
00180 }
00181 
00182 //----------------------------------------------------------------------------
00183 //------------------------- public initOpenGL() ------------------------------
00184 //----------------------------------------------------------------------------
00185 
00186 void vu1512113::initOpenGL(void)
00187 {
00188   //glEnable(GL_SECRET_FEATURE);
00189 }
00190 
00191 //----------------------------------------------------------------------------
00192 //------------------------- private intersectRayWithBox() --------------------
00193 //----------------------------------------------------------------------------
00194 
00195 bool vu1512113::intersectRayWithBox(vuVector Ro, vuVector Rd, vuVector *f, vuVector *s, vuVector *llc, vuVector *urc)
00196 {
00197   double tnear=-1.7E308,tfar=1.7E308,t1,t2;
00198   
00199   Rd.makeUnit();
00200 
00201   //
00202   // intersect ray with X slab
00203   //
00204   
00205   if (Rd[0] == 0.0)     // ray is parallel to YZ-plane
00206     {
00207       if ((Ro[0] < (*llc)[0]) || (Ro[0] > (*urc)[0]))
00208         return false;  //ray does not intersect data set
00209     }
00210   else
00211     {
00212       t1=((*llc)[0]-Ro[0])/Rd[0];
00213       t2=((*urc)[0]-Ro[0])/Rd[0];
00214       
00215       if (t1 < t2)
00216         {
00217           tnear=t1;
00218           tfar=t2;
00219         }
00220       else
00221         {
00222           tnear=t2;
00223           tfar=t1;
00224         }
00225     }
00226   
00227   //
00228   // intersect ray with Y slab
00229   //
00230   
00231   if (Rd[1] == 0.0)     // ray is parallel to XZ-plane
00232     {
00233       if ((Ro[1] < (*llc)[1]) || (Ro[1] > (*urc)[1]))
00234         return false;   // ray does not intersect data set
00235     }
00236   else
00237     {
00238       t1=((*llc)[1]-Ro[1])/Rd[1];
00239       t2=((*urc)[1]-Ro[1])/Rd[1];
00240 
00241       if (t1 > t2)
00242         {
00243           double zw=t1;
00244           t1=t2;
00245           t2=zw;
00246         }
00247       
00248       if (t1 > tnear) tnear=t1;
00249       if (t2 < tfar)  tfar =t2;
00250       
00251       if (tfar < tnear)
00252           return false; // ray misses box
00253     }
00254   
00255   //
00256   // intersect ray with Z slab
00257   //
00258   
00259   if (Rd[2] == 0.0)     // ray is parallel to XY-plane
00260     {
00261       if ((Ro[2] < (*llc)[2]) || (Ro[2] > (*urc)[2]))
00262         return false; // ray does not intersect data set
00263     }
00264   else
00265     {
00266       t1=((*llc)[2]-Ro[2])/Rd[2];
00267       t2=((*urc)[2]-Ro[2])/Rd[2];
00268       
00269       if (t1 > t2)
00270         {
00271           double zw=t1;
00272           t1=t2;
00273           t2=zw;
00274         }
00275       
00276       if (t1 > tnear) tnear=t1;
00277       if (t2 < tfar)  tfar =t2;
00278       
00279       if (tfar < tnear)
00280           return false; // ray misses box
00281     }
00282 
00283   vuVector Rd1(Rd);
00284   Rd *= tnear;
00285   *f = Ro + Rd;
00286   Rd1 *= tnear;
00287   *s = Ro + Rd;
00288 
00289   //PNT3 f1, s1;
00290   //VEC3 Rd1;
00291   //CopyVEC3(&Rd1,&Rd);
00292   //
00293   //MulVEC3Scal(&Rd,tnear);
00294   //AddPNT3VEC3(&f1,&Ro,&Rd);
00295   //
00296   //MulVEC3Scal(&Rd1,tfar);
00297   //AddPNT3VEC3(&s1,&Ro,&Rd1);
00298   //
00299   //(*f)[0] = f1.x;
00300   //(*f)[1] = f1.y;
00301   //(*f)[2] = f1.z;
00302   //
00303   //(*s)[0] = s1.x;
00304   //(*s)[1] = s1.y;
00305   //(*s)[2] = s1.z;
00306 
00307   return true;
00308 }
00309 
00310 //----------------------------------------------------------------------------
00311 //------------------------- private renderImage() ----------------------------
00312 //----------------------------------------------------------------------------
00313 
00314 void vu1512113::renderImage()
00315 {
00316   if(m_Camera == NULL) {
00317       cerr << "no camera found" << endl;
00318       return;
00319   }
00320   m_Image.init(m_Camera->getWidth(), m_Camera->getHeight());
00321 
00322   bool usingCameraLight=false;
00323   if(m_LightDir.norm2() == 0.0f) {
00324       m_LightDir = m_Camera->getLookAtVector();
00325       usingCameraLight=true;
00326   }
00327 //  double pz = 1.3;  // pseudo-zoom
00328 //  float PI=3.14159265359;
00329   int XRES=m_Camera->getWidth();
00330   int YRES=m_Camera->getHeight();
00331   unsigned short maxx = m_Dim1Size, maxy = m_Dim2Size, maxz = m_Dim3Size;
00332 
00333   vuVector l(m_Camera->getLookAtVector());
00334   l.makeUnit();
00335 
00336   vuVector dataSetLowerBound(0.0f, 0.0f, 0.0f);
00337   vuVector dataSetUpperBound((float)maxx, (float)maxy, (float)maxz);
00338   //vuVector dataSetUpperBound(64.0, 64.0, 64.0);
00339 
00340   vuVector *dslb = &dataSetLowerBound;
00341   vuVector *dsub = &dataSetUpperBound;
00342 
00343   //
00344   // shoot ray through each pixel
00345   //
00346   glBegin(GL_POINTS);
00347   for (int i=0; i<XRES; i++)
00348     {
00349       for (int j=0; j<YRES; j++)
00350         {
00351           vuRay ray(m_Camera->getRay((float)i,(float)j));
00352           vuVector pos,pos2;
00353 
00354           double val = 0.0;
00355           vuColourRGBa colour(0.0);
00356           float aalpha = 1;             // 1 - accumulated alpha
00357           // traverse ray
00358           if (intersectRayWithBox(ray.m_Position, ray.m_Direction, &pos, &pos2, dslb, dsub))
00359           {
00360               ray.m_Position = pos;
00361               ray.advance();
00362               bool terminate=false;
00363               while ( (ray.m_Position[0] <= (*dsub)[0]) && (ray.m_Position[0] >= (*dslb)[0]) &&
00364                       (ray.m_Position[1] <= (*dsub)[1]) && (ray.m_Position[1] >= (*dslb)[1]) &&
00365                       (ray.m_Position[2] <= (*dsub)[2]) && (ray.m_Position[2] >= (*dslb)[2]) && 
00366                       !terminate )
00367               {
00368                   val =getDataValue(ray.m_Position);
00369                   vuColourRGBa scol = m_TFunc[(int)val]; // sample colour
00370                   vuVector grad = getGradient(ray.m_Position);
00371                   grad.makeUnit();
00372                   
00373                   if(scol.getAlpha() > 0.001)
00374                   {
00375 #ifdef DO_EXPALPHA
00376                       scol.setAlpha(1-exp(-scol.getAlpha()*m_SamplingDistance*EXPALPHA));
00377 #endif    
00378                       // diffuse
00379                       float diffuse = grad.dot(m_LightDir);
00380                       if(diffuse<0.0f) { // two sided lighting
00381                           diffuse=-diffuse;
00382                           grad*=-1.0f;
00383                       }
00384                       scol *= diffuse;
00385                       
00386                       //do we always want to compute specular?
00387                       vuVector r(ray.m_Direction);
00388                       r -=  2*grad*grad.dot(r);
00389                       r.makeUnit();
00390                       float spec=r.dot(m_LightDir);
00391                       if(spec>0)
00392                       {
00393                           spec=(float)pow((r.dot(m_LightDir)),SHININESS)*GLOSS;
00394                           scol += m_Specular*spec;
00395                       }
00396                           
00397                       colour += scol*(scol.getAlpha()*aalpha);
00398                       aalpha *= 1-scol.getAlpha();
00399                       
00400                       if(aalpha<0.05)
00401                           terminate = true;
00402                   }
00403                   ray.advance();
00404               }
00405           }
00406           
00407           m_Image.set_xy(i,YRES-j, colour);
00408           //colour.glColor();
00409           //glVertex2f(i,YRES-j);
00410         }
00411       //printf("row %d\n",i);
00412       cout << "." << flush;
00413     }
00414     glEnd();
00415     if(usingCameraLight)
00416         m_LightDir = 0.0;
00417     cout << " done" << endl;
00418 }
00419 
00420 void vu1512113::displayFromImage ()
00421 
00422 {
00423   int mx, my;
00424 
00425   m_Image.get_extents (mx, my);
00426 
00427   if(mx && my)
00428       m_Image.blit();
00429   else
00430     cout << "bad" << endl;
00431 }

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