Changeset 1145


Ignore:
Timestamp:
07/24/06 10:12:34 (18 years ago)
Author:
mattausch
Message:

vsposp debug version

Location:
GTP/trunk/Lib/Vis
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj

    r1138 r1145  
    164164                        </File> 
    165165                        <File 
    166                                 RelativePath="..\src\GlRenderer.cpp"> 
    167                         </File> 
    168                         <File 
    169                                 RelativePath="..\src\GlRenderer.h"> 
    170                                 <FileConfiguration 
    171                                         Name="Release|Win32"> 
    172                                         <Tool 
    173                                                 Name="VCCustomBuildTool" 
    174                                                 Description="Performing moc on $(InputName).h" 
    175                                                 CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp 
    176 " 
    177                                                 Outputs="$(InputDir)moc_$(InputName).cpp"/> 
    178                                 </FileConfiguration> 
    179                         </File> 
    180                         <File 
    181166                                RelativePath="..\src\GzBinFileInputStream.cpp"> 
    182167                        </File> 
     
    246231                        <File 
    247232                                RelativePath="..\src\MeshKdTree.h"> 
    248                         </File> 
    249                         <File 
    250                                 RelativePath="..\src\moc_GlRenderer.cpp"> 
    251                         </File> 
    252                         <File 
    253                                 RelativePath="..\src\moc_Preprocessor.cpp"> 
    254                         </File> 
    255                         <File 
    256                                 RelativePath="..\src\moc_PreprocessorThread.cpp"> 
    257233                        </File> 
    258234                        <File 
     
    356332                        </File> 
    357333                        <File 
    358                                 RelativePath="..\src\Renderer.cpp"> 
    359                         </File> 
    360                         <File 
    361                                 RelativePath="..\src\Renderer.h"> 
    362                         </File> 
    363                         <File 
    364334                                RelativePath="..\src\RenderSampler.cpp"> 
    365335                        </File> 
     
    548518                        <File 
    549519                                RelativePath="..\include\ViewCell.h"> 
     520                        </File> 
     521                </Filter> 
     522                <Filter 
     523                        Name="Renderer" 
     524                        Filter=""> 
     525                        <File 
     526                                RelativePath="..\src\GlRenderer.cpp"> 
     527                        </File> 
     528                        <File 
     529                                RelativePath="..\src\GlRenderer.h"> 
     530                        </File> 
     531                        <File 
     532                                RelativePath="..\src\QtGlRenderer.cpp"> 
     533                        </File> 
     534                        <File 
     535                                RelativePath="..\src\QtGlRenderer.h"> 
     536                        </File> 
     537                        <File 
     538                                RelativePath="..\src\Renderer.cpp"> 
     539                        </File> 
     540                        <File 
     541                                RelativePath="..\src\Renderer.h"> 
    550542                        </File> 
    551543                </Filter> 
  • GTP/trunk/Lib/Vis/Preprocessing/scripts/TestPreprocessor.vcproj

    r1077 r1145  
    7070                        <Tool 
    7171                                Name="VCCLCompilerTool" 
    72                                 AdditionalIncludeDirectories="..\include;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\QtOpenGl&quot;;..\src;&quot;$(CG_INC_PATH)&quot;;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces" 
     72                                AdditionalIncludeDirectories="..\include;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include&quot;;&quot;$(BOOST_INCLUDE)&quot;;&quot;$(QTDIR)\include\QtOpenGl&quot;;..\src;&quot;$(CG_INC_PATH)&quot;;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces" 
    7373                                PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" 
    7474                                RuntimeLibrary="2" 
     
    8585                                OutputFile="$(OutDir)/Preprocessor.exe" 
    8686                                LinkIncremental="1" 
    87                                 AdditionalLibraryDirectories="..\support\xercesc\lib\;..\support\zlib\lib\;..\support\devil\lib;&quot;$(QTDIR)\lib&quot;;..\include;..\src\GL;&quot;$(CG_LIB_PATH)&quot;;&quot;$(GTPDIR)\NonGTP\Xerces&quot;;&quot;$(GTPDIR)\NonGTP\Xerces\xercesc\lib&quot;;&quot;$(GTPDIR)\NonGTP\zlib\lib&quot;;&quot;$(GTPDIR)\NonGTP\Devil\lib&quot;;..\lib\release;..\..\Preprocessing\lib\release" 
     87                                AdditionalLibraryDirectories="..\support\xercesc\lib\;..\support\zlib\lib\;..\support\devil\lib;&quot;$(QTDIR)\lib&quot;;..\include;..\src\GL;&quot;$(CG_LIB_PATH)&quot;;&quot;$(GTPDIR)\NonGTP\Xerces&quot;;&quot;$(GTPDIR)\NonGTP\Xerces\xercesc\lib&quot;;&quot;$(GTPDIR)\NonGTP\zlib\lib&quot;;&quot;$(GTPDIR)\NonGTP\Devil\lib&quot;;..\lib\release;..\..\Preprocessing\lib\release;&quot;$(BOOST_LIB)&quot;" 
    8888                                GenerateDebugInformation="FALSE" 
    8989                                SubSystem="1" 
  • GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp

    r1141 r1145  
    2323namespace GtpVisibilityPreprocessor { 
    2424 
    25 static CGcontext sCgContext = NULL; 
    26 static CGprogram sCgFragmentProgram = NULL; 
    27 static CGprofile sCgFragmentProfile; 
    28  
     25 
     26/* 
    2927GLuint frontDepthMap; 
    3028GLuint backDepthMap; 
    3129 
    3230const int depthMapSize = 512; 
    33 static vector<OcclusionQuery *> sQueries; 
    34  
    35 GlRendererWidget *rendererWidget = NULL; 
    36 GlDebuggerWidget *debuggerWidget = NULL; 
     31 
     32//static vector<OcclusionQuery *> sQueries; 
     33*/ 
    3734 
    3835static bool arbQuerySupport = false; 
     
    10198{ 
    10299  cerr<<"gl renderer destructor..\n"; 
    103   if (sCgFragmentProgram) 
    104         cgDestroyProgram(sCgFragmentProgram); 
    105   if (sCgContext) 
    106         cgDestroyContext(sCgContext); 
     100  
     101  //CLEAR_CONTAINER(sQueries); 
     102  CLEAR_CONTAINER(mOcclusionQueries); 
     103 
    107104  cerr<<"done."<<endl; 
    108     
    109   CLEAR_CONTAINER(sQueries); 
    110   CLEAR_CONTAINER(mOcclusionQueries); 
    111 } 
    112  
    113  
    114 static void handleCgError()  
    115 { 
    116     Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl; 
    117     exit(1); 
    118 } 
     105} 
     106 
    119107 
    120108void 
     
    264252  glEnable(GL_CULL_FACE); 
    265253   
    266   // HACK!! but using glew keeps crashing for some reason ... 
    267254  InitExtensions(); 
    268255   
     
    328315} 
    329316 
    330 void 
    331 GlRendererWidget::RenderInfo() 
    332 { 
    333   QString s; 
    334   int vc = 0; 
    335   if (mViewCellsManager) 
    336         vc = mViewCellsManager->GetViewCells().size(); 
    337   int filter = 0; 
    338   if (mViewCellsManager) 
    339         filter = mViewCellsManager->GetMaxFilterSize(); 
    340  
    341   s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f) viewcells:%04d filter:%04d pvs:%04d error:%5.5f\%", 
    342                         mFrame, 
    343                         mViewPoint.x, 
    344                         mViewPoint.y, 
    345                         mViewPoint.z, 
    346                         mViewDirection.x, 
    347                         mViewDirection.y, 
    348                         mViewDirection.z, 
    349                         vc, 
    350  
    351                         filter, 
    352                         mPvsSize, 
    353                         mRenderError*100.0f 
    354                         ); 
    355    
    356   glColor3f(0.0f,0.0f,0.0f); 
    357   renderText(0,20,s); 
    358    
    359   if (mShowRenderCost) { 
    360         static vector<float> costFunction; 
    361         static float maxCost = -1; 
    362         if (costFunction.size()==0) { 
    363           ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree(); 
    364           if (tree) { 
    365                 tree->GetCostFunction(costFunction); 
    366                 maxCost = -1; 
    367                 for (int i=0;  i < costFunction.size(); i++) { 
    368                   //              cout<<i<<":"<<costFunction[i]<<" "; 
    369                   if (costFunction[i] > maxCost) 
    370                         maxCost = costFunction[i]; 
    371                 } 
    372           } 
    373         } 
    374  
    375          
    376         int currentPos = mViewCellsManager->GetViewCells().size(); 
    377         float currentCost=-1; 
    378  
    379         if (currentPos < costFunction.size()) 
    380           currentCost = costFunction[currentPos]; 
    381 #if 0    
    382         cout<<"costFunction.size()="<<costFunction.size()<<endl; 
    383         cout<<"CP="<<currentPos<<endl; 
    384         cout<<"MC="<<maxCost<<endl; 
    385         cout<<"CC="<<currentCost<<endl; 
    386 #endif 
    387         if (costFunction.size()) { 
    388           glDisable(GL_DEPTH_TEST); 
    389           // init ortographic projection 
    390           glMatrixMode(GL_PROJECTION); 
    391           glPushMatrix(); 
    392            
    393           glLoadIdentity(); 
    394           gluOrtho2D(0, 1.0f, 0, 1.0f); 
    395            
    396           glTranslatef(0.1f, 0.1f, 0.0f); 
    397           glScalef(0.8f, 0.8f, 1.0f); 
    398           glMatrixMode(GL_MODELVIEW); 
    399           glLoadIdentity(); 
    400            
    401           glColor3f(1.0f,0,0); 
    402           glBegin(GL_LINE_STRIP); 
    403           //      glVertex3f(0,0,0); 
    404            
    405           for (int i=0;  i < costFunction.size(); i++) { 
    406                 float x =  i/(float)costFunction.size(); 
    407                 float y = costFunction[i]/(maxCost*0.5f); 
    408                 glVertex3f(x,y,0.0f); 
    409           } 
    410           glEnd(); 
    411            
    412           glColor3f(1.0f,0,0); 
    413           glBegin(GL_LINES); 
    414           float x =  currentPos/(float)costFunction.size(); 
    415           glVertex3f(x,0.0,0.0f); 
    416           glVertex3f(x,1.0f,0.0f); 
    417           glEnd(); 
    418            
    419           glColor3f(0.0f,0,0); 
    420           // show a grid 
    421           glBegin(GL_LINE_LOOP); 
    422           glVertex3f(0,0,0.0f); 
    423           glVertex3f(1,0,0.0f); 
    424           glVertex3f(1,1,0.0f); 
    425           glVertex3f(0,1,0.0f); 
    426           glEnd(); 
    427  
    428           glBegin(GL_LINES); 
    429           for (int i=0;  i < 50000 && i < costFunction.size(); i+=10000) { 
    430                 float x =  i/(float)costFunction.size(); 
    431                 glVertex3f(x,0.0,0.0f); 
    432                 glVertex3f(x,1.0f,0.0f); 
    433           } 
    434  
    435           for (int i=0;  i < maxCost; i+=100) { 
    436                 float y = i/(maxCost*0.5f); 
    437                 glVertex3f(0,y,0.0f); 
    438                 glVertex3f(1,y,0.0f); 
    439           } 
    440  
    441           glEnd(); 
    442  
    443            
    444           // restore the projection matrix 
    445           glMatrixMode(GL_PROJECTION); 
    446           glPopMatrix(); 
    447           glMatrixMode(GL_MODELVIEW); 
    448           glEnable(GL_DEPTH_TEST); 
    449  
    450         } 
    451   } 
    452 } 
    453  
    454317 
    455318void 
     
    477340                        target.x, target.y, target.z, 
    478341                        up.x, up.y, up.z); 
     342} 
     343 
     344void 
     345GlRenderer::_RenderScene() 
     346{ 
     347  ObjectContainer::const_iterator oi = mObjects.begin(); 
     348 
     349  for (; oi != mObjects.end(); oi++) 
     350        RenderIntersectable(*oi); 
     351} 
     352 
     353bool 
     354GlRenderer::RenderScene() 
     355{ 
     356  static int glList = -1; 
     357  if (mUseGlLists) { 
     358        if (glList == -1) { 
     359          glList = glGenLists(1); 
     360          glNewList(glList, GL_COMPILE); 
     361          _RenderScene(); 
     362          glEndList(); 
     363        } 
     364        glCallList(glList); 
     365  } else 
     366        _RenderScene(); 
     367         
     368   
     369  return true; 
    479370} 
    480371 
     
    507398} 
    508399 
    509 //std::ofstream outfile("try_arb.txt"); 
     400 
     401 
     402/****************************************************************/ 
     403/*               GlRendererBuffer implementation                */ 
     404/****************************************************************/ 
     405 
     406 
     407 
     408GlRendererBuffer::GlRendererBuffer(SceneGraph *sceneGraph, 
     409                                                                   ViewCellsManager *viewcells, 
     410                                                                   KdTree *tree): 
     411GlRenderer(sceneGraph, viewcells, tree)   
     412{ 
     413        mPixelBuffer = NULL; 
     414 
     415        // implement width and height in subclasses 
     416} 
     417 
     418 
    510419void 
    511420GlRendererBuffer::EvalQueryWithOcclusionQueries( 
     
    604513 
    605514void 
    606 GlRendererBuffer::EvalRenderCostSample(RenderCostSample &sample, 
    607                                                                            const bool useOcclusionQueries, 
    608                                                                            const int threshold 
    609                                                                            ) 
    610 { 
    611         // choose a random view point 
    612         mViewCellsManager->GetViewPoint(mViewPoint); 
    613         sample.mPosition = mViewPoint; 
    614         //cout << "viewpoint: " << mViewPoint << endl; 
    615  
    616         // take a render cost sample by rendering a cube 
    617         Vector3 directions[6]; 
    618  
    619         directions[0] = Vector3(1,0,0); 
    620         directions[1] = Vector3(0,1,0); 
    621         directions[2] = Vector3(0,0,1); 
    622         directions[3] = Vector3(-1,0,0); 
    623         directions[4] = Vector3(0,-1,0); 
    624         directions[5] = Vector3(0,0,-1); 
    625  
    626         sample.mVisibleObjects = 0; 
    627  
    628         // reset object counters 
    629         ObjectContainer::const_iterator it, it_end = mObjects.end(); 
    630  
    631         for (it = mObjects.begin(); it != it_end; ++ it)  
    632         { 
    633                 (*it)->mCounter = 0; 
    634         } 
    635  
    636         ++ mFrame; 
    637  
    638         //glCullFace(GL_FRONT); 
    639         glCullFace(GL_BACK); 
    640         glDisable(GL_CULL_FACE); 
    641          
    642  
    643         // query all 6 directions for a full point sample 
    644         for (int i = 0; i < 6; ++ i)  
    645         { 
    646                 mViewDirection = directions[i]; 
    647                 SetupCamera(); 
    648  
    649                 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
    650                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    651                 //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);      glDepthMask(GL_TRUE); 
    652                 glDepthFunc(GL_LESS); 
    653  
    654                 mUseFalseColors = true; 
    655  
    656                 // the actual scene rendering fills the depth (for occlusion queries) 
    657                 // and the frame buffer (for item buffer) 
    658                 RenderScene(); 
    659  
    660  
    661                 if (0)  
    662                 { 
    663                         char filename[256]; 
    664                         sprintf(filename, "snap/frame-%04d-%d.png", mFrame, i); 
    665                         QImage im = toImage(); 
    666                         im.save(filename, "PNG"); 
    667                 } 
    668           
    669                 // evaluate the sample 
    670                 if (useOcclusionQueries)  
    671                 { 
    672                         EvalQueryWithOcclusionQueries(); 
    673                 } 
    674                 else  
    675                 { 
    676                         EvalQueryWithItemBuffer(); 
    677                 } 
    678         }   
    679  
    680         // now evaluate the statistics over that sample 
    681         // currently only the number of visible objects is taken into account 
    682         sample.Reset(); 
    683  
    684         for (it = mObjects.begin(); it != it_end; ++ it)  
    685         { 
    686                 Intersectable *obj = *it; 
    687                 if (obj->mCounter >= threshold)  
    688                 { 
    689                         ++ sample.mVisibleObjects; 
    690                         sample.mVisiblePixels += obj->mCounter; 
    691                 } 
    692         } 
    693  
    694         //cout << "RS=" << sample.mVisibleObjects << " "; 
    695 } 
    696  
    697  
    698 void 
    699 GlRendererBuffer::SampleRenderCost(const int numSamples, 
    700                                                                    vector<RenderCostSample> &samples, 
    701                                                                    const bool useOcclusionQueries, 
    702                                                                    const int threshold 
    703                                                                    ) 
    704 { 
    705   makeCurrent(); 
    706  
    707   if (mPixelBuffer == NULL) 
    708           mPixelBuffer = new unsigned int[GetWidth()*GetHeight()]; 
    709    
    710   // using 90 degree projection to capture 360 view with 6 samples 
    711   SetupProjection(GetHeight(), GetHeight(), 90.0f); 
    712  
    713   //samples.resize(numSamples); 
    714   halton.Reset(); 
    715    
    716   // the number of queries queried in batch mode 
    717   const int numQ = 500; 
    718  
    719   //const int numQ = (int)mObjects.size(); 
    720   if (useOcclusionQueries) 
    721   { 
    722           cout << "\ngenerating " << numQ << " queries ... "; 
    723           OcclusionQuery::GenQueries(mOcclusionQueries, numQ); 
    724           cout << "finished" << endl; 
    725   } 
    726  
    727   // sampling queries  
    728   for (int i = 0; i < numSamples; ++ i) 
    729   { 
    730           cout << "."; 
    731           EvalRenderCostSample(samples[i], useOcclusionQueries, threshold); 
    732   } 
    733  
    734   doneCurrent(); 
    735  
    736 } 
    737    
    738  
    739 void 
    740515GlRendererBuffer::RandomViewPoint() 
    741516{  
     
    770545 
    771546 
    772 GlRendererBuffer::GlRendererBuffer(const int w, 
    773                                                                    const int h, 
    774                                                                    SceneGraph *sceneGraph, 
    775                                                                    ViewCellsManager *viewcells, 
    776                                                                    KdTree *tree): 
    777 QGLPixelBuffer(QSize(w, h)), GlRenderer(sceneGraph, viewcells, tree) { 
    778   
    779   Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", mPvsStatFrames); 
    780   mPvsErrorBuffer.resize(mPvsStatFrames); 
    781   ClearErrorBuffer(); 
    782  
    783   mPixelBuffer = NULL; 
    784    
    785   makeCurrent(); 
    786   InitGL(); 
    787   doneCurrent(); 
    788    
    789 } 
    790  
    791 float 
    792 GlRendererBuffer::GetPixelError(int &pvsSize) 
    793 { 
    794   float pErrorPixels = -1.0f; 
    795    
    796   glReadBuffer(GL_BACK); 
    797    
    798   //  mUseFalseColors = true; 
    799    
    800   mUseFalseColors = false; 
    801   unsigned int pixelCount; 
    802  
    803   //static int query = -1; 
    804   //if (query == -1) 
    805 //        glGenOcclusionQueriesNV(1, (unsigned int *)&query); 
    806  
    807   OcclusionQuery query; 
    808  
    809   if (mDetectEmptyViewSpace) { 
    810         // now check whether any backfacing polygon would pass the depth test 
    811         SetupCamera(); 
    812         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    813         glEnable( GL_CULL_FACE ); 
    814          
    815         RenderScene(); 
    816          
    817         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
    818         glDepthMask(GL_FALSE); 
    819         glDisable( GL_CULL_FACE ); 
    820  
    821          
    822         query.BeginQuery(); 
    823          
    824         RenderScene(); 
    825          
    826         query.EndQuery(); 
    827          
    828         // at this point, if possible, go and do some other computation 
    829         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    830         glDepthMask(GL_TRUE); 
    831         glEnable( GL_CULL_FACE ); 
    832          
    833         // reenable other state 
    834         pixelCount = query.GetQueryResult(); 
    835          
    836         if (pixelCount > 0) 
    837           return -1.0f; // backfacing polygon found -> not a valid viewspace sample 
    838   } else 
    839         glDisable( GL_CULL_FACE ); 
    840          
    841  
    842   ViewCell *viewcell = NULL; 
    843    
    844   PrVs prvs; 
    845    
    846   mViewCellsManager->SetMaxFilterSize(0); 
    847   mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth()); 
    848   viewcell = prvs.mViewCell; 
    849    
    850   //  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint); 
    851   pvsSize = 0; 
    852   if (viewcell) { 
    853         SetupCamera(); 
    854         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    855  
    856         glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); 
    857          
    858         // Render PVS 
    859         std::map<Intersectable *, 
    860           PvsData<Intersectable *>, 
    861           LtSample<Intersectable *> >::const_iterator it = viewcell->GetPvs().mEntries.begin(); 
    862  
    863         pvsSize = viewcell->GetPvs().mEntries.size(); 
    864          
    865         for (; it != viewcell->GetPvs().mEntries.end(); ++ it) { 
    866           Intersectable *object = (*it).first; 
    867           RenderIntersectable(object); 
    868         } 
    869  
    870         //      glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); 
    871         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    872         mUseFalseColors = true; 
    873  
    874         query.BeginQuery(); 
    875  
    876         SetupCamera(); 
    877  
    878         RenderScene(); 
    879          
    880         query.EndQuery(); 
    881          
    882  
    883         unsigned int pixelCount; 
    884         // reenable other state 
    885         pixelCount = query.GetQueryResult(); 
    886          
    887          
    888         pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight()); 
    889         if (mSnapErrorFrames && pErrorPixels > 0.01) { 
    890            
    891           char filename[256]; 
    892           sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels); 
    893           QImage im = toImage(); 
    894           im.save(mSnapPrefix + filename, "PNG"); 
    895           if (1) { //0 && mFrame == 1543) { 
    896                 int x,y; 
    897                 int lastIndex = -1; 
    898                 for (y=0; y < im.height(); y++) 
    899                   for (x=0; x < im.width(); x++) { 
    900                         QRgb p = im.pixel(x,y); 
    901                         int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16); 
    902                         if (qGreen(p) != 255 && index!=0) { 
    903                           if (index != lastIndex) { 
    904                                 //                              Debug<<"ei="<<index<<" "; 
    905                                 lastIndex = index; 
    906                           } 
    907                         } 
    908                   } 
    909           } 
    910  
    911  
    912           mUseFalseColors = false; 
    913           glPushAttrib(GL_CURRENT_BIT); 
    914           glColor3f(0,1,0); 
    915           glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    916           SetupCamera(); 
    917           glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    918            
    919           // Render PVS 
    920           std::map<Intersectable *, 
    921                 PvsData<Intersectable *>, 
    922                 LtSample<Intersectable *> >::const_iterator it = viewcell->GetPvs().mEntries.begin(); 
    923            
    924           for (; it != viewcell->GetPvs().mEntries.end(); ++ it) { 
    925                 Intersectable *object = (*it).first; 
    926                 RenderIntersectable(object); 
    927           } 
    928  
    929           im = toImage(); 
    930           sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels); 
    931           im.save(mSnapPrefix + filename, "PNG"); 
    932           glPopAttrib(); 
    933         } 
    934         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    935   } 
    936  
    937   if (viewcell && mViewCellsManager->GetMaxFilterSize() > 0) 
    938         mViewCellsManager->DeleteLocalMergeTree(viewcell); 
    939    
    940   return pErrorPixels; 
    941 } 
    942  
    943  
    944 void 
    945 GlRendererWidget::SetupProjection(const int w, const int h, const float angle) 
    946 { 
    947   if (!mTopView) 
    948         GlRenderer::SetupProjection(w, h, angle); 
    949   else { 
    950         glViewport(0, 0, w, h); 
    951         glMatrixMode(GL_PROJECTION); 
    952         glLoadIdentity(); 
    953         gluPerspective(50.0, 1.0, 0.1, 20.0*Magnitude(mSceneGraph->GetBox().Diagonal())); 
    954         glMatrixMode(GL_MODELVIEW); 
    955   } 
    956 } 
    957  
    958 void 
    959 GlRendererWidget::RenderPvs() 
    960 { 
    961   SetupCamera(); 
    962   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    963    
    964   ViewCell *viewcell = NULL; 
    965  
    966   PrVs prvs; 
    967    
    968   if (!mUseFilter) { 
    969         viewcell = mViewCellsManager->GetViewCell(mViewPoint, true); 
    970   } else { 
    971         //  mViewCellsManager->SetMaxFilterSize(1); 
    972         mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth()); 
    973         viewcell = prvs.mViewCell; 
    974   } 
    975    
    976   if (viewcell) { 
    977         // copy the pvs so that it can be filtered... 
    978         ObjectPvs pvs = viewcell->GetPvs(); 
    979  
    980         if (mUseSpatialFilter) { 
    981           mViewCellsManager->ApplySpatialFilter(mKdTree, 
    982                                                                                         mSpatialFilterSize* 
    983                                                                                         Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 
    984                                                                                         pvs); 
    985         } 
    986          
    987          
    988         // read back the texture 
    989         std::map<Intersectable *, 
    990           PvsData<Intersectable *>, 
    991           LtSample<Intersectable *> >::const_iterator it = pvs.mEntries.begin(); 
    992  
    993         mPvsSize = pvs.mEntries.size(); 
    994            
    995         for (; it != pvs.mEntries.end(); ++ it) { 
    996           Intersectable *object = (*it).first; 
    997           float visibility = log10((*it).second.mSumPdf + 1)/5.0f; 
    998           glColor3f(visibility, 0.0f, 0.0f); 
    999           mUseForcedColors = true; 
    1000           RenderIntersectable(object); 
    1001           mUseForcedColors = false; 
    1002         } 
    1003  
    1004         if (mRenderFilter) { 
    1005           mWireFrame = true; 
    1006           RenderIntersectable(viewcell); 
    1007           mWireFrame = false; 
    1008         } 
    1009          
    1010         if (mUseFilter) 
    1011           mViewCellsManager->DeleteLocalMergeTree(viewcell); 
    1012   } else { 
    1013         ObjectContainer::const_iterator oi = mObjects.begin(); 
    1014         for (; oi != mObjects.end(); oi++) 
    1015           RenderIntersectable(*oi); 
    1016   } 
    1017 } 
    1018  
    1019 float 
    1020 GlRendererWidget::RenderErrors() 
    1021 { 
    1022   float pErrorPixels = -1.0f; 
    1023  
    1024   glReadBuffer(GL_BACK); 
    1025    
    1026   mUseFalseColors = true; 
    1027  
    1028   SetupCamera(); 
    1029   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    1030    
    1031   double eq[4]; 
    1032   eq[0] = mSceneCutPlane.mNormal.x; 
    1033   eq[1] = mSceneCutPlane.mNormal.y; 
    1034   eq[2] = mSceneCutPlane.mNormal.z; 
    1035   eq[3] = mSceneCutPlane.mD; 
    1036    
    1037   if (mCutScene) { 
    1038         glClipPlane(GL_CLIP_PLANE0, eq); 
    1039     glEnable(GL_CLIP_PLANE0); 
    1040   } 
    1041    
    1042   if (mDetectEmptyViewSpace)  
    1043         glEnable( GL_CULL_FACE ); 
    1044   else 
    1045         glDisable( GL_CULL_FACE ); 
    1046  
    1047   ObjectContainer::const_iterator oi = mObjects.begin(); 
    1048   for (; oi != mObjects.end(); oi++) 
    1049         RenderIntersectable(*oi); 
    1050  
    1051   ViewCell *viewcell = NULL; 
    1052  
    1053   QImage im1, im2; 
    1054   QImage diff; 
    1055    
    1056   if (viewcell) { 
    1057         // read back the texture 
    1058         im1 = grabFrameBuffer(true); 
    1059          
    1060         RenderPvs(); 
    1061  
    1062         // read back the texture 
    1063         im2 = grabFrameBuffer(true); 
    1064          
    1065         diff = im1; 
    1066         int x, y; 
    1067         int errorPixels = 0; 
    1068          
    1069         for (y = 0; y < im1.height(); y++) 
    1070           for (x = 0; x < im1.width(); x++) 
    1071                 if (im1.pixel(x, y) == im2.pixel(x, y)) 
    1072                   diff.setPixel(x, y, qRgba(0,0,0,0)); 
    1073                 else { 
    1074                   diff.setPixel(x, y, qRgba(255,128,128,255)); 
    1075                   errorPixels++; 
    1076                 } 
    1077         pErrorPixels = ((float)errorPixels)/(im1.height()*im1.width()); 
    1078   } 
    1079  
    1080   // now render the pvs again 
    1081   SetupCamera(); 
    1082   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    1083   mUseFalseColors = false; 
    1084    
    1085   oi = mObjects.begin(); 
    1086   for (; oi != mObjects.end(); oi++) 
    1087         RenderIntersectable(*oi); 
    1088  
    1089   // now render im1 
    1090   if (viewcell) { 
    1091         if (0 && mTopView) { 
    1092           mWireFrame = true; 
    1093           RenderIntersectable(viewcell); 
    1094           mWireFrame = false; 
    1095         } 
    1096          
    1097         // init ortographic projection 
    1098         glMatrixMode(GL_PROJECTION); 
    1099         glPushMatrix(); 
    1100          
    1101         glLoadIdentity(); 
    1102         gluOrtho2D(0, 1.0f, 0, 1.0f); 
    1103          
    1104         glMatrixMode(GL_MODELVIEW); 
    1105         glLoadIdentity(); 
    1106          
    1107         bindTexture(diff); 
    1108          
    1109         glPushAttrib(GL_ENABLE_BIT); 
    1110         glEnable( GL_ALPHA_TEST ); 
    1111         glDisable( GL_CULL_FACE ); 
    1112         glAlphaFunc( GL_GREATER, 0.5 ); 
    1113          
    1114         glEnable( GL_TEXTURE_2D ); 
    1115         glBegin(GL_QUADS); 
    1116          
    1117         glTexCoord2f(0,0); 
    1118         glVertex3f(0,0,0); 
    1119          
    1120         glTexCoord2f(1,0); 
    1121         glVertex3f( 1, 0, 0); 
    1122          
    1123         glTexCoord2f(1,1); 
    1124         glVertex3f( 1, 1, 0); 
    1125          
    1126         glTexCoord2f(0,1); 
    1127         glVertex3f(0, 1, 0); 
    1128         glEnd(); 
    1129          
    1130         glPopAttrib(); 
    1131          
    1132         // restore the projection matrix 
    1133         glMatrixMode(GL_PROJECTION); 
    1134         glPopMatrix(); 
    1135         glMatrixMode(GL_MODELVIEW); 
    1136   } 
    1137  
    1138   glDisable(GL_CLIP_PLANE0); 
    1139    
    1140   mRenderError = pErrorPixels; 
    1141   return pErrorPixels; 
    1142 } 
    1143  
    1144 void 
    1145 GlRenderer::_RenderScene() 
    1146 { 
    1147   ObjectContainer::const_iterator oi = mObjects.begin(); 
    1148  
    1149   for (; oi != mObjects.end(); oi++) 
    1150         RenderIntersectable(*oi); 
    1151 } 
    1152  
    1153 bool 
    1154 GlRenderer::RenderScene() 
    1155 { 
    1156   static int glList = -1; 
    1157   if (mUseGlLists) { 
    1158         if (glList == -1) { 
    1159           glList = glGenLists(1); 
    1160           glNewList(glList, GL_COMPILE); 
    1161           _RenderScene(); 
    1162           glEndList(); 
    1163         } 
    1164         glCallList(glList); 
    1165   } else 
    1166         _RenderScene(); 
    1167          
    1168    
    1169   return true; 
    1170 } 
    1171  
    1172  
    1173 void 
    1174 GlRendererBuffer::ClearErrorBuffer() 
    1175 { 
    1176   for (int i=0; i < mPvsStatFrames; i++) { 
    1177         mPvsErrorBuffer[i].mError = 1.0f; 
    1178   } 
    1179 } 
    1180  
    1181  
    1182 void 
    1183 GlRendererBuffer::EvalPvsStat() 
    1184 { 
    1185   mPvsStat.Reset(); 
    1186   halton.Reset(); 
    1187  
    1188   makeCurrent(); 
    1189  
    1190  
    1191   SetupProjection(GetWidth(), GetHeight()); 
    1192  
    1193    
    1194   for (int i=0; i < mPvsStatFrames; i++) { 
    1195         float err; 
    1196         // set frame id for saving the error buffer 
    1197         mFrame = i; 
    1198         RandomViewPoint(); 
    1199  
    1200         // atlanta problematic frames: 325 525 691 1543 
    1201 #if 0 
    1202         if (mFrame != 325 && 
    1203                 mFrame != 525 && 
    1204                 mFrame != 691 && 
    1205                 mFrame != 1543) 
    1206           mPvsErrorBuffer[i] = -1; 
    1207         else { 
    1208           Debug<<"frame ="<<mFrame<<" vp="<<mViewPoint<<" vd="<<mViewDirection<<endl; 
    1209         } 
    1210 #endif 
    1211         if (mPvsErrorBuffer[i].mError > 0.0f) { 
    1212           int pvsSize; 
    1213  
    1214  
    1215           float error = GetPixelError(pvsSize); 
    1216           mPvsErrorBuffer[i].mError = error; 
    1217           mPvsErrorBuffer[i].mPvsSize = pvsSize; 
    1218  
    1219           emit UpdatePvsErrorItem(i, 
    1220                                                           mPvsErrorBuffer[i]); 
    1221            
    1222           cout<<"("<<i<<","<<mPvsErrorBuffer[i].mError<<")"; 
    1223           //      swapBuffers(); 
    1224         } 
    1225          
    1226         err = mPvsErrorBuffer[i].mError; 
    1227          
    1228         if (err >= 0.0f) { 
    1229           if (err > mPvsStat.maxError) 
    1230                 mPvsStat.maxError = err; 
    1231           mPvsStat.sumError += err; 
    1232           mPvsStat.sumPvsSize += mPvsErrorBuffer[i].mPvsSize; 
    1233            
    1234           if (err == 0.0f) 
    1235                 mPvsStat.errorFreeFrames++; 
    1236           mPvsStat.frames++; 
    1237         } 
    1238   } 
    1239  
    1240   glFinish(); 
    1241   doneCurrent(); 
    1242  
    1243   cout<<endl<<flush; 
    1244   //  mRenderingFinished.wakeAll(); 
    1245 } 
    1246  
    1247  
    1248  
    1249  
    1250  
    1251 void 
    1252 GlRendererWidget::mousePressEvent(QMouseEvent *e) 
    1253 { 
    1254   int x = e->pos().x(); 
    1255   int y = e->pos().y(); 
    1256  
    1257   mousePoint.x = x; 
    1258   mousePoint.y = y; 
    1259    
    1260 } 
    1261  
    1262 void 
    1263 GlRendererWidget::mouseMoveEvent(QMouseEvent *e) 
    1264 { 
    1265   float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3; 
    1266   float TURN_SENSITIVITY=0.1f; 
    1267   float TILT_SENSITIVITY=32.0 ; 
    1268   float TURN_ANGLE= M_PI/36.0 ; 
    1269  
    1270   int x = e->pos().x(); 
    1271   int y = e->pos().y(); 
    1272    
    1273   if (e->modifiers() & Qt::ControlModifier) { 
    1274         mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY/2.0; 
    1275         mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY/2.0; 
    1276   } else { 
    1277         mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY); 
    1278         float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY; 
    1279         float angle = atan2(mViewDirection.x, mViewDirection.z); 
    1280         mViewDirection.x = sin(angle+adiff); 
    1281         mViewDirection.z = cos(angle+adiff); 
    1282   } 
    1283    
    1284   mousePoint.x = x; 
    1285   mousePoint.y = y; 
    1286    
    1287   updateGL(); 
    1288 } 
    1289  
    1290 void 
    1291 GlRendererWidget::mouseReleaseEvent(QMouseEvent *) 
    1292 { 
    1293  
    1294  
    1295 } 
    1296  
    1297 void 
    1298 GlRendererWidget::resizeGL(int w, int h) 
    1299 { 
    1300   SetupProjection(w, h); 
    1301   updateGL(); 
    1302 } 
    1303  
    1304 void 
    1305 GlRendererWidget::paintGL() 
    1306 { 
    1307   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    1308  
    1309    
    1310   if (!mRenderViewCells) { 
    1311         if (mRenderErrors) 
    1312           RenderErrors(); 
    1313         else 
    1314           RenderPvs(); 
    1315         RenderInfo(); 
    1316   } else { 
    1317         RenderViewCells(); 
    1318          
    1319         mWireFrame = true; 
    1320         RenderScene(); 
    1321         mWireFrame = false; 
    1322          
    1323         RenderInfo(); 
    1324   } 
    1325  
    1326   mFrame++; 
    1327 } 
    1328  
    1329  
    1330 void 
    1331 GlRendererWidget::SetupCamera() 
    1332 { 
    1333   if (!mTopView) 
    1334         GlRenderer::SetupCamera(); 
    1335   else { 
    1336         if (0) { 
    1337           float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05; 
    1338           Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x, 
    1339                                                                                           -1, 
    1340                                                                                           mViewDirection.y); 
    1341            
    1342           Vector3 target = mViewPoint + dist*mViewDirection; 
    1343           Vector3 up(0,1,0); 
    1344            
    1345           glLoadIdentity(); 
    1346           gluLookAt(pos.x, pos.y, pos.z, 
    1347                                 target.x, target.y, target.z, 
    1348                                 up.x, up.y, up.z); 
    1349         } else { 
    1350           float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*mTopDistance; 
    1351           Vector3 pos = mViewPoint  + dist*Vector3(0, 
    1352                                                                                            1, 
    1353                                                                                            0); 
    1354            
    1355           Vector3 target = mViewPoint; 
    1356           Vector3 up(mViewDirection.x, 0, mViewDirection.z); 
    1357            
    1358           glLoadIdentity(); 
    1359           gluLookAt(pos.x, pos.y, pos.z, 
    1360                                 target.x, target.y, target.z, 
    1361                                 up.x, up.y, up.z); 
    1362            
    1363         } 
    1364   } 
    1365  
    1366 } 
    1367  
    1368 void 
    1369 GlRendererWidget::keyPressEvent ( QKeyEvent * e ) 
    1370 { 
    1371   switch (e->key()) { 
    1372   case Qt::Key_T: 
    1373         mTopView = !mTopView; 
    1374         SetupProjection(width(), height()); 
    1375         updateGL(); 
    1376         break; 
    1377   case Qt::Key_V: 
    1378         mRenderViewCells = !mRenderViewCells; 
    1379         updateGL(); 
    1380         break; 
    1381   case Qt::Key_P: 
    1382         // set random viewpoint 
    1383         mViewCellsManager->GetViewPoint(mViewPoint); 
    1384         updateGL(); 
    1385         break; 
    1386  
    1387   default: 
    1388         e->ignore(); 
    1389         break; 
    1390   } 
    1391 } 
    1392  
    1393    
    1394 RendererControlWidget::RendererControlWidget(QWidget * parent, Qt::WFlags f): 
    1395   QWidget(parent, f) 
    1396 { 
    1397  
    1398   QVBoxLayout *vl = new QVBoxLayout; 
    1399   setLayout(vl); 
    1400    
    1401   QWidget *vbox = new QGroupBox("ViewCells", this); 
    1402   layout()->addWidget(vbox); 
    1403    
    1404   vl = new QVBoxLayout; 
    1405   vbox->setLayout(vl); 
    1406  
    1407   QLabel *label = new QLabel("Granularity"); 
    1408   vbox->layout()->addWidget(label); 
    1409  
    1410   QSlider *slider = new QSlider(Qt::Horizontal, vbox); 
    1411   vl->addWidget(slider); 
    1412   slider->show(); 
    1413   slider->setRange(1, 10000); 
    1414   slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 
    1415   slider->setValue(200); 
    1416  
    1417   connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int))); 
    1418  
    1419   label = new QLabel("Filter size"); 
    1420   vbox->layout()->addWidget(label); 
    1421    
    1422   slider = new QSlider(Qt::Horizontal, vbox); 
    1423   vbox->layout()->addWidget(slider); 
    1424   slider->show(); 
    1425   slider->setRange(1, 100); 
    1426   slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 
    1427   slider->setValue(3); 
    1428    
    1429   connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int))); 
    1430  
    1431  
    1432   label = new QLabel("Spatial Filter size"); 
    1433   vbox->layout()->addWidget(label); 
    1434    
    1435   slider = new QSlider(Qt::Horizontal, vbox); 
    1436   vbox->layout()->addWidget(slider); 
    1437   slider->show(); 
    1438   slider->setRange(1, 100); 
    1439   slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 
    1440   slider->setValue(10); 
    1441    
    1442   connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int))); 
    1443  
    1444  
    1445  
    1446   QWidget *hbox = new QWidget(vbox); 
    1447   vl->addWidget(hbox); 
    1448   QHBoxLayout *hlayout = new QHBoxLayout; 
    1449   hbox->setLayout(hlayout); 
    1450    
    1451   QCheckBox *cb = new QCheckBox("Show viewcells", hbox); 
    1452   hlayout->addWidget(cb); 
    1453   cb->setChecked(false); 
    1454   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool))); 
    1455  
    1456   cb = new QCheckBox("Show render cost", hbox); 
    1457   hlayout->addWidget(cb); 
    1458   cb->setChecked(false); 
    1459   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool))); 
    1460  
    1461   cb = new QCheckBox("Show pvs sizes", hbox); 
    1462   hlayout->addWidget(cb); 
    1463   cb->setChecked(false); 
    1464   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool))); 
    1465  
    1466   vbox->resize(800,100); 
    1467  
    1468    
    1469   vbox = new QGroupBox("Rendering", this); 
    1470   layout()->addWidget(vbox); 
    1471    
    1472   vl = new QVBoxLayout; 
    1473   vbox->setLayout(vl); 
    1474  
    1475  
    1476  
    1477   slider = new QSlider(Qt::Horizontal, vbox); 
    1478   vbox->layout()->addWidget(slider); 
    1479   slider->show(); 
    1480   slider->setRange(0, 1000); 
    1481   slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 
    1482   slider->setValue(1000); 
    1483  
    1484   connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int))); 
    1485  
    1486   cb = new QCheckBox("Render errors", vbox); 
    1487   vbox->layout()->addWidget(cb); 
    1488   cb->setChecked(false); 
    1489   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool))); 
    1490  
    1491   cb = new QCheckBox("Use filter", vbox); 
    1492   vbox->layout()->addWidget(cb); 
    1493   cb->setChecked(true); 
    1494   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool))); 
    1495  
    1496   cb = new QCheckBox("Use spatial filter", vbox); 
    1497   vbox->layout()->addWidget(cb); 
    1498   cb->setChecked(true); 
    1499   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool))); 
    1500  
    1501   cb = new QCheckBox("Render filter", vbox); 
    1502   vbox->layout()->addWidget(cb); 
    1503   cb->setChecked(true); 
    1504   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool))); 
    1505  
    1506  
    1507   cb = new QCheckBox("Cut view cells", vbox); 
    1508   vbox->layout()->addWidget(cb); 
    1509   cb->setChecked(false); 
    1510   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool))); 
    1511  
    1512   cb = new QCheckBox("Cut scene", vbox); 
    1513   vbox->layout()->addWidget(cb); 
    1514   cb->setChecked(false); 
    1515   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool))); 
    1516  
    1517    
    1518   slider = new QSlider(Qt::Horizontal, vbox); 
    1519   vbox->layout()->addWidget(slider); 
    1520   slider->show(); 
    1521   slider->setRange(1, 1000); 
    1522   slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); 
    1523   slider->setValue(500); 
    1524    
    1525   connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int))); 
    1526    
    1527   cb = new QCheckBox("Top View", vbox); 
    1528   vbox->layout()->addWidget(cb); 
    1529   cb->setChecked(false); 
    1530   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool))); 
    1531  
    1532   vbox = new QGroupBox("PVS Errors", this); 
    1533   layout()->addWidget(vbox); 
    1534  
    1535   vl = new QVBoxLayout; 
    1536   vbox->setLayout(vl); 
    1537  
    1538   mPvsErrorWidget = new QListWidget(vbox); 
    1539   vbox->layout()->addWidget(mPvsErrorWidget); 
    1540    
    1541   connect(mPvsErrorWidget, 
    1542                   SIGNAL(doubleClicked(const QModelIndex &)), 
    1543                   this, 
    1544                   SLOT(PvsErrorClicked(const QModelIndex &))); 
    1545    
    1546   QPushButton *button = new QPushButton("Next Error Frame", vbox); 
    1547   vbox->layout()->addWidget(button); 
    1548   connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void))); 
    1549  
    1550   setWindowTitle("Preprocessor Control Widget"); 
    1551   adjustSize(); 
    1552 } 
    1553  
    1554  
    1555  
    1556 void 
    1557 RendererControlWidget::FocusNextPvsErrorFrame(void) 
    1558 { 
    1559    
    1560    
    1561 } 
    1562  
    1563 void 
    1564 RendererControlWidget::UpdatePvsErrorItem(int row, 
    1565                                                                                   GlRendererBuffer::PvsErrorEntry &pvsErrorEntry) 
    1566 { 
    1567  
    1568   QListWidgetItem *i = mPvsErrorWidget->item(row); 
    1569   QString s; 
    1570   s.sprintf("%5.5f", pvsErrorEntry.mError); 
    1571   if (i) { 
    1572         i->setText(s); 
    1573   } else { 
    1574         new QListWidgetItem(s, mPvsErrorWidget); 
    1575   } 
    1576   mPvsErrorWidget->update(); 
    1577 } 
    1578  
    1579 GlRendererWidget::GlRendererWidget(SceneGraph *sceneGraph, 
    1580                                                                    ViewCellsManager *viewcells, 
    1581                                                                    KdTree *tree, 
    1582                                                                    QWidget * parent, 
    1583                                                                    const QGLWidget * shareWidget, 
    1584                                                                    Qt::WFlags f 
    1585                                                                    ) 
    1586   : 
    1587   GlRenderer(sceneGraph, viewcells, tree), QGLWidget(parent, shareWidget, f) 
    1588 { 
    1589   mTopView = false; 
    1590   mRenderViewCells = false; 
    1591   mTopDistance = 1.0f; 
    1592   mCutViewCells = false; 
    1593   mCutScene = false; 
    1594   mRenderErrors = false; 
    1595   mRenderFilter = true; 
    1596  
    1597   bool tmp; 
    1598  
    1599   Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp ); 
    1600   mUseFilter = tmp; 
    1601    
    1602   Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", 
    1603                                                         tmp ); 
    1604  
    1605   mUseSpatialFilter = tmp; 
    1606  
    1607   mShowRenderCost = false; 
    1608   mShowPvsSizes = false; 
    1609   mSpatialFilterSize = 0.01; 
    1610   mPvsSize = 0; 
    1611   mRenderError = 0.0f; 
    1612   mControlWidget = new RendererControlWidget(NULL); 
    1613    
    1614   connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int))); 
    1615   connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int))); 
    1616   connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int))); 
    1617  
    1618   connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int))); 
    1619   connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int))); 
    1620  
    1621   connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool))); 
    1622   connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool))); 
    1623   connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool))); 
    1624   connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool))); 
    1625   connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool))); 
    1626   connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool))); 
    1627   connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool))); 
    1628   connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool))); 
    1629   connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool))); 
    1630   connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)), 
    1631                   this, SLOT(SetUseSpatialFilter(bool))); 
    1632  
    1633    
    1634   mControlWidget->show(); 
    1635 } 
    1636  
    1637 void 
    1638 GlRendererWidget::SetViewCellGranularity(int number) 
    1639 { 
    1640   if (mViewCellsManager)  
    1641         //      mViewCellsManager->SetMaxFilterSize(number); 
    1642     mViewCellsManager->CollectViewCells(number); 
    1643  
    1644   updateGL(); 
    1645 } 
    1646  
    1647 void 
    1648 GlRendererWidget::SetVisibilityFilterSize(int number) 
    1649 { 
    1650   if (mViewCellsManager)  
    1651         mViewCellsManager->SetMaxFilterSize(number); 
    1652   updateGL(); 
    1653 } 
    1654  
    1655 void 
    1656 GlRendererWidget::SetSpatialFilterSize(int number) 
    1657 { 
    1658   mSpatialFilterSize = 1e-3*number; 
    1659   updateGL(); 
    1660 } 
    1661  
    1662 void 
    1663 GlRendererWidget::SetSceneCut(int number) 
    1664 { 
    1665   // assume the cut plane can only be aligned with xz plane 
    1666   // shift it along y according to number, which is percentage of the bounding 
    1667   // box position 
    1668   if (mViewCellsManager) { 
    1669         AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox(); 
    1670         Vector3 p = box.Min() + (number/1000.0f)*box.Max(); 
    1671         mSceneCutPlane.mNormal = Vector3(0,-1,0); 
    1672         mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p); 
    1673         updateGL(); 
    1674   } 
    1675 } 
    1676  
    1677 void 
    1678 GlRendererWidget::SetTopDistance(int number) 
    1679 { 
    1680   mTopDistance = number/1000.0f; 
    1681   updateGL(); 
    1682 } 
    1683  
    1684 void 
    1685 GlRendererWidget::RenderViewCells() 
    1686 { 
    1687   mUseFalseColors = true; 
    1688  
    1689   SetupCamera(); 
    1690   glEnable(GL_CULL_FACE); 
    1691   //glDisable(GL_CULL_FACE); 
    1692   glCullFace(GL_FRONT); 
    1693   double eq[4]; 
    1694   eq[0] = mSceneCutPlane.mNormal.x; 
    1695   eq[1] = mSceneCutPlane.mNormal.y; 
    1696   eq[2] = mSceneCutPlane.mNormal.z; 
    1697   eq[3] = mSceneCutPlane.mD; 
    1698  
    1699   if (mCutViewCells) { 
    1700         glClipPlane(GL_CLIP_PLANE0, eq); 
    1701         glEnable(GL_CLIP_PLANE0); 
    1702   } 
    1703    
    1704   int i; 
    1705   ViewCellContainer &viewcells = mViewCellsManager->GetViewCells(); 
    1706   int maxPvs = -1; 
    1707   for (i=0; i < viewcells.size(); i++)  
    1708   { 
    1709         ViewCell *vc = viewcells[i]; 
    1710         const int p = vc->GetPvs().CountPvs(); 
    1711         if (p > maxPvs) 
    1712           maxPvs = p; 
    1713   } 
    1714  
    1715  
    1716   for (i=0; i < viewcells.size(); i++) { 
    1717         ViewCell *vc = viewcells[i]; 
    1718         //      Mesh *m = vc->GetMesh(); 
    1719  
    1720  
    1721         RgbColor c; 
    1722  
    1723         if (!mShowPvsSizes)  
    1724           c = vc->GetColor(); 
    1725         else { 
    1726           const float importance = (float)vc->GetPvs().CountPvs() / (float)maxPvs; 
    1727           c = RgbColor(importance, 1.0f - importance, 0.0f); 
    1728         } 
    1729         glColor3f(c.r, c.g, c.b); 
    1730          
    1731         RenderViewCell(vc); 
    1732   } 
    1733  
    1734   glDisable(GL_CLIP_PLANE0); 
    1735  
    1736 } 
    1737  
    1738 void GlRendererBuffer::SampleBeamContributions(Intersectable *sourceObject, 
    1739                                                                                            Beam &beam, 
    1740                                                                                            const int desiredSamples, 
    1741                                                                                            BeamSampleStatistics &stat) 
    1742 { 
    1743         // TODO: should be moved out of here (not to be done every time) 
    1744         // only back faces are interesting for the depth pass 
    1745         glShadeModel(GL_FLAT); 
    1746         glDisable(GL_LIGHTING); 
    1747  
    1748         // needed to kill the fragments for the front buffer 
    1749         glEnable(GL_ALPHA_TEST); 
    1750         glAlphaFunc(GL_GREATER, 0); 
    1751  
    1752         // assumes that the beam is constructed and contains kd-tree nodes 
    1753         // and viewcells which it intersects 
    1754    
    1755    
    1756         // Get the number of viewpoints to be sampled 
    1757         // Now it is a sqrt but in general a wiser decision could be made. 
    1758         // The less viewpoints the better for rendering performance, since less passes 
    1759         // over the beam is needed. 
    1760         // The viewpoints could actually be generated outside of the bounding box which 
    1761         // would distribute the 'efective viewpoints' of the object surface and thus 
    1762         // with a few viewpoints better sample the viewpoint space.... 
    1763  
    1764         //TODO: comment in 
    1765         //int viewPointSamples = sqrt((float)desiredSamples); 
    1766         int viewPointSamples = max(desiredSamples / (GetWidth() * GetHeight()), 1); 
    1767          
    1768         // the number of direction samples per pass is given by the number of viewpoints 
    1769         int directionalSamples = desiredSamples / viewPointSamples; 
    1770          
    1771         Debug << "directional samples: " << directionalSamples << endl; 
    1772         for (int i = 0; i < viewPointSamples; ++ i)  
    1773         { 
    1774                 Vector3 viewPoint = beam.mBox.GetRandomPoint(); 
    1775                  
    1776                 // perhaps the viewpoint should be shifted back a little bit so that it always lies 
    1777                 // inside the source object 
    1778                 // 'ideally' the viewpoints would be distributed on the soureObject surface, but this 
    1779         // would require more complicated sampling (perhaps hierarchical rejection sampling of 
    1780                 // the object surface is an option here - only the mesh faces which are inside the box 
    1781                 // are considered as candidates)  
    1782                  
    1783                 SampleViewpointContributions(sourceObject, 
    1784                                                                          viewPoint, 
    1785                                                                          beam, 
    1786                                                                          directionalSamples, 
    1787                                                                          stat); 
    1788         } 
    1789  
    1790  
    1791         // note: 
    1792         // this routine would be called only if the number of desired samples is sufficiently 
    1793         // large - for other rss tree cells the cpu based sampling is perhaps more efficient 
    1794         // distributing the work between cpu and gpu would also allow us to place more sophisticated 
    1795         // sample distributions (silhouette ones) using the cpu and the jittered once on the GPU 
    1796         // in order that thios scheme is working well the gpu render buffer should run in a separate 
    1797         // thread than the cpu sampler, which would not be such a big problem.... 
    1798  
    1799         // disable alpha test again 
    1800         glDisable(GL_ALPHA_TEST); 
    1801 } 
    1802  
    1803  
    1804 void GlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject, 
    1805                                                                                                         const Vector3 viewPoint, 
    1806                                                                                                         Beam &beam, 
    1807                                                                                                         const int samples, 
    1808                                                     BeamSampleStatistics &stat) 
    1809 { 
    1810     // 1. setup the view port to match the desired samples 
    1811         glViewport(0, 0, samples, samples); 
    1812  
    1813         // 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox 
    1814         SetupProjectionForViewPoint(viewPoint, beam, sourceObject); 
    1815  
    1816  
    1817         // 3. reset z-buffer to 0 and render the source object for the beam 
    1818         //    with glCullFace(Enabled) and glFrontFace(GL_CW) 
    1819         //    save result to the front depth map 
    1820         //    the front depth map holds ray origins 
    1821  
    1822  
    1823         // front depth buffer must be initialised to 0 
    1824         float clearDepth; 
    1825          
    1826         glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth); 
    1827         glClearDepth(0.0f); 
    1828         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    1829  
    1830  
    1831         //glFrontFace(GL_CW); 
    1832         glEnable(GL_CULL_FACE); 
    1833         glCullFace(GL_FRONT); 
    1834         glColorMask(0, 0, 0, 0); 
    1835          
    1836  
    1837         // stencil is increased where the source object is located 
    1838         glEnable(GL_STENCIL_TEST);       
    1839         glStencilFunc(GL_ALWAYS, 0x1, 0x1); 
    1840         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
    1841  
    1842  
    1843 #if 0 
    1844         static int glSourceObjList = -1;          
    1845         if (glSourceObjList != -1)  
    1846         { 
    1847                 glSourceObjList = glGenLists(1); 
    1848                 glNewList(glSourceObjList, GL_COMPILE); 
    1849  
    1850                 RenderIntersectable(sourceObject); 
    1851          
    1852                 glEndList(); 
    1853         } 
    1854         glCallList(glSourceObjList); 
    1855  
    1856 #else 
    1857         RenderIntersectable(sourceObject); 
    1858  
    1859 #endif   
    1860  
    1861          // copy contents of the front depth buffer into depth texture 
    1862         glBindTexture(GL_TEXTURE_2D, frontDepthMap);     
    1863         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize); 
    1864  
    1865  
    1866         // reset clear function 
    1867         glClearDepth(clearDepth); 
    1868  
    1869          
    1870          
    1871         // 4. set up the termination depth buffer (= standard depth buffer) 
    1872         //    only rays which have non-zero entry in the origin buffer are valid since 
    1873         //    they realy start on the object surface (this is tagged by setting a 
    1874         //    stencil buffer bit at step 3). 
    1875          
    1876         glStencilFunc(GL_EQUAL, 0x1, 0x1); 
    1877         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 
    1878  
    1879         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    1880         glDepthMask(1); 
    1881  
    1882         glEnable(GL_DEPTH_TEST); 
    1883                  
    1884         glEnable(GL_CULL_FACE); 
    1885         glCullFace(GL_BACK); 
    1886  
    1887         // setup front depth buffer 
    1888         glEnable(GL_TEXTURE_2D); 
    1889          
    1890         // bind pixel shader implementing the front depth buffer functionality 
    1891         cgGLBindProgram(sCgFragmentProgram); 
    1892         cgGLEnableProfile(sCgFragmentProfile); 
    1893  
    1894  
    1895         // 5. render all objects inside the beam  
    1896         //    we can use id based false color to read them back for gaining the pvs 
    1897  
    1898         glColorMask(1, 1, 1, 1); 
    1899  
    1900          
    1901         // if objects not stored in beam => extract objects 
    1902         if (beam.mFlags & !Beam::STORE_OBJECTS) 
    1903         { 
    1904                 vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end(); 
    1905  
    1906                 Intersectable::NewMail(); 
    1907                 for (it = beam.mKdNodes.begin(); it != it_end; ++ it) 
    1908                 { 
    1909                         mKdTree->CollectObjects(*it, beam.mObjects); 
    1910                 } 
    1911         } 
    1912  
    1913  
    1914         //    (objects can be compiled to a gl list now so that subsequent rendering for 
    1915         //    this beam is fast - the same hold for step 3) 
    1916         //    Afterwards we have two depth buffers defining the ray origin and termination 
    1917          
    1918  
    1919 #if 0 
    1920         static int glObjList = -1;  
    1921         if (glObjList != -1)  
    1922         { 
    1923                 glObjList = glGenLists(1); 
    1924                 glNewList(glObjList, GL_COMPILE); 
    1925          
    1926                 ObjectContainer::const_iterator it, it_end = beam.mObjects.end(); 
    1927                 for (it = beam.mObjects.begin(); it != it_end; ++ it) 
    1928                 { 
    1929                         // render all objects except the source object 
    1930                         if (*it != sourceObject) 
    1931                                 RenderIntersectable(*it); 
    1932                 } 
    1933                  
    1934                 glEndList(); 
    1935         } 
    1936  
    1937         glCallList(glObjList); 
    1938 #else 
    1939         ObjectContainer::const_iterator it, it_end = beam.mObjects.end(); 
    1940         for (it = beam.mObjects.begin(); it != it_end; ++ it) 
    1941         {        
    1942                 // render all objects except the source object 
    1943                 if (*it != sourceObject) 
    1944                         RenderIntersectable(*it); 
    1945         } 
    1946 #endif 
    1947          
    1948     
    1949  
    1950         // 6. Use occlusion queries for all viewcell meshes associated with the beam -> 
    1951         //     a fragment passes if the corresponding stencil fragment is set and its depth is 
    1952         //     between origin and termination buffer 
    1953  
    1954         // create new queries if necessary 
    1955         OcclusionQuery::GenQueries(sQueries, (int)beam.mViewCells.size()); 
    1956  
    1957         // check whether any backfacing polygon would pass the depth test? 
    1958         // matt: should check both back /front facing because of dual depth buffer 
    1959         // and danger of cutting the near plane with front facing polys. 
    1960          
    1961         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
    1962         glDepthMask(GL_FALSE); 
    1963         glDisable(GL_CULL_FACE); 
    1964  
    1965    
    1966         ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end(); 
    1967  
    1968         int queryIdx = 0; 
    1969  
    1970         for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit) 
    1971         { 
    1972                 sQueries[queryIdx ++]->BeginQuery(); 
    1973  
    1974                 RenderIntersectable(*vit); 
    1975                  
    1976                 sQueries[queryIdx]->EndQuery(); 
    1977  
    1978                 ++ queryIdx; 
    1979         } 
    1980  
    1981  
    1982  
    1983         // at this point, if possible, go and do some other computation 
    1984  
    1985  
    1986          
    1987         // 7. The number of visible pixels is the number of sample rays which see the source 
    1988         //    object from the corresponding viewcell -> remember these values for later update 
    1989         //   of the viewcell pvs - or update immediately? 
    1990  
    1991         queryIdx = 0; 
    1992  
    1993         for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit) 
    1994         { 
    1995                 // fetch queries 
    1996                 unsigned int pixelCount = sQueries[queryIdx ++]->GetQueryResult(); 
    1997  
    1998                 if (pixelCount) 
    1999                         Debug << "view cell " << (*vit)->GetId() << " visible pixels: " << pixelCount << endl; 
    2000         } 
    2001          
    2002  
    2003         // 8. Copmpute rendering statistics 
    2004         // In general it is not neccessary to remember to extract all the rays cast. I hope it 
    2005         // would be sufficient to gain only the intergral statistics about the new contributions 
    2006         // and so the rss tree would actually store no new rays (only the initial ones) 
    2007         // the subdivision of the tree would only be driven by the statistics (the glrender could 
    2008         // evaluate the contribution entropy for example) 
    2009         // However might be an option to extract/store only those the rays which made a contribution 
    2010         // (new viewcell has been discovered) or relative contribution greater than a threshold ...  
    2011  
    2012         ObjectContainer pvsObj; 
    2013         stat.pvsSize = ComputePvs(beam.mObjects, pvsObj); 
    2014          
    2015         // to gain ray source and termination 
    2016         // copy contents of ray termination buffer into depth texture 
    2017         // and compare with ray source buffer 
    2018 #if 0 
    2019         VssRayContainer rays; 
    2020  
    2021         glBindTexture(GL_TEXTURE_2D, backDepthMap);      
    2022         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize); 
    2023  
    2024         ComputeRays(Intersectable *sourceObj, rays); 
    2025  
    2026 #endif 
    2027  
    2028  
    2029  
    2030         //-- cleanup 
    2031  
    2032  
    2033         // reset gl state 
    2034         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    2035         glDepthMask(GL_TRUE); 
    2036         glEnable(GL_CULL_FACE); 
    2037         glDisable(GL_STENCIL_TEST); 
    2038         cgGLDisableProfile(sCgFragmentProfile); 
    2039         glDisable(GL_TEXTURE_2D); 
    2040  
    2041         // remove objects from beam 
    2042         if (beam.mFlags & !Beam::STORE_OBJECTS) 
    2043                 beam.mObjects.clear(); 
    2044 } 
    2045  
    2046  
    2047 void GlRendererBuffer::SetupProjectionForViewPoint(const Vector3 &viewPoint,  
    2048                                                                                                    const Beam &beam,  
    2049                                                                                                    Intersectable *sourceObject) 
    2050 { 
    2051         float left, right, bottom, top, znear, zfar; 
    2052  
    2053         beam.ComputePerspectiveFrustum(left, right, bottom, top, znear, zfar, 
    2054                                                                    mSceneGraph->GetBox()); 
    2055  
    2056         //Debug << left << " " << right << " " << bottom << " " << top << " " << znear << " " << zfar << endl; 
    2057         glMatrixMode(GL_PROJECTION); 
    2058         glLoadIdentity(); 
    2059         glFrustum(left, right, bottom, top, znear, zfar); 
    2060         //glFrustum(-1, 1, -1, 1, 1, 20000); 
    2061  
    2062     const Vector3 center = viewPoint + beam.GetMainDirection() * (zfar - znear) * 0.3f; 
    2063         const Vector3 up =  
    2064                 Normalize(CrossProd(beam.mPlanes[0].mNormal, beam.mPlanes[4].mNormal)); 
    2065  
    2066 #ifdef _DEBUG 
    2067         Debug << "view point: " << viewPoint << endl; 
    2068         Debug << "eye: " << center << endl; 
    2069         Debug << "up: " << up << endl; 
    2070 #endif 
    2071  
    2072         glMatrixMode(GL_MODELVIEW); 
    2073         glLoadIdentity(); 
    2074         gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z,  
    2075                           center.x, center.y, center.z,                    
    2076                           up.x, up.y, up.z); 
    2077 }                
    2078  
    2079    
    2080 void GlRendererBuffer::InitGL() 
    2081 { 
    2082  makeCurrent();  
    2083  GlRenderer::InitGL(); 
    2084  
    2085 #if 1 
    2086         // initialise dual depth buffer textures 
    2087         glGenTextures(1, &frontDepthMap); 
    2088         glBindTexture(GL_TEXTURE_2D, frontDepthMap); 
    2089          
    2090         glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,  
    2091                 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); 
    2092         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    2093         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    2094         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
    2095         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
    2096  
    2097         glGenTextures(1, &backDepthMap); 
    2098         glBindTexture(GL_TEXTURE_2D, backDepthMap); 
    2099          
    2100         glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,  
    2101                 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); 
    2102         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    2103         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    2104         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
    2105         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
    2106  
    2107         // cg initialization 
    2108         cgSetErrorCallback(handleCgError); 
    2109         sCgContext = cgCreateContext(); 
    2110          
    2111         if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1)) 
    2112                 sCgFragmentProfile = CG_PROFILE_ARBFP1; 
    2113         else  
    2114         { 
    2115           // try FP30 
    2116           if (cgGLIsProfileSupported(CG_PROFILE_FP30)) 
    2117             sCgFragmentProfile = CG_PROFILE_FP30; 
    2118           else  
    2119           { 
    2120                   Debug << "Neither arbfp1 or fp30 fragment profiles supported on this system" << endl; 
    2121                   exit(1); 
    2122           } 
    2123   } 
    2124  
    2125  
    2126  sCgFragmentProgram = cgCreateProgramFromFile(sCgContext, 
    2127                                                                                            CG_SOURCE, "../src/dual_depth.cg", 
    2128                                                                                            sCgFragmentProfile, 
    2129                                                                                            NULL,  
    2130                                                                                            NULL); 
    2131  
    2132   if (!cgIsProgramCompiled(sCgFragmentProgram)) 
    2133           cgCompileProgram(sCgFragmentProgram); 
    2134  
    2135   cgGLLoadProgram(sCgFragmentProgram); 
    2136   cgGLBindProgram(sCgFragmentProgram); 
    2137  
    2138   Debug << "---- PROGRAM BEGIN ----\n" << 
    2139           cgGetProgramString(sCgFragmentProgram, CG_COMPILED_PROGRAM) << "---- PROGRAM END ----\n"; 
    2140  
    2141 #endif 
    2142   doneCurrent(); 
    2143 } 
    2144  
    2145  
    2146 void GlRendererBuffer::ComputeRays(Intersectable *sourceObj, VssRayContainer &rays) 
    2147 { 
    2148         for (int i = 0; i < depthMapSize * depthMapSize; ++ i) 
    2149         { 
    2150                 //todo glGetTexImage() 
    2151         } 
    2152 } 
    2153  
    2154  
    2155  
    2156 inline bool ilt(Intersectable *obj1, Intersectable *obj2) 
    2157 { 
    2158         return obj1->mId < obj2->mId; 
    2159 } 
    2160  
    2161  
    2162 int GlRendererBuffer::ComputePvs(ObjectContainer &objects,  
    2163                                                                  ObjectContainer &pvs) const 
    2164 { 
    2165         int pvsSize = 0; 
    2166         QImage image = toImage(); 
    2167         Intersectable::NewMail(); 
    2168  
    2169         std::stable_sort(objects.begin(), objects.end(), ilt); 
    2170  
    2171         MeshInstance dummy(NULL); 
    2172  
    2173         Intersectable *obj = NULL; 
    2174                          
    2175         for (int x = 0; x < image.width(); ++ x) 
    2176         { 
    2177                 for (int y = 0; y < image.height(); ++ y) 
    2178                 { 
    2179                         QRgb pix = image.pixel(x, y); 
    2180                         const int id = GetId(qRed(pix), qGreen(pix), qBlue(pix)); 
    2181  
    2182                         dummy.SetId(id); 
    2183  
    2184                         ObjectContainer::iterator oit = 
    2185                                 lower_bound(objects.begin(), objects.end(), &dummy, ilt); 
    2186                          
    2187                          
    2188                         if (//(oit != oit.end()) &&  
    2189                                 ((*oit)->GetId() == id) &&  
    2190                                 !obj->Mailed()) 
    2191                         { 
    2192                                 obj = *oit; 
    2193                                 obj->Mail(); 
    2194                                 ++ pvsSize; 
    2195                                 pvs.push_back(obj); 
    2196                         } 
    2197                 } 
    2198         } 
    2199  
    2200         return pvsSize; 
    2201 } 
    2202  
    2203 /***********************************************************************/ 
    2204 /*                     GlDebuggerWidget implementation                             */ 
    2205 /***********************************************************************/ 
    2206  
    2207  
    2208 GlDebuggerWidget::GlDebuggerWidget(GlRendererBuffer *buf, QWidget *parent) 
    2209       : QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf) 
    2210 { 
    2211         // create the pbuffer 
    2212     //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this); 
    2213     timerId = startTimer(20); 
    2214     setWindowTitle(("OpenGL pbuffers")); 
    2215 } 
    2216  
    2217  
    2218 GlDebuggerWidget::~GlDebuggerWidget() 
    2219 { 
    2220  mRenderBuffer->releaseFromDynamicTexture(); 
    2221    glDeleteTextures(1, &dynamicTexture); 
    2222           
    2223          DEL_PTR(mRenderBuffer); 
    2224 } 
    2225  
    2226  
    2227 void GlDebuggerWidget::initializeGL() 
    2228 { 
    2229         glMatrixMode(GL_PROJECTION); 
    2230         glLoadIdentity(); 
    2231  
    2232         glFrustum(-1, 1, -1, 1, 10, 100); 
    2233         glTranslatef(-0.5f, -0.5f, -0.5f); 
    2234         glTranslatef(0.0f, 0.0f, -15.0f); 
    2235         glMatrixMode(GL_MODELVIEW); 
    2236  
    2237         glEnable(GL_CULL_FACE); 
    2238         initCommon(); 
    2239         initPbuffer(); 
    2240  
    2241 } 
    2242  
    2243  
    2244 void GlDebuggerWidget::resizeGL(int w, int h) 
    2245 { 
    2246         glViewport(0, 0, w, h); 
    2247 } 
    2248  
    2249  
    2250 void GlDebuggerWidget::paintGL() 
    2251 { 
    2252         // draw a spinning cube into the pbuffer.. 
    2253         mRenderBuffer->makeCurrent(); 
    2254          
    2255         BeamSampleStatistics stats; 
    2256         mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats); 
    2257  
    2258         glFlush(); 
    2259  
    2260         // rendering directly to a texture is not supported on X11, unfortunately 
    2261     mRenderBuffer->updateDynamicTexture(dynamicTexture); 
    2262     
    2263     // and use the pbuffer contents as a texture when rendering the 
    2264     // background and the bouncing cubes 
    2265     makeCurrent(); 
    2266     glBindTexture(GL_TEXTURE_2D, dynamicTexture); 
    2267     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    2268  
    2269     // draw the background 
    2270     glMatrixMode(GL_MODELVIEW); 
    2271     glPushMatrix(); 
    2272     glLoadIdentity(); 
    2273     glMatrixMode(GL_PROJECTION); 
    2274     glPushMatrix(); 
    2275     glLoadIdentity(); 
    2276  
    2277         glPopMatrix(); 
    2278         glMatrixMode(GL_MODELVIEW); 
    2279         glPopMatrix(); 
    2280 } 
    2281  
    2282  
    2283 void GlDebuggerWidget::initPbuffer() 
    2284 { 
    2285         // set up the pbuffer context 
    2286     mRenderBuffer->makeCurrent(); 
    2287         /*mRenderBuffer->InitGL(); 
    2288  
    2289         glViewport(0, 0, mRenderBuffer->size().width(), mRenderBuffer->size().height()); 
    2290         glMatrixMode(GL_PROJECTION); 
    2291         glLoadIdentity(); 
    2292         glOrtho(-1, 1, -1, 1, -99, 99); 
    2293         glTranslatef(-0.5f, -0.5f, 0.0f); 
    2294         glMatrixMode(GL_MODELVIEW); 
    2295         glLoadIdentity(); 
    2296  
    2297         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);*/ 
    2298          
    2299         // generate a texture that has the same size/format as the pbuffer 
    2300     dynamicTexture = mRenderBuffer->generateDynamicTexture(); 
    2301  
    2302         // bind the dynamic texture to the pbuffer - this is a no-op under X11 
    2303         mRenderBuffer->bindToDynamicTexture(dynamicTexture); 
    2304         makeCurrent(); 
    2305 } 
    2306  
    2307 void GlDebuggerWidget::initCommon() 
    2308 { 
    2309         glEnable(GL_TEXTURE_2D); 
    2310         glEnable(GL_DEPTH_TEST); 
    2311  
    2312         glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
    2313 } 
    2314  
    2315 } 
     547} 
  • GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h

    r1008 r1145  
    33 
    44//#include "glInterface.h" 
    5 #include <QtOpenGL> 
    6 #include <QWaitCondition> 
    7  
     5 
     6//#include <QWaitCondition> 
     7//#include <QtOpenGL> 
    88//#include <QGLPixelBuffer> 
     9 
     10//class QWidget; 
    911 
    1012#include "Vector3.h" 
     
    1416#include "Beam.h" 
    1517 
    16 class QWidget; 
    1718 
    1819namespace GtpVisibilityPreprocessor { 
     
    105106  bool mUseGlLists; 
    106107   
    107   QString mSnapPrefix; 
     108  string mSnapPrefix; 
    108109 
    109110  KdTree *mKdTree; 
    110111 
    111   QWaitCondition mRenderingFinished; 
     112  //QWaitCondition mRenderingFinished; 
    112113   
    113114  vector<OcclusionQuery *> mOcclusionQueries; 
     
    117118                         KdTree *tree); 
    118119   
    119   ~GlRenderer(); 
     120  virtual ~GlRenderer(); 
    120121 
    121122 
     
    151152 
    152153 
    153 class GlRendererBuffer : public QObject, public QGLPixelBuffer, public GlRenderer 
     154class GlRendererBuffer: public GlRenderer 
    154155{ 
    155 Q_OBJECT 
     156 
     157//Q_OBJECT 
    156158public: 
    157 GlRendererBuffer(const int w, 
    158                                  const int h, 
    159                                  SceneGraph *sceneGraph, 
     159GlRendererBuffer(SceneGraph *sceneGraph, 
    160160                                 ViewCellsManager *viewcells, 
    161161                                 KdTree *tree); 
     
    182182                                                  vector<RenderCostSample> &samples, 
    183183                                                  const bool useOcclusionQueries, 
    184                                                   const int threshold = 0); 
    185  
    186  
    187   void 
    188   EvalPvsStat(); 
    189  
    190   void 
    191   ClearErrorBuffer(); 
    192    
    193  
    194   virtual int GetWidth() const { return width(); } 
    195   virtual int GetHeight() const { return height(); } 
     184                                                  const int threshold = 0) 
     185        {} 
     186 
     187        /** Implerment in subclasses. 
     188        */ 
     189        void EvalPvsStat() {}; 
     190 
     191        void ClearErrorBuffer(); 
     192   
     193 
     194  virtual int GetWidth() const { return 0; } 
     195  virtual int GetHeight() const { return 0; } 
    196196 
    197197 
     
    230230  int mPvsStatFrames; 
    231231  struct PvsErrorEntry { 
    232         PvsErrorEntry() {} 
    233         float mError; 
    234         int mPvsSize; 
    235         Vector3 mPosition; 
    236         Vector3 mDirection; 
     232          PvsErrorEntry() {} 
     233          float mError; 
     234          int mPvsSize; 
     235          Vector3 mPosition; 
     236          Vector3 mDirection; 
    237237  }; 
    238238   
     
    240240 
    241241   
    242 private: 
    243   unsigned int *mPixelBuffer; 
     242protected: 
     243        unsigned int *mPixelBuffer; 
    244244   
    245245        static void GenQueries(const int numQueries); 
     
    258258 
    259259public: 
    260   signals: 
    261         void UpdatePvsErrorItem(int i, GlRendererBuffer::PvsErrorEntry &); 
    262 }; 
    263  
    264  
    265 class RendererControlWidget : public QWidget 
    266 { 
    267   Q_OBJECT 
    268 public: 
    269  
    270   QListWidget *mPvsErrorWidget; 
    271  
    272   RendererControlWidget(QWidget * parent = 0, Qt::WFlags f = 0); 
    273  
    274   public slots: 
    275  
    276   void FocusNextPvsErrorFrame(); 
    277   void UpdatePvsErrorItem(int i, 
    278                                                   GlRendererBuffer::PvsErrorEntry &); 
    279  
    280   signals: 
    281    
    282   void SetViewCellGranularity(int); 
    283   void SetSceneCut(int); 
    284   void SetTopDistance(int); 
    285   void SetVisibilityFilterSize(int); 
    286   void SetSpatialFilterSize(int); 
    287  
    288   void SetRenderFilter(bool); 
    289   void SetUseFilter(bool); 
    290   void SetUseSpatialFilter(bool); 
    291   void SetRenderErrors(bool); 
    292   void SetShowViewCells(bool); 
    293   void SetShowRenderCost(bool); 
    294   void SetShowPvsSizes(bool); 
    295   void SetTopView(bool); 
    296   void SetCutViewCells(bool); 
    297   void SetCutScene(bool); 
    298  
    299    
    300 }; 
    301  
    302 class GlRendererWidget : public QGLWidget, public GlRenderer 
    303 { 
    304   Q_OBJECT 
    305 public: 
    306  
    307   // point of the last mouse click used for movement in the scene 
    308   Vector3 mousePoint; 
    309  
    310   bool mTopView; 
    311   bool mRenderViewCells; 
    312   bool mCutViewCells; 
    313   bool mCutScene; 
    314   bool mRenderErrors; 
    315   bool mRenderFilter; 
    316   bool mUseFilter; 
    317   bool mUseSpatialFilter; 
    318   bool mShowRenderCost; 
    319    
    320   bool mShowPvsSizes; 
    321   float mSpatialFilterSize; 
    322    
    323   Plane3 mSceneCutPlane; 
    324   float mTopDistance; 
    325  
    326   // some statistics 
    327   int mPvsSize; 
    328   float mRenderError; 
    329  
    330   RendererControlWidget *mControlWidget; 
    331    
    332   GlRendererWidget(SceneGraph *sceneGraph, 
    333                                    ViewCellsManager *viewcells, 
    334                                    KdTree *tree, 
    335                                    QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WFlags f = 0 
    336                                    ); 
    337  
    338  
    339   virtual void SetupCamera(); 
    340  
    341   void initializeGL() { 
    342         InitGL(); 
    343   } 
    344   void resizeGL(int w, int h); 
    345   void paintGL(); 
    346   void timerEvent(QTimerEvent *) { 
    347           update(); 
    348   } 
    349  
    350   void mousePressEvent(QMouseEvent *); 
    351   void mouseReleaseEvent(QMouseEvent *); 
    352   void mouseMoveEvent(QMouseEvent *); 
    353  
    354   void keyPressEvent ( QKeyEvent * e ) ; 
    355  
    356   void 
    357   RenderPvs(); 
    358  
    359   float 
    360   RenderErrors(); 
    361   void 
    362   RenderInfo(); 
    363  
    364   virtual int GetWidth() const { return width(); } 
    365   virtual int GetHeight() const { return height(); } 
    366  
    367  virtual void 
    368   SetupProjection(const int w, const int h, const float angle = 70.0f); 
    369  
    370   void 
    371   RenderViewCells(); 
    372  
    373  public slots: 
    374  
    375  void SetRenderErrors(bool b) { 
    376    mRenderErrors = b; 
    377    updateGL(); 
    378  } 
    379  
    380  void SetRenderFilter(bool b) { 
    381    mRenderFilter = b; 
    382    updateGL(); 
    383  } 
    384  
    385   void SetUseFilter(bool b) { 
    386    mUseFilter = b; 
    387    updateGL(); 
    388  } 
    389  
    390   void SetUseSpatialFilter(bool b) { 
    391         mUseSpatialFilter = b; 
    392         updateGL(); 
    393   } 
    394  
    395    
    396   void 
    397   SetViewCellGranularity(int number); 
    398    
    399   void 
    400   SetVisibilityFilterSize(int number); 
    401  
    402   void 
    403   SetSpatialFilterSize(int number); 
    404    
    405   void 
    406   SetSceneCut(int cut); 
    407    
    408   void 
    409   SetTopDistance(int dist); 
    410    
    411   void SetShowViewCells(bool b) { 
    412         mRenderViewCells = b; 
    413         updateGL(); 
    414   } 
    415  
    416   void SetShowRenderCost(bool b) { 
    417         mShowRenderCost = b; 
    418         updateGL(); 
    419   } 
    420  
    421   void SetShowPvsSizes(bool b) { 
    422         mShowPvsSizes = b; 
    423         updateGL(); 
    424   } 
    425  
    426   void SetTopView(bool b) { 
    427         mTopView = b; 
    428         updateGL(); 
    429   } 
    430  
    431   void SetCutViewCells(bool b) { 
    432         mCutViewCells = b; 
    433         updateGL(); 
    434   } 
    435   void SetCutScene(bool b) { 
    436         mCutScene = b; 
    437         updateGL(); 
    438   } 
    439  
    440  
    441 }; 
    442  
    443  
    444 extern GlRendererWidget *rendererWidget; 
    445  
    446 class GlDebuggerWidget : public QGLWidget 
    447 { 
    448         Q_OBJECT 
    449 public: 
    450     GlDebuggerWidget(GlRendererBuffer *buf, QWidget *parent = NULL); 
    451     ~GlDebuggerWidget(); 
    452     void initializeGL(); 
    453     void resizeGL(int w, int h); 
    454     void paintGL(); 
    455     void timerEvent(QTimerEvent *) { update(); } 
    456     void mousePressEvent(QMouseEvent *) { killTimer(timerId); } 
    457     void mouseReleaseEvent(QMouseEvent *) { timerId = startTimer(20); } 
    458  
    459     void initCommon(); 
    460     void initPbuffer(); 
    461  
    462    
    463          GlRendererBuffer *mRenderBuffer; 
    464  
    465          Beam mBeam; 
    466          int mSamples; 
    467          Intersectable *mSourceObject; 
    468  
    469 private: 
    470     GLuint dynamicTexture; 
    471     int timerId; 
    472 }; 
    473  
    474 extern GlDebuggerWidget *debuggerWidget; 
     260        // matt: remove qt dependencies 
     261 // signals: 
     262//      void UpdatePvsErrorItem(int i, GlRendererBuffer::PvsErrorEntry &); 
     263}; 
    475264 
    476265}; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/OcclusionQuery.cpp

    r1001 r1145  
    1 //#include "glInterface.h" 
    21#include "OcclusionQuery.h" 
    32#include <iostream> 
    4 //#include <GL/gl.h> 
    5 //#include <QtOpenGL> 
    63#include <glInterface.h> 
    74 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp

    r1144 r1145  
    2121const static bool ADDITIONAL_GEOMETRY_HACK = false; 
    2222 
    23 Preprocessor *preprocessor; 
     23//Preprocessor *preprocessor; 
    2424 
    2525 
     
    163163  cout << "done.\n"; 
    164164  
    165 #if 0 
    166   cout << "Deleting vsp osp tree...\n"; 
    167   DEL_PTR(mVspOspTree); 
     165  cout << "Deleting vsp tree...\n"; 
     166  DEL_PTR(mVspTree); 
    168167  cout << "done.\n"; 
    169 #endif 
     168 
     169  cout << "Deleting osp tree...\n"; 
     170  DEL_PTR(mOspTree); 
     171  cout << "done.\n"; 
    170172 
    171173  cout << "Deleting vspbsp tree...\n"; 
     
    408410                // NOTE: render texture should be power of 2 and square 
    409411                // renderer must be initialised 
    410                 renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree); 
     412                // $$matt 
     413//              renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree); 
    411414                //              renderer->makeCurrent(); 
    412415                 
     
    468471 
    469472 
    470 inline bool ilt(Intersectable *obj1, Intersectable *obj2) 
     473static inline bool ilt(Intersectable *obj1, Intersectable *obj2) 
    471474{ 
    472475        return obj1->mId < obj2->mId; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h

    r1022 r1145  
    88#include "KdTree.h" 
    99 
    10 #include <QObject> 
     10// matt: remove qt dependencies 
     11//#include <QObject> 
    1112 
    1213namespace GtpVisibilityPreprocessor { 
     
    3334*/ 
    3435   
    35   /** Main class of the visibility preprocessor. Responsible for loading and 
    36       saving of the input and output files. Initiates construction of the kD-tree, 
    37       viewcell loading/generation and the visibility computation itself. 
    38   */ 
    39 class Preprocessor : public QObject { 
    40   Q_OBJECT 
     36/** Main class of the visibility preprocessor. Responsible for loading and 
     37    saving of the input and output files. Initiates construction of the kD-tree, 
     38    viewcell loading/generation and the visibility computation itself. 
     39*/ 
     40// matt: remove qt dependencies 
     41class Preprocessor// : public QObject  
     42{ 
     43  //Q_OBJECT 
    4144 
    4245public: 
     
    4952  /** Load the input scene.  
    5053      @param filename file to load 
    51         @return true on success 
     54          @return true on success 
    5255  */ 
    5356  virtual bool LoadScene(const string filename); 
     
    202205 
    203206  GlRendererBuffer *renderer; 
    204    
    205   signals: 
     207// matt: remove qt dependencies  
     208//signals: 
    206209  void EvalPvsStat(); 
    207210 
    208211}; 
    209212 
    210  
    211  
    212 extern Preprocessor *preprocessor; 
     213//extern Preprocessor *preprocessor; 
    213214 
    214215} 
  • GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.cpp

    r878 r1145  
    1 #include <QApplication> 
    2  
     1//#include <QApplication> 
    32#include "PreprocessorThread.h" 
    43#include "Camera.h" 
     
    1110 
    1211 
     12// matt: remove qt dependencies 
     13/* 
    1314PreprocessorThread::PreprocessorThread(Preprocessor *p, 
    1415                                                                           QObject *parent):QThread(parent) 
    1516{ 
    1617  mPreprocessor = p; 
     18   
    1719  if (p->mQuitOnFinish) 
    1820        connect(this, SIGNAL(finished()), qApp, SLOT(closeAllWindows(void))); 
    1921} 
     22*/ 
    2023 
    21 void 
    22 PreprocessorThread::Main() 
     24PreprocessorThread::PreprocessorThread(Preprocessor *p): 
     25mPreprocessor(p) 
    2326{ 
    24    
    25   Camera camera; 
    26  
    27   if (0) { 
    28         // camera.LookAtBox(mPreprocessor->mKdTree->GetBox()); 
    29          //     camera.LookInBox(mPreprocessor->mKdTree->GetBox()); 
    30         camera.SetPosition(Vector3(3473, 6.778, -1699)); 
    31         camera.SetDirection(Vector3(-0.2432, 0, 0.97)); 
    32         //      camera.SetPosition(Vector3(991.7, 187.8, -271)); 
    33         //      camera.SetDirection(Vector3(0.9, 0, -0.4)); 
    34  
    35     camera.SnapImage("camera.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph); 
    36   }  
    37  
    38   if (0) { 
    39     camera.LookInBox(mPreprocessor->mKdTree->GetBox()); 
    40     camera.SetPosition(camera.mPosition + Vector3(-250,0,-550)); 
    41     camera.SnapImage("camera2.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph); 
    42   } 
    43  
    44   if (0) { 
    45     camera.SetPosition( mPreprocessor->mKdTree->GetBox().Center() - Vector3(0,-100,0) ); 
    46         camera.SetDirection(Vector3(1, 0, 0)); 
    47         camera.SnapImage("camera3.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph); 
    48   } 
    49  
    50   if (mPreprocessor->mComputeVisibility) { 
    51     mPreprocessor->ComputeVisibility(); 
    52         //      mPreprocessor->ExportPreprocessedData("scene.vis"); 
    53         mPreprocessor->PostProcessVisibility(); 
    54   } 
    55    
     27} 
    5628 
    5729 
    58   cerr << "Preprocessor main finished...\n"; 
     30void PreprocessorThread::operator()() 
     31{ 
     32        Main(); 
     33} 
     34 
     35void PreprocessorThread::Main() 
     36{ 
     37        Camera camera; 
     38 
     39        if (0)  
     40        { 
     41                // camera.LookAtBox(mPreprocessor->mKdTree->GetBox()); 
     42                //      camera.LookInBox(mPreprocessor->mKdTree->GetBox()); 
     43                camera.SetPosition(Vector3(3473, 6.778, -1699)); 
     44                camera.SetDirection(Vector3(-0.2432, 0, 0.97)); 
     45                //      camera.SetPosition(Vector3(991.7, 187.8, -271)); 
     46                //      camera.SetDirection(Vector3(0.9, 0, -0.4)); 
     47 
     48                camera.SnapImage("camera.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph); 
     49        }  
     50 
     51        if (0) { 
     52                camera.LookInBox(mPreprocessor->mKdTree->GetBox()); 
     53                camera.SetPosition(camera.mPosition + Vector3(-250,0,-550)); 
     54                camera.SnapImage("camera2.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph); 
     55        } 
     56 
     57        if (0) { 
     58                camera.SetPosition( mPreprocessor->mKdTree->GetBox().Center() - Vector3(0,-100,0) ); 
     59                camera.SetDirection(Vector3(1, 0, 0)); 
     60                camera.SnapImage("camera3.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph); 
     61        } 
     62 
     63        if (mPreprocessor->mComputeVisibility) { 
     64                mPreprocessor->ComputeVisibility(); 
     65                //      mPreprocessor->ExportPreprocessedData("scene.vis"); 
     66                mPreprocessor->PostProcessVisibility(); 
     67        } 
     68 
     69        cerr << "Preprocessor main finished...\n"; 
    5970   
    6071} 
  • GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.h

    r860 r1145  
    11#ifndef __PREPROCESSOR_THREAD_H 
    22#define __PREPROCESSOR_THREAD_H 
    3  
    4 #include <QThread> 
     3// matt: remove qt dependencies 
     4//#include <QThread> 
    55 
    66namespace GtpVisibilityPreprocessor { 
     
    88class Preprocessor; 
    99 
    10 class PreprocessorThread : public QThread 
     10/** This class represents a preprocessor thread. 
     11*/ 
     12class PreprocessorThread//: public QThread 
    1113{ 
    12   Q_OBJECT 
     14  //Q_OBJECT 
    1315 
    1416  Preprocessor *mPreprocessor; 
    1517public: 
    16   PreprocessorThread(Preprocessor *p, QObject *parent = 0); 
     18  //PreprocessorThread(Preprocessor *p, QObject *parent = 0); 
     19        PreprocessorThread(Preprocessor *p); 
    1720  ~PreprocessorThread(); 
     21 
     22  void operator()(); 
    1823 
    1924  void Main(); 
    2025 
    21 protected: 
     26/*protected: 
    2227  void run() { 
    2328        Main(); 
    24   } 
     29  }*/ 
    2530}; 
    2631 
  • GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp

    r1112 r1145  
    484484{ 
    485485  // compute rendering error 
     486         
    486487  if (renderer && renderer->mPvsStatFrames) { 
    487488        //      emit EvalPvsStat(); 
     
    835836 
    836837        if (0 && mPass > 0) { 
     838                char buf[100]; 
    837839          if (mUseImportanceSampling) 
    838                 renderer->mSnapPrefix.sprintf("snap/i-%02d-", mPass); 
     840          { 
     841                sprintf(buf, "snap/i-%02d-", mPass); 
     842 
     843                renderer->mSnapPrefix = buf; 
     844          } 
    839845          else 
    840                 renderer->mSnapPrefix.sprintf("snap/r-%02d-", mPass); 
     846          { 
     847                sprintf(buf, "snap/r-%02d-", mPass); 
     848 
     849                renderer->mSnapPrefix = buf; 
     850          } 
     851 
    841852          renderer->mSnapErrorFrames = true; 
    842853        } 
  • GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp

    r1112 r1145  
    20862086        //      exporter->ExportKdTree(*mKdTree); 
    20872087        exporter->SetWireframe(); 
    2088         exporter->ExportScene(preprocessor->mSceneGraph->mRoot); 
     2088//      exporter->ExportScene(preprocessor->mSceneGraph->mRoot); 
    20892089        exporter->SetWireframe(); 
    20902090        exporter->ExportBox(box); 
  • GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h

    r1142 r1145  
    250250        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; } 
    251251 
    252         int IncMail() { return ++mMailbox - sMailId; } 
     252        int IncMail() { return ++ mMailbox - sMailId; } 
    253253 
    254254 
  • GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp

    r1144 r1145  
    5353mMinPvsSize(0), // one means only empty view cells are invalid 
    5454mMaxPvsRatio(1.0), 
    55 mViewCellPvsIsUpdated(false) 
     55mViewCellPvsIsUpdated(false), 
     56mPreprocessor(NULL) 
    5657{ 
    5758        mViewSpaceBox.Initialize(); 
     
    343344        SimpleRayContainer simpleRays; 
    344345 
    345         preprocessor->GenerateRays(samplesPerPass, 
     346        mPreprocessor->GenerateRays(samplesPerPass, 
    346347                                                           sampleType, 
    347348                                                           simpleRays); 
    348349 
    349350        // shoot simple ray and add it to importance samples 
    350         preprocessor->CastRays(simpleRays, passSamples); 
     351        mPreprocessor->CastRays(simpleRays, passSamples); 
    351352 
    352353        return (int)passSamples.size(); 
     
    390391int ViewCellsManager::Construct(Preprocessor *preprocessor, VssRayContainer *outRays) 
    391392{ 
     393        mPreprocessor = preprocessor; 
     394 
    392395        int numSamples = 0; 
    393396 
     
    544547        if (mEvaluateViewCells) 
    545548        { 
    546                 EvalViewCellPartition(preprocessor); 
     549                EvalViewCellPartition(); 
    547550        } 
    548551 
     
    597600        int histoMaxVal; 
    598601        Environment::GetSingleton()->GetIntValue("Preprocessor.histogram.maxValue", histoMaxVal); 
    599         maxRenderCost = max(histoMaxVal, maxRenderCost); 
     602        maxRenderCost = max((float)histoMaxVal, maxRenderCost); 
    600603 
    601604         
     
    872875 
    873876 
    874 void ViewCellsManager::EvalViewCellPartition(Preprocessor *preprocessor) 
     877void ViewCellsManager::EvalViewCellPartition() 
    875878{ 
    876879        int samplesPerPass; 
     
    895898        cout << "reseting pvs ... "; 
    896899                 
    897  
    898         bool startFromZero = true; 
     900        const bool startFromZero = true; 
    899901 
    900902        // reset pvs and start over from zero 
     
    903905                mViewCellsTree->ResetPvs(); 
    904906        } 
    905         else // statistics without addidtional samples 
    906         { 
     907        else // start from current sampless 
     908        { 
     909                // statistics before casting more samples 
    907910                cout << "compute new statistics ... "; 
    908911                sprintf(s, "-%09d-eval.log", castSamples); 
     
    10151018                } 
    10161019        } 
    1017  
    1018         // find empty view cells bug 
    1019         if (TEST_EMPTY_VIEW_CELLS) 
    1020         { 
    1021                 TestEmptyViewCells(preprocessor->mObjects); 
    1022         } 
    10231020} 
    10241021 
     
    10301027 
    10311028 
    1032 // Returns index of the best view cells of the neighborhood 
     1029/// Returns index of the best view cells of the neighborhood 
    10331030int GetBestViewCellIdx(ViewCell *root, const ViewCellContainer &neighborhood) 
    10341031{ 
     
    10701067         
    10711068        case PER_TRIANGLE: 
    1072                 {cout << "pertriangle" << endl; 
     1069                {//cout << "pertriangle" << endl; 
    10731070                        // HACK 
    10741071                        MeshInstance *mi = dynamic_cast<MeshInstance *>(obj); 
     
    10771074                        if (mi->GetMesh()) 
    10781075                        { 
    1079                                 return mi->GetMesh()->mFaces.size(); 
     1076                                return (float)mi->GetMesh()->mFaces.size(); 
    10801077                        } 
    10811078                } 
     
    12921289        sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs); 
    12931290 
    1294         int start = mViewCells.size()*minValid; 
    1295         int end = mViewCells.size()*maxValid; 
     1291        int start = mViewCells.size() * minValid; 
     1292        int end = mViewCells.size() * maxValid; 
    12961293 
    12971294        for (int i = 0; i < mViewCells.size(); ++ i) 
     
    19571954float ViewCellsManager::GetRendercost(ViewCell *viewCell) const 
    19581955{ 
    1959         return mViewCellsTree->GetPvsSize(viewCell); 
     1956        return (float)mViewCellsTree->GetPvsSize(viewCell); 
    19601957} 
    19611958 
     
    24492446 
    24502447 
    2451 /**********************************************************************/ 
    2452 /*                 BspViewCellsManager implementation                 */ 
    2453 /**********************************************************************/ 
     2448/*******************************************************************/ 
     2449/*               BspViewCellsManager implementation                */ 
     2450/*******************************************************************/ 
    24542451 
    24552452 
     
    45784575        vector<RenderCostSample> samples; 
    45794576   
    4580         if (!preprocessor->GetRenderer()) 
     4577        if (!mPreprocessor->GetRenderer()) 
    45814578                return; 
    45824579 
    4583         //start the from point queries 
     4580        //start the view point queries 
    45844581        long startTime = GetTime(); 
    45854582        cout << "starting sampling of render cost ... "; 
    45864583         
    4587         preprocessor->GetRenderer()->SampleRenderCost(numSamples, samples, true); 
     4584        mPreprocessor->GetRenderer()->SampleRenderCost(numSamples, samples, true); 
    45884585 
    45894586        cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 
     
    49164913        // print subdivision statistics 
    49174914        Debug << mVspTree->GetStatistics() << endl; 
     4915        Debug << mOspTree->GetStatistics() << endl; 
    49184916 
    49194917        // print view cell statistics 
     
    53335331         
    53345332                        const int savedColorCode = mColorCode; 
     5333                        mColorCode = 0; 
    53355334                        const int maxPvs = 200;//mOspTree.GetStatistics().maxPvs; 
    53365335 
    53375336                        exporter->ExportOspTree(*mOspTree, mColorCode == 0 ? 0 : maxPvs); 
     5337 
     5338                        mColorCode = savedColorCode; 
    53385339 
    53395340                        delete exporter; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h

    r1142 r1145  
    4141 
    4242 
    43 /** Probably Visible Set */ 
     43/** Probably Visible Set  
     44*/ 
    4445class PrVs  
    4546{ 
     
    379380        void SetViewCellsActive(); 
    380381 
    381         /** Evaluates worth of current view cell hierarchy. 
    382         */ 
    383         void EvalViewCellPartition(Preprocessor *preprocessor); 
     382        /** Evaluates render cost statistics of current view cell hierarchy. 
     383        */ 
     384        void EvalViewCellPartition(); 
    384385 
    385386        /** Sets maximal size of a view cell filter. 
     
    479480 
    480481protected: 
     482 
    481483        /** Exports bounding boxes as xml stream 
    482484        */ 
     
    570572        //////////////////////////////////////////////// 
    571573 
    572         /// if bounding boxes should also be exported 
     574        Preprocessor *mPreprocessor; 
     575        /// if bounding boxes should be exported together with the view cells 
    573576        bool mExportBboxesForPvs; 
    574577                 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp

    r1141 r1145  
    640640        // compute first split candidate 
    641641        VspBspSplitCandidate splitCandidate; 
    642         EvalSplitCandidate(tData, splitCandidate); 
     642        splitCandidate.mParentData = tData; 
     643 
     644        EvalSplitCandidate(splitCandidate); 
    643645 
    644646        tQueue.push(splitCandidate); 
     
    814816                        // evaluate subdivision stats 
    815817                        if (1) 
    816                         { 
    817                                 const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
    818                                 const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
    819                                 const float cData = (float)tData.mPvs * tData.mProbability;; 
    820  
    821                 const float costDecr = (cFront + cBack - cData) / mBox.GetVolume(); 
    822  
    823                                 mTotalCost += costDecr; 
    824                                 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 
    825  
    826                                 AddSubdivisionStats(mBspStats.Leaves(), 
    827                                                                     -costDecr, 
    828                                                                         0, 
    829                                                                         mTotalCost, 
    830                                                                         (float)mTotalPvsSize / (float)mBspStats.Leaves()); 
    831                         } 
     818                                EvalSubdivisionStats(tData, tFrontData, tBackData); 
     819                         
    832820 
    833821                        // push the children on the stack 
     
    964952                //-- push the new split candidates on the stack 
    965953                VspBspSplitCandidate frontCandidate; 
     954                frontCandidate.mParentData = tFrontData; 
     955 
    966956                VspBspSplitCandidate backCandidate; 
    967  
    968                 EvalSplitCandidate(tFrontData, frontCandidate); 
    969                 EvalSplitCandidate(tBackData, backCandidate); 
     957                backCandidate.mParentData = tBackData; 
     958 
     959                EvalSplitCandidate(frontCandidate); 
     960                EvalSplitCandidate(backCandidate); 
    970961         
    971962                tQueue.push(frontCandidate); 
     
    10471038 
    10481039 
     1040/* 
    10491041void VspBspTree::EvalSplitCandidate(VspBspTraversalData &tData, 
    10501042                                                                        VspBspSplitCandidate &splitData) 
     
    10671059        splitData.mParentData = tData; 
    10681060        splitData.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1; 
     1061} 
     1062*/ 
     1063 
     1064void VspBspTree::EvalSplitCandidate(VspBspSplitCandidate &splitCandidate) 
     1065{ 
     1066        VspBspTraversalData frontData; 
     1067        VspBspTraversalData backData; 
     1068         
     1069        BspLeaf *leaf = dynamic_cast<BspLeaf *>(splitCandidate.mParentData.mNode); 
     1070         
     1071        // compute locally best split plane 
     1072    bool success = SelectPlane(splitCandidate.mSplitPlane, leaf, splitCandidate.mParentData,  
     1073                                                           frontData, backData, splitCandidate.mSplitAxis); 
     1074 
     1075        float oldRenderCost; 
     1076 
     1077        // compute global decrease in render cost 
     1078        const float renderCostDecr = EvalRenderCostDecrease(splitCandidate.mSplitPlane,  
     1079                                                                                                                splitCandidate.mParentData, 
     1080                                                                                                                oldRenderCost); 
     1081 
     1082        splitCandidate.mRenderCostDecr = renderCostDecr; 
     1083 
     1084        // TODO: geometry could be reused 
     1085        delete frontData.mGeometry; 
     1086        delete backData.mGeometry; 
     1087 
     1088        // set priority for queue 
     1089#if 0 
     1090        const float priority = (float)-data.mDepth; 
     1091#else    
     1092 
     1093        // take render cost of node into account  
     1094        // otherwise danger of being stuck in a local minimum!! 
     1095        const float factor = mRenderCostDecreaseWeight; 
     1096        const float priority = factor * renderCostDecr + (1.0f - factor) * oldRenderCost; 
     1097#endif 
     1098         
     1099        splitCandidate.mPriority = priority; 
     1100 
     1101        // max cost threshold violated? 
     1102        splitCandidate.mMaxCostMisses =  
     1103                success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1; 
     1104} 
     1105 
     1106 
     1107void VspBspTree::EvalSubdivisionStats(const VspBspTraversalData &tData, 
     1108                                                                          const VspBspTraversalData &tFrontData, 
     1109                                                                          const VspBspTraversalData &tBackData) 
     1110{ 
     1111        const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
     1112        const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
     1113        const float cData = (float)tData.mPvs * tData.mProbability; 
     1114         
     1115        const float costDecr =  
     1116                (cFront + cBack - cData) / mBox.GetVolume(); 
     1117 
     1118        mTotalCost += costDecr; 
     1119        mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 
     1120 
     1121        AddSubdivisionStats(mBspStats.Leaves(), 
     1122                                                -costDecr, 
     1123                                                0, 
     1124                                                mTotalCost, 
     1125                                                (float)mTotalPvsSize / (float)mBspStats.Leaves()); 
    10691126} 
    10701127 
     
    18961953 
    18971954float VspBspTree::EvalRenderCostDecrease(const Plane3 &candidatePlane, 
    1898                                                                                  const VspBspTraversalData &data) const 
     1955                                                                                 const VspBspTraversalData &data, 
     1956                                                                                 float &normalizedOldRenderCost) const 
    18991957{ 
    19001958        float pvsFront = 0; 
     
    19722030        const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack; 
    19732031 
    1974         //Debug << "decrease: " << oldRenderCost - newRenderCost << endl; 
    19752032        const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBox.GetVolume(); 
    19762033         
    1977         const float weight = mRenderCostDecreaseWeight; 
    19782034        // take render cost of node into account to avoid being stuck in a local minimum 
    1979         const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume(); 
    1980          
    1981         //Debug << "rendercostdecr: " << weight * renderCostDecrease << " old render cost: " << (1.0f - weight) * normalizedOldRenderCost << endl; 
    1982         return weight * renderCostDecrease + (1.0f - weight) * normalizedOldRenderCost; 
     2035        normalizedOldRenderCost = oldRenderCost / mBox.GetVolume(); 
     2036         
     2037        return renderCostDecrease; 
    19832038} 
    19842039 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h

    r1133 r1145  
    170170                float mPriority; 
    171171 
    172                 VspBspSplitCandidate(): mPriority(0)  
     172                float mRenderCostDecr; 
     173 
     174                VspBspSplitCandidate(): mPriority(0), mRenderCostDecr(0)  
    173175                {}; 
    174176 
    175177                VspBspSplitCandidate(const Plane3 &plane, const VspBspTraversalData &tData):  
    176                 mSplitPlane(plane), mParentData(tData), mPriority(0) 
     178                mSplitPlane(plane), mParentData(tData), mPriority(0), mRenderCostDecr(0)  
    177179                {} 
    178180 
     
    404406        /** Evaluates candidate for splitting. 
    405407        */ 
    406         void EvalSplitCandidate(VspBspTraversalData &tData, VspBspSplitCandidate &splitData); 
     408        void EvalSplitCandidate(VspBspSplitCandidate &splitData); 
    407409 
    408410        /** Computes priority of the traversal data and stores it in tData. 
     
    413415        */ 
    414416        float EvalRenderCostDecrease(const Plane3 &candidatePlane, 
    415                                                                  const VspBspTraversalData &data) const; 
     417                                                                 const VspBspTraversalData &data, 
     418                                                                 float &normalizedOldRenderCost) const; 
    416419 
    417420        /** Constructs tree using the split priority queue. 
     
    705708        //float GetMemUsage(const VspBspTraversalQueue &tstack) const; 
    706709 
     710 
     711        void EvalSubdivisionStats(const VspBspTraversalData &tData, 
     712                                                      const VspBspTraversalData &tFrontData, 
     713                                                          const VspBspTraversalData &tBackData 
     714                                                          ); 
    707715 
    708716        /** Adds stats to subdivision log file. 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp

    r1144 r1145  
    103103 
    104104 
     105void OspTreeStatistics::Print(ostream &app) const 
     106{ 
     107        app << "=========== OspTree statistics ===============\n"; 
     108 
     109        app << setprecision(4); 
     110 
     111        app << "#N_CTIME  ( Construction time [s] )\n" << Time() << " \n"; 
     112 
     113        app << "#N_NODES ( Number of nodes )\n" << nodes << "\n"; 
     114 
     115        app << "#N_INTERIORS ( Number of interior nodes )\n" << Interior() << "\n"; 
     116 
     117        app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n"; 
     118 
     119        app << "#AXIS_ALIGNED_SPLITS (number of axis aligned splits)\n" << splits[0] + splits[1] + splits[2] << endl; 
     120 
     121        app << "#N_SPLITS ( Number of splits in axes x y z)\n"; 
     122 
     123        for (int i = 0; i < 3; ++ i) 
     124                app << splits[i] << " "; 
     125        app << endl; 
     126 
     127        app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n"  
     128                <<      maxDepthNodes * 100 / (double)Leaves() << endl; 
     129 
     130        app << "#N_PMINPVSLEAVES  ( Percentage of leaves with mininimal PVS )\n"  
     131                << minPvsNodes * 100 / (double)Leaves() << endl; 
     132 
     133        //app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minimal number of rays)\n"  
     134        //      << minRaysNodes * 100 / (double)Leaves() << endl; 
     135 
     136        app << "#N_MAXCOSTNODES  ( Percentage of leaves with terminated because of max cost ratio )\n" 
     137                << maxCostNodes * 100 / (double)Leaves() << endl; 
     138 
     139        app << "#N_PMINPROBABILITYLEAVES  ( Percentage of leaves with mininum probability )\n" 
     140                << minProbabilityNodes * 100 / (double)Leaves() << endl; 
     141 
     142//      app << "#N_PMAXRAYCONTRIBLEAVES  ( Percentage of leaves with maximal ray contribution )\n"  
     143//              <<      maxRayContribNodes * 100 / (double)Leaves() << endl; 
     144 
     145        app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl; 
     146 
     147        app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl; 
     148 
     149        app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl; 
     150 
     151        app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl; 
     152 
     153//      app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl; 
     154        //app << "#N_PVS: " << pvs << endl; 
     155 
     156        app << "========== END OF VspTree statistics ==========\n"; 
     157} 
     158 
     159 
    105160/******************************************************************/ 
    106161/*                  class VspNode implementation                  */ 
     
    471526void VspTree::AddSubdivisionStats(const int viewCells, 
    472527                                                                  const float renderCostDecr, 
    473                                                                   const float splitCandidateCost, 
    474528                                                                  const float totalRenderCost, 
    475529                                                                  const float avgRenderCost) 
     
    478532                        << "#ViewCells\n" << viewCells << endl 
    479533                        << "#RenderCostDecrease\n" << renderCostDecr << endl  
    480                         << "#SplitCandidateCost\n" << splitCandidateCost << endl 
    481534                        << "#TotalRenderCost\n" << totalRenderCost << endl 
    482535                        << "#AvgRenderCost\n" << avgRenderCost << endl; 
     
    584637 
    585638 
     639void VspTree::EvalSubdivisionStats(const VspTraversalData &tData, 
     640                                                                   const VspTraversalData &tFrontData, 
     641                                                                   const VspTraversalData &tBackData 
     642                                                                   ) 
     643{ 
     644        const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
     645        const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
     646        const float cData = (float)tData.mPvs * tData.mProbability; 
     647         
     648        const float costDecr =  
     649                (cFront + cBack - cData) / mBoundingBox.GetVolume(); 
     650 
     651        mTotalCost += costDecr; 
     652        mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 
     653 
     654        AddSubdivisionStats(mVspStats.Leaves(), 
     655                                                -costDecr, 
     656                                                mTotalCost, 
     657                                                (float)mTotalPvsSize / (float)mVspStats.Leaves()); 
     658} 
     659 
     660 
    586661VspNode *VspTree::Subdivide(SplitQueue &tQueue, 
    587                                                         VspSplitCandidate &splitCandidate, 
     662                                                        SplitCandidate *splitCandidate, 
    588663                                                        const bool globalCriteriaMet) 
    589664{ 
    590         VspTraversalData &tData = splitCandidate.mParentData; 
     665        // doto remove dynamic cast 
     666        VspSplitCandidate *sc = dynamic_cast<VspSplitCandidate *>(splitCandidate); 
     667        VspTraversalData &tData = sc->mParentData; 
    591668 
    592669        VspNode *newNode = tData.mNode; 
     
    600677                 
    601678                // create new interior node and two leaf node 
    602                 const AxisAlignedPlane splitPlane = splitCandidate.mSplitPlane; 
     679                const AxisAlignedPlane splitPlane = sc->mSplitPlane; 
    603680                newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData); 
    604681         
    605                 const int maxCostMisses = splitCandidate.mMaxCostMisses; 
     682                const int maxCostMisses = sc->mMaxCostMisses; 
    606683 
    607684 
     
    611688                         
    612689         
    613                 if (1) 
    614                 { 
    615                         //-- subdivision statistics 
    616  
    617                         const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
    618                         const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
    619                         const float cData = (float)tData.mPvs * tData.mProbability; 
    620          
    621                         const float costDecr =  
    622                                 (cFront + cBack - cData) / mBoundingBox.GetVolume(); 
    623  
    624                         mTotalCost += costDecr; 
    625                         mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 
    626  
    627                         AddSubdivisionStats(mVspStats.Leaves(), 
    628                                                                 -costDecr, 
    629                                                                 splitCandidate.GetPriority(), 
    630                                                                 mTotalCost, 
    631                                                                 (float)mTotalPvsSize / (float)mVspStats.Leaves()); 
    632                 } 
    633  
    634  
     690                if (1) //-- subdivision statistics 
     691                        EvalSubdivisionStats(tData, tFrontData, tBackData); 
     692                 
    635693                //-- evaluate new split candidates for global greedy cost heuristics 
     694 
    636695                VspSplitCandidate *frontCandidate = new VspSplitCandidate(tFrontData); 
    637696                VspSplitCandidate *backCandidate = new VspSplitCandidate(tBackData); 
     
    645704                // delete old view cell 
    646705                delete tData.mNode->mViewCell; 
     706 
    647707                // delete old leaf node 
    648708                DEL_PTR(tData.mNode); 
     
    702762                SelectSplitPlane(splitCandidate.mParentData, splitCandidate.mSplitPlane, frontProb, backProb); 
    703763 
     764        float oldRenderCost; 
     765 
    704766        // compute global decrease in render cost 
    705         const float priority = EvalRenderCostDecrease(splitCandidate.mSplitPlane, splitCandidate.mParentData); 
     767        const float renderCostDecr = EvalRenderCostDecrease(splitCandidate.mSplitPlane,  
     768                                                                                                                splitCandidate.mParentData, 
     769                                                                                                                oldRenderCost); 
     770 
     771        splitCandidate.SetRenderCostDecrease(renderCostDecr); 
     772 
     773#if 0 
     774        const float priority = (float)-data.mDepth; 
     775#else    
     776 
     777        // take render cost of node into account  
     778        // otherwise danger of being stuck in a local minimum!! 
     779        const float factor = mRenderCostDecreaseWeight; 
     780        const float priority = factor * renderCostDecr + (1.0f - factor) * oldRenderCost; 
     781#endif 
     782         
    706783        splitCandidate.SetPriority(priority); 
    707         splitCandidate.mMaxCostMisses = success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1; 
     784 
     785        // max cost threshold violated? 
     786        splitCandidate.mMaxCostMisses =  
     787                success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1; 
    708788        //Debug << "p: " << tData.mNode << " depth: " << tData.mDepth << endl; 
    709789} 
     
    14041484         
    14051485        //if (axis != 1) 
    1406         Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox) 
    1407               <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl; 
     1486        //Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox) 
     1487        //      <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl; 
     1488 
     1489        const float volRatio = tData.mBoundingBox.GetVolume() / (sizeBox * mBoundingBox.GetVolume()); 
     1490 
     1491        Debug << "\n§§§§ eval local cost §§§§" << endl 
     1492                  << "back pvs: " << penaltyBack << " front pvs: " << penaltyFront << " total pvs: " << penaltyOld << endl  
     1493                  << "back p: " << pBack * volRatio << " front p " << pFront * volRatio << " p: " << pOverall * volRatio << endl 
     1494                  << "old rc: " << oldRenderCost * volRatio << " new rc: " << newRenderCost * volRatio << endl 
     1495                  << "render cost decrease: " << oldRenderCost * volRatio - newRenderCost * volRatio << endl; 
    14081496 
    14091497        return ratio; 
     
    14971585 
    14981586float VspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 
    1499                                                                           const VspTraversalData &data) const 
    1500 { 
    1501 #if 0 
    1502         return (float)-data.mDepth; 
    1503 #endif 
     1587                                                                          const VspTraversalData &data, 
     1588                                                                          float &normalizedOldRenderCost) const 
     1589{ 
    15041590        float pvsFront = 0; 
    15051591        float pvsBack = 0; 
     
    15111597        float pBack = 0; 
    15121598 
     1599        const float viewSpaceVol = mBoundingBox.GetVolume(); 
    15131600 
    15141601        // create unique ids for pvs heuristics 
    1515         Intersectable::NewMail(); 
     1602        Intersectable::NewMail(3); 
    15161603         
    15171604        RayInfoContainer::const_iterator rit, rit_end = data.mRays->end(); 
     
    15551642        const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack; 
    15561643 
     1644        normalizedOldRenderCost = oldRenderCost / viewSpaceVol; 
     1645 
    15571646        //Debug << "decrease: " << oldRenderCost - newRenderCost << endl; 
    1558         const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume(); 
    1559          
    1560         // take render cost of node into account  
    1561         // otherwise danger of being stuck in a local minimum!! 
    1562         const float factor = mRenderCostDecreaseWeight; 
    1563  
    1564         const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume(); 
    1565         return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost; 
     1647        const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol; 
     1648         
     1649         
     1650        Debug << "\n==== eval render cost decrease ===" << endl 
     1651                  << "back pvs: " << pvsBack << " front pvs " << pvsFront << " total pvs: " << totalPvs << endl  
     1652                  << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << " p: " << pOverall / viewSpaceVol << endl 
     1653                  << "old rc: " << normalizedOldRenderCost << " new rc: " << newRenderCost / viewSpaceVol << endl 
     1654                  << "render cost decrease: " << renderCostDecrease << endl; 
     1655 
     1656        return renderCostDecrease; 
    15661657} 
    15671658 
     
    15791670         
    15801671        // create unique ids for pvs heuristics 
    1581         Intersectable::NewMail(); 
     1672        Intersectable::NewMail(3); 
    15821673 
    15831674        const int pvsSize = data.mPvs; 
     
    16011692        pOverall = data.mProbability; 
    16021693 
    1603         // we take simplified computation for spatial mid split 
     1694        // we use spatial mid split => simplified computation 
    16041695        pBack = pFront = pOverall * 0.5f; 
    16051696         
     
    16251716                return; 
    16261717 
    1627         //const float renderCost = mViewCellsManager->EvalRenderCost(obj); 
     1718        //const float renderCost = mViewCellsManager->SimpleRay &raynderCost(obj); 
    16281719        const int renderCost = 1; 
    16291720 
     
    16341725        } 
    16351726 
    1636         // TODO: does this really belong to no pvs? 
     1727        // QUESTION matt: is it safe to assume that  
     1728        // the object belongs to no pvs in this case? 
    16371729        //if (cf == Ray::COINCIDENT) return; 
    16381730 
     
    21622254 
    21632255        Intersectable::NewMail(); 
    2164         ViewCell::NewMail(); 
     2256        //ViewCell::NewMail(); 
    21652257 
    21662258        Vector3 entp = origin; 
     
    22252317                        ViewCell *vc = leaf->GetViewCell(); 
    22262318 
    2227                         if (!vc->Mailed()) 
    2228                         { 
    2229                                 vc->Mail(); 
     2319                        // don't have to mail because each view cell belongs to exactly one leaf 
     2320                        //if (!vc->Mailed()) 
     2321                        //{ 
     2322                        //      vc->Mail(); 
    22302323                                viewcells.push_back(vc); 
    22312324                                ++ hits; 
    2232                         } 
     2325                        //} 
    22332326#if 0 
    22342327                        leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); 
     
    27852878        //-- debug output 
    27862879 
    2787         Debug << "******* OSP options ******** " << endl; 
     2880        Debug << "******* OSP tree options ******** " << endl; 
    27882881 
    27892882    Debug << "max depth: " << mTermMaxDepth << endl; 
     
    29513044 
    29523045KdNode *OspTree::Subdivide(SplitQueue &tQueue, 
    2953                                                    OspSplitCandidate &splitCandidate, 
     3046                                                   SplitCandidate *splitCandidate, 
    29543047                                                   const bool globalCriteriaMet) 
    29553048{ 
    2956         OspTraversalData &tData = splitCandidate.mParentData; 
     3049        OspSplitCandidate *sc = dynamic_cast<OspSplitCandidate *>(splitCandidate); 
     3050        OspTraversalData &tData = sc->mParentData; 
     3051 
    29573052        KdNode *newNode = tData.mNode; 
    29583053 
     
    29653060                 
    29663061                // create new interior node and two leaf node 
    2967                 const AxisAlignedPlane splitPlane = splitCandidate.mSplitPlane; 
     3062                const AxisAlignedPlane splitPlane = sc->mSplitPlane; 
    29683063                 
    29693064                newNode = SubdivideNode(splitPlane,  
     
    29723067                                                                tBackData); 
    29733068         
    2974                 const int maxCostMisses = splitCandidate.mMaxCostMisses; 
     3069                const int maxCostMisses = sc->mMaxCostMisses; 
    29753070 
    29763071                // how often was max cost ratio missed in this branch? 
     
    30153110                SelectSplitPlane(splitCandidate.mParentData, splitCandidate.mSplitPlane, frontProb, backProb); 
    30163111 
    3017         const float priority = EvalRenderCostDecrease(splitCandidate.mSplitPlane, splitCandidate.mParentData); 
     3112        float oldRenderCost; 
     3113 
     3114        // compute global decrease in render cost 
     3115        const float renderCostDecr = EvalRenderCostDecrease(splitCandidate.mSplitPlane,  
     3116                                                                                                                splitCandidate.mParentData, 
     3117                                                                                                                oldRenderCost); 
     3118 
     3119        splitCandidate.SetRenderCostDecrease(renderCostDecr); 
     3120 
     3121#if 0 
     3122        const float priority = (float)-data.mDepth; 
     3123#else    
     3124        // take render cost of node into account  
     3125        // otherwise danger of being stuck in a local minimum!! 
     3126        const float factor = mRenderCostDecreaseWeight; 
     3127        const float priority = factor * renderCostDecr + (1.0f - factor) * oldRenderCost; 
     3128 
     3129#endif 
     3130 
    30183131        // compute global decrease in render cost 
    30193132        splitCandidate.SetPriority(priority); 
     
    31123225        SortSplitCandidates(tData, axis, minBand, maxBand); 
    31133226 
    3114         float totalVol = PrepareHeuristics(tData); 
     3227        int numViewCells; 
     3228 
     3229        float totalVol = PrepareHeuristics(tData, numViewCells); 
    31153230        float voll = 0; 
    31163231        float volr = totalVol; 
     3232 
     3233        int vcl = 0; 
     3234        int vcr = numViewCells; 
    31173235   
    31183236        const int totalPvs = tData.mNode->mObjects.size(); 
     
    31213239        int pvsr = totalPvs; 
    31223240 
    3123         // if no good split can be found, take mid split 
     3241        float sum = (float)totalVol * sizeBox; 
     3242 
     3243        ///////////////////////////////// 
     3244 
     3245        // note: initialised to take mid split  
     3246        // if no good split can be found, 
    31243247        position = minBox + 0.5f * sizeBox; 
    31253248         
     
    31273250        float ratio = 99999999.0f; 
    31283251        bool splitPlaneFound = false; 
    3129     
    3130     float minSum = 1e20f; 
    31313252 
    31323253        float volBack = voll; 
    31333254        float volFront = volr; 
    31343255 
    3135         int pvsBack = 0; 
    3136         int pvsFront = 0; 
    3137          
    3138  
    3139         float sum = (float)totalVol * sizeBox; 
     3256        int pvsBack = pvsl; 
     3257        int pvsFront = pvsr; 
     3258         
     3259        float minSum = 1e20f; 
     3260 
     3261        ///////////////////////////// 
    31403262 
    31413263        Intersectable::NewMail(); 
     
    31503272                Intersectable *object = (*ci).mObject; 
    31513273 
    3152                 EvalHeuristicsContribution(*ci, voll, volr, pvsl, pvsr); 
    3153  
    3154                 cout << "incr: " << ci->mObject->mViewCellPvs.GetSize() << " obj id "  
    3155                          << ci->mObject->GetId() << endl; 
     3274                EvalHeuristicsContribution(tData.mNode,  
     3275                                                                   *ci,  
     3276                                                                   voll, volr,  
     3277                                                                   pvsl, pvsr, 
     3278                                                                   vcl, vcr); 
    31563279 
    31573280                // Note: sufficient to compare size of bounding boxes of front and back side? 
     3281 
    31583282                if (((*ci).mPos >= minBand) && ((*ci).mPos <= maxBand)) 
    31593283                { 
    3160                         //sum = costl * ((*ci).value - minBox) + costr * (maxBox - (*ci).value); 
    3161                         sum = voll * pvsBack + volr * pvsFront; 
    3162  
    3163                         cout << "pos: " << (*ci).mPos  
    3164                                  << "\t (pvsl: " << pvsBack << ", pvsr: " << pvsFront << ")" 
     3284                        sum = voll * pvsl + volr * pvsr; 
     3285 
     3286                        // note matt: can happen that volr is less than zero: bug or numerical error? 
     3287                        //if (volr < 0)         Debug << "warning!! " << totalVol << " " << volRightDecr << " " << volRightDecr - totalVol << endl; 
     3288 
     3289                        /*Debug << "pos: " << (*ci).mPos  
     3290                                 << "\t (pvsl: " << pvsl << ", pvsr: " << pvsr << ")" 
    31653291                                 << "\t (voll: " << voll << ", volr: " << volr << ")" 
    3166                                  << "\t sum: " << sum << endl; 
     3292                                 << "\t (vcl: " << vcl << ", vcr: " << vcr << ", nvc: " << numViewCells << ")" 
     3293                                 << "\t sum: " << sum << endl;*/ 
    31673294 
    31683295                        if (sum < minSum) 
     
    31933320        const float pFront = volFront; 
    31943321 
    3195         const float penaltyOld = (float)totalPvs;//EvalPvsPenalty(pvsSize, lowerPvsLimit, upperPvsLimit); 
    3196     const float penaltyFront = (float)pvsFront;//EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit); 
    3197         const float penaltyBack = (float)pvsBack;//EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit); 
     3322        const float penaltyOld = (float)totalPvs; 
     3323    const float penaltyFront = (float)pvsFront; 
     3324        const float penaltyBack = (float)pvsBack; 
    31983325         
    31993326        const float oldRenderCost = penaltyOld * pOverall + Limits::Small; 
     
    32063333        } 
    32073334         
    3208         //if (axis != 1) 
    3209         Debug << "axis=" << axis << " costRatio=" << ratio << " pos="  
    3210                   << position << " t=" << (position - minBox) / (maxBox - minBox) 
    3211               << "\t pb=(" << volBack << ")\t pf=(" << volFront << ")" << endl; 
     3335        //Debug << "axis=" << axis << " costRatio=" << ratio << " pos="  
     3336        //        << position << " t=" << (position - minBox) / (maxBox - minBox) 
     3337        //      << "\t pb=(" << volBack << ")\t pf=(" << volFront << ")" << endl; 
     3338 
     3339        const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 
     3340 
     3341        Debug << "\n§§§§ eval local cost §§§§" << endl 
     3342                  << "back pvs: " << pvsBack << " front pvs: " << pvsFront << " total pvs: " << totalPvs << endl  
     3343                  << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << " p: " << pOverall / viewSpaceVol << endl 
     3344                  << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl 
     3345                  << "render cost decrease: " << oldRenderCost / viewSpaceVol - newRenderCost / viewSpaceVol << endl; 
    32123346 
    32133347        return ratio; 
     
    32553389                 
    32563390                // if hitpoint with object is inside this node 
    3257                 if (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf) 
     3391                if (ray->mOriginObject && (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)) 
    32583392                { 
    32593393                        pos = ray->mOrigin[axis]; 
     
    32673401                } 
    32683402 
    3269                 if (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf) 
     3403                if (ray->mTerminationObject && (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)) 
    32703404                { 
    32713405                        pos = ray->mTermination[axis]; 
     
    32743408                                SortableEntry(SortableEntry::BOX_INTERSECT,  
    32753409                                                          pos,  
    3276                                                           ray->mOriginObject,  
     3410                                                          ray->mTerminationObject,  
    32773411                                                          ray) 
    32783412                                                          ); 
     
    33193453 
    33203454 
    3321 float OspTree::PrepareHeuristics(const VssRay &ray) 
     3455float OspTree::PrepareHeuristics(const VssRay &ray, int &numViewCells) 
    33223456{ 
    33233457        float vol = 0; 
     3458        numViewCells = 0; 
    33243459 
    33253460        ViewCellContainer viewCells; 
    33263461 
    33273462        mVspTree->GetViewCells(ray, viewCells); 
    3328      
     3463         
    33293464        ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 
    33303465 
     
    33353470                if (!vc->Mailed()) 
    33363471                { 
     3472                        //Debug << "single vol: "<< vc->GetVolume() << endl; 
    33373473                        vc->Mail(); 
    33383474                        vc->mCounter = 0; 
    33393475                        vol += vc->GetVolume(); 
    3340                 } 
     3476                        ++ numViewCells; 
     3477                } 
     3478                 
     3479                // view cell volume already added => just increase counter 
     3480                ++ vc->mCounter; 
    33413481        } 
    33423482 
     
    33453485 
    33463486 
    3347 float OspTree::PrepareHeuristics(const OspTraversalData &tData) 
     3487float OspTree::PrepareHeuristics(const OspTraversalData &tData, int &numViewCells) 
    33483488{        
     3489        float vol = 0; 
     3490 
    33493491        Intersectable::NewMail(); 
    33503492        ViewCell::NewMail(); 
    3351  
    3352         float vol = 0; 
     3493        numViewCells = 0; 
    33533494 
    33543495        KdLeaf *leaf = tData.mNode; 
     
    33593500        { 
    33603501                VssRay *ray = (*rit).mRay; 
     3502 
     3503                int newViewCells; 
    33613504 
    33623505                // if hitpoint with one of the objects is inside this node, we 
    33633506                // evaluate the volume of the view cells seen by this ray 
    3364                 if ((GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf) || 
    3365                         (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)) 
    3366                 { 
    3367             vol += PrepareHeuristics(tData); 
    3368                 } 
    3369         } 
    3370  
     3507                if (ray->mOriginObject && (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)) 
     3508                { 
     3509            vol += PrepareHeuristics(*ray, newViewCells); 
     3510                        numViewCells += newViewCells; 
     3511                } 
     3512 
     3513                // count double if both hit points are within the kd node 
     3514                if (ray->mTerminationObject && (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)) 
     3515                { 
     3516                        vol += PrepareHeuristics(*ray, newViewCells); 
     3517                        numViewCells += newViewCells; 
     3518                } 
     3519        } 
     3520 
     3521        //Debug << "vol: " << vol << endl; 
    33713522        return vol; 
    33723523} 
    33733524 
    33743525 
    3375 void OspTree::EvalHeuristicsContribution(const SortableEntry &ci, 
     3526void OspTree::EvalHeuristicsContribution(KdLeaf *leaf, 
     3527                                                                                 const SortableEntry &ci, 
    33763528                                                                                 float &volLeft, 
    33773529                                                                                 float &volRight, 
    33783530                                                                                 int &pvsLeft, 
    3379                                                                                  int &pvsRight) 
     3531                                                                                 int &pvsRight, 
     3532                                                                                 int &viewCellsLeft, 
     3533                                                                                 int &viewCellsRight) 
    33803534{ 
    33813535        Intersectable *obj = ci.mObject; 
    33823536        VssRay *ray = ci.mRay; 
    3383  
     3537         
    33843538        switch (ci.mType)  
    33853539        { 
     
    33953549                // compute volume contribution from view cells 
    33963550                case SortableEntry::BOX_INTERSECT: 
    3397                         EvalVolumeContribution(*ray, volRight, volLeft); 
     3551                                if ((ray->mOriginObject && (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)) || 
     3552                                        (ray->mTerminationObject && (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf))) 
     3553                                { 
     3554                                        EvalVolumeContribution(*ray, volLeft, volRight, viewCellsLeft, viewCellsRight); 
     3555                                } 
    33983556                        break; 
    33993557                default: 
     
    34063564 
    34073565 
    3408 void OspTree::EvalVolumeContribution(const VssRay &ray, float &volLeft, float &volRight) 
     3566void OspTree::EvalVolumeContribution(const VssRay &ray,  
     3567                                                                         float &volLeft,  
     3568                                                                         float &volRight, 
     3569                                                                         int &viewCellsLeft, 
     3570                                                                         int &viewCellsRight) 
    34093571{ 
    34103572        ViewCellContainer viewCells; 
     
    34133575 
    34143576        ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 
    3415  
     3577         
    34163578        for (vit = viewCells.begin(); vit != vit_end; ++ vit) 
    34173579        { 
    3418                 // view cells comes to left child node 
     3580                // add view cells volume to left child node 
    34193581                ViewCell *viewCell = *vit; 
    34203582 
     
    34223584                { 
    34233585                        viewCell->Mail(); 
     3586                         
    34243587                        volLeft += viewCell->GetVolume(); 
     3588 
     3589                        ++ viewCellsLeft; 
    34253590                } 
    34263591 
    34273592                // remove from right child node 
    3428  
    34293593                if (-- viewCell->mCounter == 0) 
    34303594                { 
    34313595                        volRight -= viewCell->GetVolume(); 
     3596 
     3597                        -- viewCellsRight; 
    34323598                } 
    34333599        } 
     
    35203686        pBack = nProbBack[bestAxis]; 
    35213687 
    3522         //Debug << "val: " << nCostRatio[bestAxis] << " axis: " << bestAxis << endl; 
     3688        Debug << "val: " << nCostRatio[bestAxis] << " axis: " << bestAxis << endl; 
    35233689        return nCostRatio[bestAxis]; 
    35243690} 
    35253691 
    35263692 
     3693bool OspTree::EndPointInsideNode(KdLeaf *leaf,  
     3694                                                                 VssRay &ray,  
     3695                                                                 bool isTermination) const 
     3696{ 
     3697        // test if the leaf where the hitpoint is located is the current leaf 
     3698        if (isTermination) 
     3699        { 
     3700                 return ray.mTerminationObject && (GetLeaf(ray.mTermination, ray.mOriginNode) == leaf); 
     3701        } 
     3702        else 
     3703        { 
     3704                 return ray.mOriginObject && (GetLeaf(ray.mOrigin, ray.mOriginNode) == leaf); 
     3705        } 
     3706} 
     3707 
     3708 
     3709#if TODO 
     3710void OspTree::EvalSubdivisionStats(const VspTraversalData &tData, 
     3711                                                                   const VspTraversalData &tFrontData, 
     3712                                                                   const VspTraversalData &tBackData 
     3713                                                                   ) 
     3714{ 
     3715        const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
     3716        const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
     3717        const float cData = (float)tData.mPvs * tData.mProbability; 
     3718         
     3719        const float costDecr =  
     3720                (cFront + cBack - cData) / mBoundingBox.GetVolume(); 
     3721 
     3722        mTotalCost += costDecr; 
     3723        mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 
     3724 
     3725        AddSubdivisionStats(mVspStats.Leaves(), 
     3726                                                -costDecr, 
     3727                                                sc->GetPriority(), 
     3728                                                mTotalCost, 
     3729                                                (float)mTotalPvsSize / (float)mVspStats.Leaves()); 
     3730} 
     3731#endif 
     3732 
     3733 
     3734int OspTree::ClassifyRay(VssRay *ray,  
     3735                                                 KdLeaf *leaf,  
     3736                                                 const AxisAlignedPlane &plane) const 
     3737{ 
     3738        const bool originInside = EndPointInsideNode(leaf, *ray, false); 
     3739    const bool terminationInside = EndPointInsideNode(leaf, *ray, true); 
     3740 
     3741        const bool originGt =  
     3742                ray->mOrigin[plane.mAxis] > plane.mPosition; 
     3743                 
     3744        const bool terminationGt =  
     3745                ray->mTermination[plane.mAxis] > plane.mPosition; 
     3746 
     3747        // add view cell volume to front volume 
     3748        const bool addToFront = ((originInside && originGt) || (terminationInside && terminationGt)); 
     3749 
     3750        // add view cell volume to back volume 
     3751        const bool addToBack = ((originInside && !originGt) || (terminationInside && !terminationGt)); 
     3752 
     3753        // classify ray with respect to the child nodes the view cells contribute 
     3754        if (addToFront && addToBack) 
     3755                return 0; 
     3756        else if (addToBack) 
     3757                return -1; 
     3758        else if (addToFront) 
     3759                return 1; 
     3760 
     3761        return -2; 
     3762} 
     3763 
     3764 
    35273765float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 
    3528                                                                           const OspTraversalData &tData) const 
    3529 { 
    3530 #if 0 
    3531         return (float)-tData.mDepth; 
    3532 #endif 
    3533  
     3766                                                                          const OspTraversalData &tData, 
     3767                                                                          float &normalizedOldRenderCost) const 
     3768{ 
    35343769        float pvsFront = 0; 
    35353770        float pvsBack = 0; 
     
    35413776        float pBack = 0; 
    35423777 
    3543         Intersectable::NewMail(); 
     3778        const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 
     3779 
     3780        //Intersectable::NewMail(); 
    35443781        KdLeaf::NewMail(); 
    35453782        ViewCell::NewMail(); 
     
    35493786 
    35503787        // evaluate reverse pvs and view cell volume on left and right cell 
     3788        // note: should I take all leaf objects or rather the objects hit by rays? 
    35513789        for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit) 
    35523790        { 
     
    35563794                ++ totalPvs; 
    35573795 
    3558                 cout << "totalpvs " << totalPvs << endl; 
    3559  
     3796                //cout << "totalpvs " << totalPvs << endl; 
     3797 
     3798                // test if box falls in left / right child node 
    35603799                if (box.Max(candidatePlane.mAxis) > candidatePlane.mPosition) 
    35613800                { 
     
    35693808 
    35703809 
    3571         ViewCell::NewMail(); 
     3810        // sum up volume seen from the objects of left and right children 
     3811        // => the volume is the weight for the render cost equation 
     3812        ViewCell::NewMail(3); 
    35723813         
    35733814        RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end(); 
     
    35773818                VssRay *ray = (*rit).mRay; 
    35783819 
    3579                 // if hitpoint with one of the objects is inside this node 
    3580                 if (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf) 
    3581                 { 
     3820                // test if intersection point with one of the objects is inside this node 
     3821                const bool originInside = EndPointInsideNode(leaf, *ray, false); 
     3822        const bool terminationInside = EndPointInsideNode(leaf, *ray, true); 
     3823 
     3824                if (originInside || terminationInside) 
     3825                { 
     3826                        // add volume to volumes of left and / or right children 
     3827                        // if one of the ray end points is inside 
     3828                        const int classification = ClassifyRay(ray, leaf, candidatePlane); 
     3829 
    35823830                        ViewCellContainer viewCells;             
    35833831                        mVspTree->GetViewCells(*ray, viewCells); 
     
    35853833                        ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 
    35863834 
    3587                         // add view cells volume to front        
     3835                        // evaluate view cells volume contribution 
    35883836                        for (vit = viewCells.begin(); vit != vit_end; ++ vit) 
    35893837                        { 
    3590                                 ViewCell *vc = *vit; 
    3591  
    3592                                 if (!vc->Mailed()) 
    3593                                 { 
    3594                                         vc->Mail(); 
    3595  
    3596                                         const float vol = vc->GetVolume(); 
    3597                                         pOverall += vol; 
    3598  
    3599                                         if (ray->mOrigin[candidatePlane.mAxis] > candidatePlane.mPosition) 
    3600                                                 pFront += vol; 
    3601                                         else 
    3602                                                 pBack += vol; 
    3603                                 } 
     3838                                AddViewCellVolume(*vit, classification, pFront, pBack, pOverall); 
    36043839                        } 
    36053840                } 
     
    36113846        const float newRenderCost = pvsFront * pFront + pvsBack * pBack; 
    36123847 
    3613         Debug << "total pvs: " << totalPvs << " p " << pOverall << endl 
    3614                   << "old: " << oldRenderCost << " new: " << newRenderCost << " decrease: "  
    3615                   << oldRenderCost - newRenderCost << endl; 
    3616  
    3617         // todo matt§§: how to normalize volume?? 
    3618         const float renderCostDecrease = (oldRenderCost - newRenderCost);// / mBoundingBox.GetVolume(); 
    3619          
    3620         // take render cost of node into account  
    3621         // otherwise danger of being stuck in a local minimum!! 
    3622         const float factor = mRenderCostDecreaseWeight; 
    3623  
    3624         const float normalizedOldRenderCost = oldRenderCost;// / mBoundingBox.GetVolume(); 
    3625         return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost; 
     3848        // normalize volume with view space volume 
     3849        const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol; 
     3850 
     3851        Debug << "\n==== eval render cost decrease ===" << endl 
     3852                  << "back pvs: " << pvsBack << " front pvs " << pvsFront << " total pvs: " << totalPvs << endl  
     3853                  << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << " p: " << pOverall / viewSpaceVol << endl 
     3854                  << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl 
     3855                  << "render cost decrease: " << renderCostDecrease << endl; 
     3856 
     3857        normalizedOldRenderCost = oldRenderCost / viewSpaceVol; 
     3858 
     3859        return renderCostDecrease; 
    36263860} 
    36273861 
     
    37413975                } 
    37423976        } 
    3743  
    37443977} 
    37453978 
     
    39614194 
    39624195 
     4196void OspTree::AddViewCellVolume(ViewCell *vc, 
     4197                                                                const int cf, 
     4198                                                                float &frontVol, 
     4199                                                                float &backVol, 
     4200                                                                float &totalVol) const 
     4201{ 
     4202        //const float renderCost = mViewCellsManager->SimpleRay &raynderCost(obj); 
     4203        const float vol = vc->GetVolume(); 
     4204 
     4205        // view cell not found yet => new 
     4206        if (!vc->Mailed() && !vc->Mailed(1) && !vc->Mailed(2)) 
     4207        { 
     4208                totalVol += vol; 
     4209        } 
     4210 
     4211        if (cf >= 0) // front volume 
     4212        { 
     4213                if (!vc->Mailed() && !vc->Mailed(2)) 
     4214                { 
     4215                        frontVol += vol; 
     4216                 
     4217                        // already in back volume => in both volumes 
     4218                        if (vc->Mailed(1)) 
     4219                                vc->Mail(2); 
     4220                        else 
     4221                                vc->Mail(); 
     4222                } 
     4223        } 
     4224 
     4225        if (cf <= 0) // back volume 
     4226        { 
     4227                if (!vc->Mailed(1) && !vc->Mailed(2)) 
     4228                { 
     4229                        backVol += vol; 
     4230                 
     4231                        // already in front volume => in both volume 
     4232                        if (vc->Mailed()) 
     4233                                vc->Mail(2); 
     4234                        else 
     4235                                vc->Mail(1); 
     4236                } 
     4237        } 
     4238} 
     4239 
    39634240 
    39644241/********************************************************************/ 
     
    39894266 
    39904267 
    3991 SplitCandidate *HierarchyManager::PrepareVsp(const VssRayContainer &sampleRays, 
     4268VspTree::VspSplitCandidate *HierarchyManager::PrepareVsp(const VssRayContainer &sampleRays, 
    39924269                                                                                         AxisAlignedBox3 *forcedViewSpace, 
    39934270                                                                                         RayInfoContainer &rays) 
     
    40094286        const int pvsSize = mVspTree.ComputePvsSize(rays); 
    40104287         
    4011         Debug <<  "pvs size: " << pvsSize << endl; 
    4012         Debug <<  "rays size: " << rays.size() << endl; 
     4288        Debug <<  "pvs size: " << (int)pvsSize << endl; 
     4289        Debug <<  "rays size: " << (int)rays.size() << endl; 
    40134290 
    40144291        //-- prepare view space partition 
     
    40524329 
    40534330 
    4054 SplitCandidate * HierarchyManager::PrepareOsp(const VssRayContainer &sampleRays, 
     4331OspTree::OspSplitCandidate * HierarchyManager::PrepareOsp(const VssRayContainer &sampleRays, 
    40554332                                                                                          const ObjectContainer &objects, 
    40564333                                                                                          AxisAlignedBox3 *forcedObjectSpace, 
     
    41394416        const long startTime = GetTime();        
    41404417         
    4141         int i = 0; 
     4418        RunConstruction(true); 
     4419 
     4420        cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
     4421 
     4422        mVspTree.mVspStats.Stop(); 
     4423} 
     4424 
     4425 
     4426bool HierarchyManager::SubdivideSplitCandidate(SplitCandidate *sc) 
     4427{ 
     4428        const bool globalTerminationCriteriaMet =  
     4429                        GlobalTerminationCriteriaMet(sc); 
     4430 
     4431        const bool vspSplit = (sc->Type() == SplitCandidate::VIEW_SPACE); 
     4432 
     4433        if (vspSplit) 
     4434        { 
     4435                mVspTree.Subdivide(mTQueue, sc, globalTerminationCriteriaMet); 
     4436                return true; 
     4437        } 
     4438        else 
     4439        { 
     4440                mOspTree.Subdivide(mTQueue, sc, globalTerminationCriteriaMet); 
     4441                return false; 
     4442        } 
     4443} 
     4444 
     4445 
     4446void HierarchyManager::RunConstruction(const bool repair) 
     4447{ 
     4448        int numNodes = 0; 
     4449 
    41424450        while (!FinishedConstruction()) 
    41434451        { 
    4144                 mCurrentCandidate = NextSplitCandidate(); 
    4145             
    4146                 const bool globalTerminationCriteriaMet =  
    4147                         GlobalTerminationCriteriaMet(mCurrentCandidate); 
    4148  
    4149                 cout << "view cells: " << i ++ << endl; 
    4150  
     4452                SplitCandidate *splitCandidate = NextSplitCandidate(); 
     4453             
     4454                cout << "nodes: " << ++ numNodes << endl; 
     4455 
     4456                mTotalCost -= splitCandidate->GetRenderCostDecrease(); 
     4457 
     4458                //-- subdivide leaf node 
     4459                SubdivideSplitCandidate(splitCandidate); 
     4460                 
    41514461                // cost ratio of cost decrease / totalCost 
    4152                 const float costRatio = mCurrentCandidate->GetPriority() / mTotalCost; 
    4153                 //Debug << "cost ratio: " << costRatio << endl; 
     4462                const float costRatio = splitCandidate->GetRenderCostDecrease() / mTotalCost; 
     4463                 
     4464                Debug << "\n**********" << endl 
     4465                          << "total cost: " << mTotalCost << " render cost decr: "  
     4466                          << splitCandidate->GetRenderCostDecrease()  
     4467                          << " cost ratio: " << costRatio << endl << endl; 
    41544468 
    41554469                if (costRatio < mTermMinGlobalCostRatio) 
    41564470                        ++ mGlobalCostMisses; 
    4157  
    4158                 //-- subdivide leaf node 
    4159  
    4160                 // we have either a object space or view space split 
    4161                 if (mCurrentCandidate->Type() == SplitCandidate::VIEW_SPACE) 
    4162                 { 
    4163                         VspTree::VspSplitCandidate *sc =  
    4164                                 dynamic_cast<VspTree::VspSplitCandidate *>(mCurrentCandidate); 
    4165  
    4166                         VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
    4167                 } 
    4168                 else // object space split 
    4169                 {                        
    4170                         OspTree::OspSplitCandidate *sc =  
    4171                                 dynamic_cast<OspTree::OspSplitCandidate *>(mCurrentCandidate); 
    4172  
    4173                         KdNode *r = mOspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
    4174                 } 
    41754471 
    41764472                // reevaluate candidates affected by the split 
    41774473                // for view space splits, this would be object space splits 
    41784474                // and other way round 
    4179                 RepairQueue(); 
    4180  
    4181                 DEL_PTR(mCurrentCandidate); 
    4182         } 
    4183  
    4184         cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
    4185  
    4186         mVspTree.mVspStats.Stop(); 
     4475                if (repair) 
     4476                        RepairQueue(); 
     4477 
     4478                DEL_PTR(splitCandidate); 
     4479        } 
    41874480} 
    41884481 
     
    41954488        RayInfoContainer *objectSpaceRays = new RayInfoContainer(); 
    41964489 
     4490 
    41974491        ///////////////////////////////////////////////////////////// 
    41984492        // view space space partition 
    41994493        ///////////////////////////////////////////////////////////// 
     4494 
    42004495 
    42014496        // makes no sense otherwise because only one kd cell available 
     
    42074502        mVspTree.mStoreKdPvs = false; 
    42084503 
    4209         SplitCandidate *sc = PrepareVsp(sampleRays, forcedViewSpace, *viewSpaceRays); 
    4210         mTQueue.Push(sc); 
     4504        VspTree::VspSplitCandidate *vsc =  
     4505                PrepareVsp(sampleRays, forcedViewSpace, *viewSpaceRays); 
     4506        // add to queue 
     4507        mTQueue.Push(vsc); 
    42114508 
    42124509        long startTime = GetTime(); 
     
    42184515        int i = 0; 
    42194516 
    4220         while (!FinishedConstruction()) 
    4221         { 
    4222                 SplitCandidate *splitCandidate = NextSplitCandidate(); 
    4223              
    4224                 const bool globalTerminationCriteriaMet =  
    4225                         GlobalTerminationCriteriaMet(splitCandidate); 
    4226  
    4227                 cout << "vsp nodes: " << i ++ << endl; 
    4228  
    4229                 // cost ratio of cost decrease / totalCost 
    4230                 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 
    4231                 //cout << "cost ratio: " << costRatio << endl; 
    4232  
    4233                 if (costRatio < mTermMinGlobalCostRatio) 
    4234                         ++ mGlobalCostMisses; 
    4235  
    4236                 //-- subdivide leaf node 
    4237  
    4238                 // we have either a object space or view space split 
    4239                 VspTree::VspSplitCandidate *sc =  
    4240                         dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate); 
    4241  
    4242          
    4243                 VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
    4244  
    4245                 DEL_PTR(splitCandidate); 
    4246         } 
     4517        // all objects can be seen from everywhere 
     4518        mTotalCost = (float)vsc->mParentData.mPvs; 
     4519 
     4520        const bool repairQueue = false; 
     4521 
     4522        // process view space candidates 
     4523        RunConstruction(repairQueue); 
    42474524 
    42484525        cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
    42494526        mVspTree.mVspStats.Stop(); 
    42504527         
    4251          
     4528 
     4529 
    42524530        ///////////////////////////////////////////////////////////// 
    42534531        // object space partition 
    42544532        ///////////////////////////////////////////////////////////// 
    42554533 
    4256         Debug << "**************** osp construction **************" << endl; 
     4534        Debug << "\n$$$$$$$$$ osp tree construction $$$$$$$$$$\n" << endl; 
    42574535        cout << "starting osp contruction ... " << endl; 
    42584536 
     4537        // compute first candidate 
     4538        OspTree::OspSplitCandidate *osc = 
     4539                PrepareOsp(sampleRays, objects, forcedViewSpace, *objectSpaceRays); 
     4540 
     4541    mTQueue.Push(osc); 
     4542 
     4543        mOspTree.mOspStats.Reset(); 
     4544        mOspTree.mOspStats.Start(); 
     4545 
    42594546        startTime = GetTime(); 
    42604547 
    4261         SplitCandidate *osc = 
    4262                 PrepareOsp(sampleRays, objects, forcedViewSpace, *objectSpaceRays); 
    4263  
    4264     mTQueue.Push(osc); 
    4265  
    4266  
    4267         i = 0; 
    4268         while (!FinishedConstruction()) 
    4269         { 
    4270                 SplitCandidate *splitCandidate = NextSplitCandidate(); 
    4271              
    4272                 const bool globalTerminationCriteriaMet =  
    4273                         GlobalTerminationCriteriaMet(splitCandidate); 
    4274  
    4275                 // cost ratio of cost decrease / totalCost 
    4276                 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 
    4277                  
    4278                 //Debug << "cost ratio: " << costRatio << endl; 
    4279                 //cout << "kd nodes: " << i ++ << endl; 
    4280  
    4281                 if (costRatio < mTermMinGlobalCostRatio) 
    4282                         ++ mGlobalCostMisses; 
    4283  
    4284                 //-- subdivide leaf node 
    4285  
    4286                 // object space split 
    4287                 OspTree::OspSplitCandidate *sc =  
    4288                         dynamic_cast<OspTree::OspSplitCandidate *>(splitCandidate); 
    4289  
    4290                 KdNode *r = mOspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
    4291                  
    4292                 DEL_PTR(splitCandidate); 
    4293         } 
    4294          
    4295         cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
    4296  
     4548        // reset cost 
     4549        // start with one big kd cell - all objects can be seen from everywhere 
     4550        // note: only true for view space = object space 
     4551        mTotalCost = (float)osc->mParentData.mNode->mObjects.size();//(float)sc->mParentData.mPvs; 
     4552 
     4553        Debug << "reseting cost, new total cost: " << mTotalCost << endl; 
     4554 
     4555        // process object space candidates 
     4556        RunConstruction(repairQueue); 
     4557         
     4558        cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 
     4559 
     4560        mOspTree.mOspStats.Stop(); 
     4561 
     4562        // reset parameters 
    42974563        mVspTree.mUseKdPvsForHeuristics = savedCountMethod; 
    42984564        mVspTree.mStoreKdPvs = savedStoreMethod; 
     
    43044570                                                                  AxisAlignedBox3 *forcedViewSpace) 
    43054571{ 
     4572        // only view space partition 
     4573        // object kd tree is taken for osp 
     4574 
    43064575        mVspTree.mVspStats.Reset(); 
    43074576        mVspTree.mVspStats.Start(); 
     
    43154584 
    43164585        long startTime = GetTime(); 
    4317         int i = 0; 
    4318  
    4319         while (!FinishedConstruction()) 
    4320         { 
    4321                 SplitCandidate *splitCandidate = NextSplitCandidate(); 
    4322              
    4323                 const bool globalTerminationCriteriaMet =  
    4324                         GlobalTerminationCriteriaMet(splitCandidate); 
    4325  
    4326                 cout << "vsp nodes: " << i ++ << endl; 
    4327                  
    4328                 // cost ratio of cost decrease / totalCost 
    4329                 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 
    4330                 //cout << "cost ratio: " << costRatio << endl; 
    4331  
    4332                 if (costRatio < mTermMinGlobalCostRatio) 
    4333                         ++ mGlobalCostMisses; 
    4334  
    4335                 //-- subdivide leaf node 
    4336          
    4337                 // we have either a object space or view space split 
    4338                 VspTree::VspSplitCandidate *sc =  
    4339                         dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate); 
    4340  
    4341          
    4342                 VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
    4343  
    4344                 DEL_PTR(splitCandidate); 
    4345         } 
     4586 
     4587        RunConstruction(false); 
    43464588 
    43474589        cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
     
    43504592 
    43514593 
    4352 bool HierarchyManager::FinishedConstruction() 
     4594bool HierarchyManager::FinishedConstruction() const 
    43534595{ 
    43544596        return mTQueue.Empty(); 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h

    r1144 r1145  
    6666        int mMaxCostMisses; 
    6767 
    68         /// priority of this split 
    69         //float mPriority; 
    70          
    7168        SplitCandidate() 
    7269        {}; 
     
    7875        virtual int Type() const = 0; 
    7976        virtual bool GlobalTerminationCriteriaMet() const = 0; 
     77 
     78        /** Set render cost decrease achieved through this split. 
     79        */ 
     80        void SetRenderCostDecrease(const float renderCostDecr) 
     81        { 
     82                mRenderCostDecrease = renderCostDecr; 
     83        } 
     84         
     85        float GetRenderCostDecrease() const 
     86        { 
     87                return mRenderCostDecrease; 
     88        } 
     89 
     90protected: 
     91 
     92        /// render cost decrease achieved through this split 
     93        float mRenderCostDecrease; 
     94         
    8095}; 
    8196 
     
    814829        */ 
    815830        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 
    816                                                                  const VspTraversalData &data) const; 
     831                                                                 const VspTraversalData &data, 
     832                                                                 float &normalizedOldRenderCost) const; 
    817833 
    818834        /** Collects view cells in the subtree under root. 
     
    852868        */ 
    853869        VspNode *Subdivide(SplitQueue &tQueue, 
    854                                            VspSplitCandidate &splitCandidate, 
     870                                           SplitCandidate *splitCandidate, 
    855871                                           const bool globalCriteriaMet); 
    856872 
     
    859875        void AddSubdivisionStats(const int viewCells, 
    860876                                                         const float renderCostDecr, 
    861                                                          const float splitCandidateCost, 
    862877                                                         const float totalRenderCost, 
    863878                                                         const float avgRenderCost); 
     
    10241039                RayInfoContainer &rays); 
    10251040 
     1041        void EvalSubdivisionStats(const VspTraversalData &tData, 
     1042                                                          const VspTraversalData &tFrontData, 
     1043                                                          const VspTraversalData &tBackData); 
    10261044protected: 
     1045 
    10271046 
    10281047        bool mUseKdPvsForHeuristics; 
     
    14421461        */ 
    14431462        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 
    1444                                                                  const OspTraversalData &data) const; 
     1463                                                                 const OspTraversalData &data, 
     1464                                                                 float &normalizedOldRenderCost) const; 
    14451465 
    14461466 
     
    14631483        */ 
    14641484        KdNode *Subdivide(SplitQueue &tQueue, 
    1465                                           OspSplitCandidate &splitCandidate, 
     1485                                          SplitCandidate *splitCandidate, 
    14661486                                          const bool globalCriteriaMet); 
    14671487         
     
    15851605                @param rightPvs updates the right pvs 
    15861606        */ 
    1587         void EvalHeuristicsContribution(const SortableEntry &ci, 
     1607        void EvalHeuristicsContribution(KdLeaf *leaf, 
     1608                const SortableEntry &ci, 
    15881609                float &volLeft, 
    15891610                float &volRight, 
    15901611                int &pvsLeft, 
    1591                 int &pvsRight); 
     1612                int &pvsRight, 
     1613                int &viewCellsLeft, 
     1614                int &viewCellsRight); 
    15921615 
    15931616        /** Evaluate the contributions of view cell volume of the left and the right view cell. 
    15941617        */ 
    1595         void EvalVolumeContribution(const VssRay &ray, float &volLeft, float &volRight); 
     1618        void EvalVolumeContribution(const VssRay &ray,  
     1619                                                                float &volLeft,  
     1620                                                                float &volRight, 
     1621                                                                int &viewCellsLeft, 
     1622                                                                int &viewCellsRight); 
    15961623 
    15971624        /** Prepares objects for the cost heuristics. 
    15981625                @returns pvs size of the node 
    15991626        */ 
    1600         float PrepareHeuristics(const OspTraversalData &tData); 
     1627        float PrepareHeuristics(const OspTraversalData &tData, int &numViewCells); 
    16011628 
    16021629        /** Prepares heuristics for a particular ray. 
    16031630        */ 
    1604         float PrepareHeuristics(const VssRay &ray); 
     1631        float PrepareHeuristics(const VssRay &ray, int &numViewCells); 
    16051632 
    16061633        /** Prepares construction for vsp and osp trees. 
     
    16201647                RayInfoContainer &rays); 
    16211648 
    1622  
     1649        /** Reads parameters from environment singleton. 
     1650        */ 
    16231651        void ReadEnvironment(); 
     1652 
     1653        /** Returns true if the specified ray end points is inside the kd leaf. 
     1654                @param isTermination if origin or termination point should be checked 
     1655        */ 
     1656        bool EndPointInsideNode(KdLeaf *leaf, VssRay &ray, bool isTermination) const; 
     1657 
     1658        void AddViewCellVolume(ViewCell *vc, 
     1659                                                   const int cf, 
     1660                                                   float &frontPvs, 
     1661                                                   float &backPvs, 
     1662                                                   float &totalPvs) const; 
     1663 
     1664        int ClassifyRay(VssRay *ray, KdLeaf *leaf, const AxisAlignedPlane &plane) const; 
    16241665 
    16251666protected: 
     
    17791820                RayInfoContainer &objectSpaceRays); 
    17801821 
    1781         bool FinishedConstruction(); 
     1822        void RunConstruction(const bool repair); 
     1823        bool SubdivideSplitCandidate(SplitCandidate *sc); 
     1824 
     1825        bool FinishedConstruction() const; 
    17821826 
    17831827        SplitCandidate *NextSplitCandidate(); 
     
    17871831        void CollectDirtyCandidates(vector<SplitCandidate *> &dirtyList); 
    17881832 
    1789         SplitCandidate *PrepareVsp(const VssRayContainer &sampleRays, 
     1833        VspTree::VspSplitCandidate *PrepareVsp(const VssRayContainer &sampleRays, 
    17901834                                                           AxisAlignedBox3 *forcedViewSpace, 
    17911835                                                           RayInfoContainer &rays); 
    17921836 
    1793         SplitCandidate *PrepareOsp(const VssRayContainer &sampleRays, 
     1837        OspTree::OspSplitCandidate *PrepareOsp(const VssRayContainer &sampleRays, 
    17941838                const ObjectContainer &objects, 
    17951839                AxisAlignedBox3 *forcedObjectSpace, 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp

    r1076 r1145  
    432432        exporter->SetFilled(); 
    433433        //Randomize(); 
    434         debuggerWidget = new GlDebuggerWidget(renderer); 
     434// §§matt 
     435//      debuggerWidget = new GlDebuggerWidget(renderer); 
    435436 
    436437        /*debuggerWidget->mBeam = beam; 
     
    439440         
    440441        Debug << "showing window" << endl; 
    441         debuggerWidget->show();*/ 
    442          
    443         renderer->makeCurrent(); 
     442        debuggerWidget->show(); 
     443         
     444        renderer->makeCurrent();*/ 
    444445 
    445446        for (int i = 0; i < 10; ++ i) 
     
    464465 
    465466                BeamSampleStatistics stats; 
    466  
    467                 renderer->SampleBeamContributions(sourceObj, 
     467// §§matt 
     468/*              renderer->SampleBeamContributions(sourceObj, 
    468469                                                                                  beam, 
    469470                                                                                  200000, 
     
    475476                image.save(s, "PNG"); 
    476477                Debug << "beam statistics: " << stats << endl << endl; 
    477  
     478*/ 
    478479                if (1) 
    479480                { 
  • GTP/trunk/Lib/Vis/Preprocessing/src/common.h

    r1112 r1145  
    3838//#pragma warning(disable:4244) 
    3939 
    40 #if 0 // $$$matt: comment this out because conflicts with definition in qt library!! 
     40#if 0 // Note matt: comment this out because conflicts with definition in qt library!! 
    4141typedef unsigned int uint; 
    4242#endif 
  • GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp

    r1112 r1145  
    1616#include "ResourceManager.h" 
    1717 
    18 #include <QApplication> 
    19 #include <QtOpenGL> 
     18//#include <QApplication> 
     19//#include <QtOpenGL> 
     20#include <boost/thread/thread.hpp> 
     21#include <boost/thread/xtime.hpp> 
    2022#include "GlRenderer.h" 
    2123 
     
    2527 
    2628using namespace GtpVisibilityPreprocessor; 
     29 
     30Preprocessor *preprocessor = NULL; 
     31 
     32#if QT_ENABLED 
     33QApplication *app = NULL; 
     34#endif 
     35 
     36 
     37void Cleanup() 
     38{ 
     39#if QT_ENABLED 
     40        DEL_PTR(rendererWidget); 
     41#endif 
     42 
     43        DEL_PTR(preprocessor); 
     44 
     45        Environment::DelSingleton(); 
     46        MeshManager::DelSingleton(); 
     47        MaterialManager::DelSingleton(); 
     48} 
     49 
     50 
     51void DisplayWidget() 
     52{ 
     53#if QT_ENABLED 
     54        QApplication *app = NULL; 
     55 
     56        // create a qt application first (must be created before any opengl widget ...) 
     57        app = new QApplication(argc, argv); 
     58 
     59        if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) { 
     60                QMessageBox::information(0, "OpenGL pbuffers",  
     61                        "This system does not support OpenGL/pbuffers.", 
     62                        QMessageBox::Ok); 
     63                return -1; 
     64        } 
     65         
     66        // note matt: capsulate qt dependent code as good as possible 
     67        rendererWidget =  
     68                new GlRendererWidget(p->mSceneGraph, p->mViewCellsManager, p->mKdTree); 
     69 
     70        rendererWidget->resize(640, 480); 
     71        rendererWidget->show(); 
     72 
     73        if (0 && p->GetRenderer())  
     74        { 
     75                cout<<"CONNECTING"<<endl; 
     76                QObject::connect(p->GetRenderer(), 
     77                SIGNAL(UpdatePvsErrorItem(int i, GlRendererBuffer::PvsErrorEntry &)), 
     78                                rendererWidget->mControlWidget,  
     79                                SLOT(UpdatePvsErrorItem(int i, 
     80                                GlRendererBuffer::PvsErrorEntry &))); 
     81 
     82                cout<<"CONNECTED"<<endl; 
     83        } 
     84#endif 
     85} 
     86 
    2787 
    2888int 
     
    3090{ 
    3191 
    32   //Now just call this function at the start of your program and if you're 
    33   //compiling in debug mode (F5), any leaks will be displayed in the Output 
    34   //window when the program shuts down. If you're not in debug mode this will 
    35   //be ignored. Use it as you will! 
    36   //note: from GDNet Direct [3.8.04 - 3.14.04] void detectMemoryLeaks() { 
    37   _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF); 
    38   _CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE); 
    39   _CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR);  
    40  
    41   InitTiming(); 
    42  
    43   Debug.open("debug.log"); 
    44    
    45   Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH); 
    46   MeshKdTree::ParseEnvironment(); 
    47  
    48   char buff[128]; 
    49   Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff); 
    50   string preprocessorType(buff); 
    51  
    52   Preprocessor *p = NULL; 
    53  
    54   
    55   if (preprocessorType == "vss") 
    56   { 
    57           p = new VssPreprocessor(); 
    58   } 
    59   else 
    60   { 
    61         if (preprocessorType == "rss") 
    62         { 
    63                 p = new RssPreprocessor(); 
     92        //Now just call this function at the start of your program and if you're 
     93        //compiling in debug mode (F5), any leaks will be displayed in the Output 
     94        //window when the program shuts down. If you're not in debug mode this will 
     95        //be ignored. Use it as you will! 
     96        //note: from GDNet Direct [3.8.04 - 3.14.04] void detectMemoryLeaks() { 
     97        _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF); 
     98        _CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE); 
     99        _CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR);  
     100 
     101        int returnCode = 0; 
     102 
     103        InitTiming(); 
     104 
     105        Debug.open("debug.log"); 
     106 
     107        Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH); 
     108        MeshKdTree::ParseEnvironment(); 
     109 
     110        char buff[128]; 
     111        Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff); 
     112        string preprocessorType(buff); 
     113 
     114        if (preprocessorType == "vss") 
     115        { 
     116                preprocessor = new VssPreprocessor(); 
    64117        } 
    65118        else 
    66119        { 
    67           if (preprocessorType == "exact") 
    68           { 
    69                 p = new ExactPreprocessor(); 
    70           } 
    71           else 
    72           { 
    73                 if (preprocessorType == "sampling") 
     120                if (preprocessorType == "rss") 
    74121                { 
    75                   p = new SamplingPreprocessor(); 
     122                        preprocessor = new RssPreprocessor(); 
    76123                } 
    77124                else 
    78                 {        
    79                   if (preprocessorType == "render") 
    80                   { 
    81                          p = new RenderSampler(); 
    82                   } 
    83                   else { 
    84                           Environment::DelSingleton(); 
    85                           cerr<<"Unknown preprocessor type"<<endl; 
    86                           Debug<<"Unknown preprocessor type"<<endl; 
    87                           exit(1); 
    88                   } 
     125                { 
     126                        if (preprocessorType == "exact") 
     127                        { 
     128                                preprocessor = new ExactPreprocessor(); 
     129                        } 
     130                        else 
     131                        { 
     132                                if (preprocessorType == "sampling") 
     133                                { 
     134                                        preprocessor = new SamplingPreprocessor(); 
     135                                } 
     136                                else 
     137                                {        
     138                                        if (preprocessorType == "render") 
     139                                        { 
     140                                                preprocessor = new RenderSampler(); 
     141                                        } 
     142                                        else { 
     143                                                Environment::DelSingleton(); 
     144                                                cerr<<"Unknown preprocessor type"<<endl; 
     145                                                Debug<<"Unknown preprocessor type"<<endl; 
     146                                                exit(1); 
     147                                        } 
     148                                } 
     149                        } 
    89150                } 
    90           } 
    91         } 
    92   } 
    93    
    94   QApplication *app = NULL; 
    95  
    96   if (p->mUseGlRenderer || p->mUseGlDebugger) { 
     151        } 
    97152         
    98         // create a qt application first (must be created before any opengl widget... 
    99         app = new QApplication(argc, argv); 
    100          
    101         if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) { 
    102           QMessageBox::information(0, "OpenGL pbuffers",  
    103                                                            "This system does not support OpenGL/pbuffers.", 
    104                                                            QMessageBox::Ok); 
    105           return -1; 
    106         } 
    107   } 
    108    
    109   preprocessor = p; 
    110    
    111   Environment::GetSingleton()->GetStringValue("Scene.filename", buff); 
    112   string filename(buff); 
    113   
    114   p->LoadScene(filename); 
    115    
    116   p->BuildKdTree(); 
    117   p->KdTreeStatistics(cout); 
    118   
    119   // parse view cells related options 
    120   p->PrepareViewCells(); 
    121    
    122  
    123   // create a preprocessor thread 
    124   PreprocessorThread *pt = new PreprocessorThread(p, app); 
    125  
    126   //  p->mSceneGraph->Export("soda.x3d"); 
    127   if (0) { 
    128     p->Export(filename + "-out.x3d", true, false, false); 
    129     p->Export(filename + "-kdtree.x3d", false, true, false);     
    130   } 
    131  
    132   if (p->mUseGlRenderer) { 
    133           
    134         rendererWidget = new GlRendererWidget(p->mSceneGraph, p->mViewCellsManager, p->mKdTree); 
    135         //  renderer->resize(640, 480); 
    136           
    137         rendererWidget->resize(640, 480); 
    138         rendererWidget->show(); 
    139          
    140         if (0 && p->GetRenderer()) { 
    141            
    142           cout<<"CONNECTING"<<endl; 
    143           QObject::connect(p->GetRenderer(), 
    144                                            SIGNAL(UpdatePvsErrorItem(int i, 
    145                                                                                                  GlRendererBuffer::PvsErrorEntry &)), 
    146                                             
    147                                            rendererWidget->mControlWidget, 
    148                                            SLOT(UpdatePvsErrorItem(int i, 
    149                                                                                            GlRendererBuffer::PvsErrorEntry &))); 
    150           cout<<"CONNECTED"<<endl; 
    151         } 
    152          
    153         pt->start(QThread::LowPriority); 
    154          
    155          
    156   } else{ 
    157         // just call the mail method -> will be executed in the main thread 
    158         pt->Main(); 
    159   } 
    160    
    161  
    162   int returnCode = 0; 
    163  
    164   if (app) 
    165   { 
    166          returnCode = app->exec(); 
    167         DEL_PTR(app); 
    168         } 
    169  
    170   //-- clean up 
    171   DEL_PTR(p); 
    172   Environment::DelSingleton(); 
    173   DEL_PTR(rendererWidget); 
    174  
    175   MeshManager::DelSingleton(); 
    176   MaterialManager::DelSingleton(); 
    177  
    178   DEL_PTR(pt); 
    179  
    180   return returnCode; 
     153 
     154        //-- load scene  
     155 
     156        Environment::GetSingleton()->GetStringValue("Scene.filename", buff); 
     157        string filename(buff); 
     158        preprocessor->LoadScene(filename); 
     159 
     160        //-- build kd tree from scene geometry 
     161 
     162        preprocessor->BuildKdTree(); 
     163        preprocessor->KdTreeStatistics(cout); 
     164 
     165        // parse view cells related options 
     166        preprocessor->PrepareViewCells(); 
     167 
     168        //  p->mSceneGraph->Export("soda.x3d"); 
     169        if (0) { 
     170                preprocessor->Export(filename + "-out.x3d", true, false, false); 
     171                preprocessor->Export(filename + "-kdtree.x3d", false, true, false);      
     172        } 
     173 
     174 
     175        // create a preprocessor thread 
     176        //PreprocessorThread *pt = new PreprocessorThread(p, app); 
     177        PreprocessorThread pt(preprocessor); 
     178 
     179        if (preprocessor->mUseGlRenderer || preprocessor->mUseGlDebugger) 
     180        { 
     181                // display the render widget 
     182                DisplayWidget(); 
     183 
     184                // create and run the thread 
     185                boost::thread thrd(pt); 
     186                thrd.join(); 
     187                //pt->start(QThread::LowPriority); 
     188        }  
     189        else 
     190        { 
     191                // just call the mail method -> will be executed in the main thread 
     192                pt.Main(); 
     193        } 
     194 
     195#if QT_ENABLED 
     196        if (app) 
     197        { 
     198                returnCode = app->exec(); 
     199        DEL_PTR(app); 
     200        } 
     201#endif 
     202 
     203        Cleanup(); 
     204 
     205        return returnCode; 
    181206} 
    182207 
Note: See TracChangeset for help on using the changeset viewer.