00001 #include "Scanner.h"
00002 #include <iostream>
00003 #include <stdio.h>
00004 #include <math.h>
00005 #include "General/vuLinAlg/vuVector.h"
00006 #include "General/vuCamera/vuParallelCamera.h"
00007 #include "vuLightfield/Converter/vuSphericLightfieldFile.h"
00008 #include <GL/gl.h>
00009 #include <GL/glut.h>
00010
00011
00012
00013
00014
00015 Scanner::Scanner(const char *fileName, dword width, dword height, dword views)
00016 {
00017 m_Width = width;
00018 m_Height = height;
00019 m_Views = views;
00020
00021 cerr << "calculate view directions..." << endl;
00022
00023 m_Sphere = new vuUDSphere(views);
00024 m_Sphere->lazyCalculate();
00025
00026 cerr << "initialize raycaster..." << endl;
00027
00028 m_Raycast = new vu1112113();
00029 m_Raycast->setFileName(fileName);
00030 _initTransferFunction();
00031 m_Raycast->doPreviewDraw(false);
00032 m_Raycast->doSpecular(false);
00033
00034 m_Raycast->read();
00035 m_Raycast->initOpenGL();
00036
00037
00038 vuParallelCamera *camera = new vuParallelCamera;
00039 m_Raycast->setCamera(camera);
00040
00041 camera->setXRange(int(m_Raycast->getDim1Size()*1.0));
00042 camera->setYRange(int(m_Raycast->getDim2Size()*1.0));
00043
00044 m_Raycast->setImageSize(width, height);
00045
00046 m_Raycast->setSamplingDistance(0.5);
00047 m_Raycast->setTFuncMethod(TFUNC_PIAW);
00048 m_isComputed = false;
00049 }
00050
00051 Scanner::~Scanner()
00052 {
00053 if (m_Raycast != NULL) delete m_Raycast;
00054 if (m_Sphere != NULL) delete m_Sphere;
00055 }
00056
00057 void Scanner::loadTFuncFromFile(const char *fileName)
00058 {
00059 cerr << "........ load transfer function" << endl;
00060 try {
00061 if (m_TransFunct.loadTF(fileName)) {
00062 m_TransFunct.generateFunction();
00063 m_Raycast->setTransferFunc(m_TransFunct);
00064 }
00065 else
00066 cerr << "Warning: could not load TFunc form '" << fileName <<"'"<< endl;
00067 }
00068 catch (const char *msg) {
00069 cerr << msg << endl;
00070 }
00071 }
00072
00073 void Scanner::lazyCalculateAndDisplay(const char *fileName)
00074 {
00075 _lazyCalculate(fileName, true);
00076 }
00077
00078 void Scanner::lazyCalculateAndLog(const char *fileName)
00079 {
00080 _lazyCalculate(fileName, false);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 void Scanner::_initTransferFunction()
00090 {
00091 m_TransFunct.addOpacity(1,0.01);
00092 m_TransFunct.addOpacity(11,0.01);
00093 m_TransFunct.addOpacity(12,1);
00094 m_TransFunct.addOpacity(32,1);
00095 m_TransFunct.addColour(1,vuColourRGBa(0.f));
00096 m_TransFunct.addColour(11,vuColourRGBa(1.f));
00097 m_TransFunct.addColour(32,vuColourRGBa(0.f,0.f,0.6f));
00098 m_TransFunct.setOpacitySmoothing(0);
00099 m_TransFunct.setColourSmoothing(0);
00100
00101 m_TransFunct.generateFunction();
00102 m_Raycast->setTransferFunc(m_TransFunct);
00103 }
00104
00105
00106
00107
00108
00109
00110 void Scanner::_renderView(dword idx, vuSphericView3B *view, bool verbose)
00111 {
00112 Point3d point = m_Sphere->getPointAt(idx);
00113 vuParallelCamera *camera = NULL;
00114 vuVector lookAt(point.x, point.y, point.z);
00115 vuVector up(0,1,0);
00116 vuVector right;
00117
00118
00119 camera = (vuParallelCamera *)m_Raycast->getCameraPtr();
00120 lookAt.makeUnit();
00121 lookAt *= -1;
00122
00123 vuVector pos = m_Raycast->getCenter() - (lookAt * 1000);
00124 _calcViewVectors(lookAt, up, right);
00125
00126 camera->setPosition(pos);
00127 camera->setRightVector(right);
00128 camera->setUpVector(up);
00129 camera->setLookAtVector(lookAt);
00130
00131 try{
00132 camera->init();
00133 }
00134 catch(const char *msg) {
00135 cerr << "catched exception" << endl;
00136 cerr << msg << endl;
00137 }
00138
00139
00140 if (verbose) {
00141 cerr << "render view: ";
00142 cerr.width(_numberOfDigits(m_Views - 1));
00143 cerr << idx << " ";
00144 }
00145
00146 m_Raycast->doRefresh();
00147 m_Raycast->render();
00148
00149
00150 byte *dest = view->getMap()->getBuffer();
00151 const byte *src = m_Raycast->getImage()->get_rgb();
00152
00153 for (dword i = 3 * m_Width * m_Height; i>0; i--) *(dest++) = *(src++);
00154
00155 view->setLookFrom(vuVector(point.x, point.y, point.z));
00156 view->setUp(up);
00157 cerr << "Done." << endl;
00158 }
00159
00160 word Scanner::_numberOfDigits(word number)
00161 {
00162 if (number > 9999) return 5;
00163 if (number > 999) return 4;
00164 if (number > 99) return 3;
00165 if (number > 9) return 2;
00166
00167 return 1;
00168 }
00169
00170 void Scanner::_lazyCalculate(const char *fileName, bool display)
00171 {
00172 if (!m_isComputed) {
00173 vuSphericLightfieldFile3B *outFile = NULL;
00174 vuSphericView3B *view = new vuSphericView3B(m_Width, m_Height);
00175
00176 outFile = new vuSphericLightfieldFile3B(m_Width,m_Height,m_Views,fileName);
00177
00178 outFile->open();
00179 outFile->writeHeader();
00180
00181 if (display) {
00182 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00183 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00184 glutSwapBuffers();
00185 }
00186
00187 for (dword i=0; i<m_Views; i++) {
00188 if (display) {
00189 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00190 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00191 }
00192
00193 _renderView(i, view);
00194 outFile->writeView(view);
00195
00196 if (display) {
00197 view->getMap()->glRender();
00198 glutSwapBuffers();
00199 }
00200 }
00201 outFile->close();
00202 CHECKNDELETE(view);
00203 CHECKNDELETE(outFile);
00204 m_isComputed = true;
00205 }
00206 }
00207
00208 void Scanner::_calcViewVectors(vuVector& lookAt, vuVector& up, vuVector& right)
00209 {
00210 lookAt.makeUnit();
00211
00212 if (fabs(lookAt.dot(up)) > 0.999) up = vuVector(0,0,1).makeUnit();
00213
00214 up = (up - (lookAt.dot(up) * lookAt)).makeUnit();
00215 right = up.cross(lookAt).makeUnit() * -1;
00216 }