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
00012
00014 #define DO_EXPALPHA
00015
00018 #define EXPALPHA 3
00019 #define SHININESS 10
00020 #define GLOSS 0.2
00021
00022
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
00039
00040
00041 vu1112113::vu1112113(const vu1112113& inst) : vu111211(inst)
00042 {
00043 lightdir = inst.lightdir;
00044 }
00045
00046
00047
00048
00049
00050 vu1112113::~vu1112113()
00051 {
00052 if (m_Camera != NULL) {
00053 delete m_Camera;
00054 m_Camera = NULL;
00055 }
00056 }
00057
00058
00059
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
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
00100 m_Camera->init();
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 void vu1112113::initOpenGL(void)
00118 {
00119 glDisable(GL_LIGHTING);
00120 }
00121
00122
00123
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
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
00187
00188
00189 void vu1112113::preprocess(void)
00190 {
00191
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
00205
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
00220
00221
00222 void vu1112113::render(void)
00223 {
00224
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();
00237 m_Mutex[1].lock();
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
00253
00254
00255
00256
00257
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);
00282 }
00283
00284 }
00285 }
00286 glEnd();
00287 }
00288
00289
00290
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;
00300 float lastvalue = 0;
00301 while(!terminate && Sray.advanceRay())
00302 {
00303
00304
00305 float fdensity = Sray.getSamplePoint(sample, m_DoSpecular);
00306
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 }
00342 if(!terminate)
00343 colour += m_Background*aalpha;
00344 return colour;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
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
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