Changeset 390 for trunk


Ignore:
Timestamp:
11/08/05 19:00:49 (19 years ago)
Author:
mattausch
Message:

changed bsp splitplane choosing functions

Location:
trunk/VUT/GtpVisibilityPreprocessor
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/GtpVisibilityPreprocessor/scripts/Preprocessor.vcproj

    r378 r390  
    2020                                Name="VCCLCompilerTool" 
    2121                                Optimization="0" 
    22                                 AdditionalIncludeDirectories="..\include" 
     22                                AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include" 
    2323                                PreprocessorDefinitions="WIN32;_DEBUG;_LIB" 
    2424                                MinimalRebuild="TRUE" 
     
    6262                        <Tool 
    6363                                Name="VCCLCompilerTool" 
    64                                 AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;..\include" 
     64                                AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include" 
    6565                                PreprocessorDefinitions="WIN32;NDEBUG;_LIB;" 
    6666                                RuntimeLibrary="2" 
     
    285285                        </File> 
    286286                        <File 
    287                                 RelativePath="..\src\VisibilityVector3.h"> 
    288                         </File> 
    289                         <File 
    290287                                RelativePath="..\src\VssPreprocessor.cpp"> 
    291288                        </File> 
     
    365362                        </File> 
    366363                </Filter> 
    367                 <File 
    368                         RelativePath=".\VTune\Preprocessor.vpj"> 
    369                 </File> 
    370364        </Files> 
    371365        <Globals> 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp

    r389 r390  
    12151215                 "5"); 
    12161216 
     1217  RegisterOption("BspTree.Termination.minPvs", 
     1218                 optInt, 
     1219                 "-bsp_term_min_pvs=", 
     1220                 "20"); 
     1221 
    12171222   RegisterOption("BspTree.Termination.maxRays", 
    12181223                 optInt, 
     
    12761281 
    12771282   
    1278   RegisterOption("Bsptree.Visualization.samples", 
     1283  RegisterOption("BspTree.Visualization.samples", 
    12791284          optInt, 
    12801285          "-bsp_visualization_samples=", 
     
    12851290          "-bsp_visualization.exportSplits", 
    12861291          "false"); 
    1287  
    1288   RegisterOption("BspTree.Visualization.storePolys", 
    1289                  optBool, 
    1290                  "-bsp_visualization_store_polys=", 
    1291                  "false"); 
    12921292 
    12931293  RegisterOption("Preprocessor.type", 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h

    r387 r390  
    153153                 
    154154        virtual ostream &Describe(ostream &s) { 
    155                 return s<<"Mesh #vertices="<<mVertices.size()<<" #faces="<<mFaces.size(); 
     155                return s<<"Mesh #vertices="<<(int)mVertices.size()<<" #faces="<<(int)mFaces.size(); 
    156156        } 
    157157 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp

    r384 r390  
    439439 
    440440        for (pit = cell.begin(); pit != cell.end(); ++ pit) 
     441        { 
    441442                area += (*pit)->GetArea(); 
    442  
     443        } 
    443444        return area; 
    444445} 
  • trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp

    r389 r390  
    1515  environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples); 
    1616  environment->GetIntValue("ViewCells.PostProcessing.samples", mPostProcessSamples); 
    17   environment->GetIntValue("BspTree.visualizationSamples", mVisualizationSamples); 
     17  environment->GetIntValue("BspTree.Visualization.samples", mVisualizationSamples); 
    1818 
    1919  mKdPvsDepth = 100; 
     
    728728        } 
    729729        // save rays for post processing 
    730         else if ((int)mSampleRays.size() < mPostProcessSamples) || 
    731                         (((int)mSampleRays.size() < mVisualizationSamples)) 
     730        else if (((int)mSampleRays.size() < mPostProcessSamples) || 
     731                         ((int)mSampleRays.size() < mVisualizationSamples)) 
    732732        { 
    733733                mSampleRays.push_back(new Ray(ray)); 
     
    747747        for (int i = 0; i < limit; ++i) 
    748748        {   
    749                 Ray *ray = mSamplesRays[i]; 
     749                Ray *ray = mSampleRays[i]; 
    750750 
    751751                // traverse leaves stored in the rays and compare and merge consecutive 
     
    842842        //-- some rays for output 
    843843        const int raysOut = min((int)mSampleRays.size(), mVisualizationSamples); 
     844        cout << "visualization using " << mVisualizationSamples << " samples" << endl; 
    844845        vector<Ray *> vcRays[leafOut]; 
    845846 
     
    882883                        ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 
    883884 
     885                        //exporter->SetWireframe(); 
     886                        exporter->SetFilled(); 
     887 
     888                        Material m;//= RandomMaterial(); 
     889                        m.mDiffuseColor = RgbColor(0, 1, 0); 
     890                        exporter->SetForcedMaterial(m); 
     891 
     892                        if (vc->GetMesh()) 
     893                                exporter->ExportViewCell(vc); 
     894                        else 
     895                        { 
     896                                PolygonContainer cell; 
     897                                // export view cell geometry 
     898                                mBspTree->ConstructGeometry(vc, cell); 
     899                                exporter->ExportPolygons(cell); 
     900                                CLEAR_CONTAINER(cell); 
     901                        } 
     902 
     903                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()  
     904                                        << ", piercing rays=" << (int)vcRays[i].size() << endl; 
     905 
     906                        // export rays piercing this view cell 
     907                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0)); 
     908 
     909                        m.mDiffuseColor = RgbColor(1, 0, 0); 
     910                        exporter->SetForcedMaterial(m); 
     911 
    884912                        exporter->SetWireframe(); 
     913 
     914                        // output PVS of view cell 
     915                        for (; it != vc->GetPvs().mEntries.end(); ++ it)  
     916                        { 
     917                                Intersectable *intersect = (*it).first; 
     918                                if (!intersect->Mailed()) 
     919                                { 
     920                                        exporter->ExportIntersectable(intersect); 
     921                                        intersect->Mail(); 
     922                                }                        
     923                        } 
     924                                 
     925                        // output rest of the objects 
     926                        if (0) 
     927                        { 
     928                                Material m;//= RandomMaterial(); 
     929                                m.mDiffuseColor = RgbColor(0, 0, 1); 
     930                                exporter->SetForcedMaterial(m); 
     931 
     932                                for (int j = 0; j < objects.size(); ++ j) 
     933                                        if (!objects[j]->Mailed()) 
     934                                        { 
     935                                                exporter->SetForcedMaterial(m); 
     936                                                exporter->ExportIntersectable(objects[j]); 
     937                                                objects[j]->Mail(); 
     938                                        } 
     939                        } 
     940                        DEL_PTR(exporter); 
     941                        cout << "finished" << endl; 
     942                } 
     943        } 
     944        else 
     945        { 
     946                ViewCellContainer viewCells; 
     947 
     948                mBspTree->CollectViewCells(viewCells); 
     949                stable_sort(viewCells.begin(), viewCells.end(), vc_gt); 
     950 
     951                int limit = min(leafOut, (int)viewCells.size());  
     952                 
     953                for (int i = 0; i < limit; ++ i) 
     954                { 
     955                        cout << "creating output for view cell " << i << " ... "; 
     956                         
     957            Intersectable::NewMail(); 
     958                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]); 
     959 
     960                        cout << "creating output for view cell " << i << " ... "; 
     961                        // check whether we can add the current ray to the output rays 
     962                        for (int k = 0; k < raysOut; ++ k)  
     963                        { 
     964                                Ray *ray = mSampleRays[k]; 
     965 
     966                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 
     967                                { 
     968                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf; 
     969 
     970                                        if (vc == leaf->GetViewCell())  
     971                                        { 
     972                                                vcRays[i].push_back(ray); 
     973                                        } 
     974                                } 
     975                        } 
     976 
     977                        //bspLeaves[j]->Mail(); 
     978                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 
     979 
     980                        Exporter *exporter = Exporter::GetExporter(s); 
     981                        exporter->SetFilled(); 
     982 
     983                        ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 
     984 
     985                        exporter->SetFilled();//Wireframe(); 
    885986 
    886987                        Material m;//= RandomMaterial(); 
     
    8991000                        } 
    9001001 
    901                         Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()  
    902                                         << ", piercing rays=" << (int)vcRays[i].size() << endl; 
    903  
     1002                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() << endl; 
     1003 
     1004                         
    9041005                        // export rays piercing this view cell 
    905                         exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0)); 
     1006                        exporter->ExportRays(vcRays[i], 10000, RgbColor(0, 1, 0)); 
    9061007 
    9071008                        m.mDiffuseColor = RgbColor(1, 0, 0); 
     
    9191020                        } 
    9201021                                 
    921                         // output rest of the objects 
    922                         if (0) 
    923                         { 
    924                                 Material m;//= RandomMaterial(); 
    925                                 m.mDiffuseColor = RgbColor(0, 0, 1); 
    926                                 exporter->SetForcedMaterial(m); 
    927  
    928                                 for (int j = 0; j < objects.size(); ++ j) 
    929                                         if (!objects[j]->Mailed()) 
    930                                         { 
    931                                                 exporter->SetForcedMaterial(m); 
    932                                                 exporter->ExportIntersectable(objects[j]); 
    933                                                 objects[j]->Mail(); 
    934                                         } 
    935                         } 
    936                         DEL_PTR(exporter); 
    937                         cout << "finished" << endl; 
    938                 } 
    939         } 
    940         else 
    941         { 
    942                 ViewCellContainer viewCells; 
    943  
    944                 mBspTree->CollectViewCells(viewCells); 
    945                 stable_sort(viewCells.begin(), viewCells.end(), vc_gt); 
    946  
    947                 int limit = min(leafOut, (int)viewCells.size());  
    948                  
    949                 for (int i = 0; i < limit; ++ i) 
    950                 { 
    951                         cout << "creating output for view cell " << i << " ... "; 
    952                          
    953             Intersectable::NewMail(); 
    954                         BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]); 
    955  
    956                         cout << "creating output for view cell " << i << " ... "; 
    957                         // check whether we can add the current ray to the output rays 
    958                         for (int k = 0; k < raysOut; ++ k)  
    959                         { 
    960                                 Ray *ray = mSampleRays[k]; 
    961  
    962                                 for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 
    963                                 { 
    964                                         BspLeaf *leaf = ray->bspIntersections[j].mLeaf; 
    965  
    966                                         if (vc == leaf->GetViewCell())  
    967                                         { 
    968                                                 vcRays[i].push_back(ray); 
    969                                         } 
    970                                 } 
    971                         } 
    972  
    973                         //bspLeaves[j]->Mail(); 
    974                         char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 
    975  
    976                         Exporter *exporter = Exporter::GetExporter(s); 
    977                         exporter->SetFilled(); 
    978  
    979                         ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 
    980  
    981                         exporter->SetWireframe(); 
    982  
    983                         Material m;//= RandomMaterial(); 
    984                         m.mDiffuseColor = RgbColor(0, 1, 0); 
    985                         exporter->SetForcedMaterial(m); 
    986  
    987                         if (vc->GetMesh()) 
    988                                 exporter->ExportViewCell(vc); 
    989                         else 
    990                         { 
    991                                 PolygonContainer cell; 
    992                                 // export view cell 
    993                                 mBspTree->ConstructGeometry(vc, cell); 
    994                                 exporter->ExportPolygons(cell); 
    995                                 CLEAR_CONTAINER(cell); 
    996                         } 
    997  
    998                         Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() << endl; 
    999  
    1000                          
    1001                         // export rays piercing this view cell 
    1002                         exporter->ExportRays(vcRays[i], 10000, RgbColor(0, 1, 0)); 
    1003  
    1004                         m.mDiffuseColor = RgbColor(1, 0, 0); 
    1005                         exporter->SetForcedMaterial(m); 
    1006  
    1007                         // output PVS of view cell 
    1008                         for (; it != vc->GetPvs().mEntries.end(); ++ it)  
    1009                         { 
    1010                                 Intersectable *intersect = (*it).first; 
    1011                                 if (!intersect->Mailed()) 
    1012                                 { 
    1013                                         exporter->ExportIntersectable(intersect); 
    1014                                         intersect->Mail(); 
    1015                                 }                        
    1016                         } 
    1017                                  
    10181022                        DEL_PTR(exporter); 
    10191023                        cout << "finished" << endl; 
  • trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h

    r380 r390  
    3030  int mBspConstructionSamples; 
    3131  int mPostProcessSamples; 
    32  
     32  int mVisualizationSamples; 
    3333 
    3434  void 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp

    r389 r390  
    1515 
    1616int BspTree::sTermMaxPolygons = 10; 
     17int BspTree::sTermMinPvs = 20; 
    1718int BspTree::sTermMaxDepth = 20; 
    1819int BspTree::sMaxPolyCandidates = 10; 
     
    4647float BspTree::sPvsFactor = 1.0f; 
    4748 
    48 bool BspTree::sStoreSplitPolys = false; 
    49  
    5049int BspNode::mailID = 1; 
    5150 
     
    7372 
    7473BspNode::BspNode():  
    75 mParent(NULL), mPolygons(NULL) 
     74mParent(NULL) 
    7675{} 
    7776 
    7877BspNode::BspNode(BspInterior *parent):  
    79 mParent(parent), mPolygons(NULL) 
     78mParent(parent) 
    8079{} 
    8180 
    82 BspNode::~BspNode() 
    83 { 
    84         if (mPolygons) 
    85         { 
    86                 CLEAR_CONTAINER(*mPolygons); 
    87                 DEL_PTR(mPolygons); 
    88         } 
    89 } 
    9081 
    9182bool BspNode::IsRoot() const  
     
    10394        mParent = parent; 
    10495} 
    105  
    106 PolygonContainer *BspNode::GetPolygons() 
    107 { 
    108         if (!mPolygons) 
    109                 mPolygons = new PolygonContainer(); 
    110  
    111         return mPolygons; 
    112 } 
    113  
    114 void BspNode::ProcessPolygons(PolygonContainer *polys, bool storePolys) 
    115 { 
    116         if (storePolys) 
    117         { 
    118                 while (!polys->empty()) 
    119                 { 
    120                         GetPolygons()->push_back(polys->back()); 
    121                         polys->pop_back(); 
    122                 } 
    123         } 
    124         else CLEAR_CONTAINER(*polys); 
    125 } 
    126  
    12796 
    12897/****************************************************************/ 
     
    169138} 
    170139 
    171 void BspInterior::ProcessPolygon(Polygon3 **poly, const bool storePolys) 
    172 { 
    173         if (storePolys)  
    174                 GetPolygons()->push_back(*poly); 
    175         else 
    176                 DEL_PTR(*poly); 
    177 } 
    178  
    179140int BspInterior::SplitPolygons(PolygonContainer &polys,  
    180141                                                           PolygonContainer &frontPolys,  
    181142                                                           PolygonContainer &backPolys,  
    182                                                            PolygonContainer &coincident, 
    183                                                            const bool storePolys) 
     143                                                           PolygonContainer &coincident) 
    184144{ 
    185145        Polygon3 *splitPoly = NULL; 
     
    246206                                Debug << "split " << *poly << endl << *front_piece << endl << *back_piece << endl; 
    247207#endif 
    248                                 ProcessPolygon(&poly, storePolys);                       
     208                                DEL_PTR(poly);                   
    249209                                break; 
    250210                        default: 
     
    449409                mRoot = new BspLeaf(); 
    450410 
    451         tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new BoundedRayContainer())); 
     411        tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new BoundedRayContainer(), 0,  
     412                                                                 mBox.SurfaceArea(), new BspNodeGeometry())); 
    452413 
    453414        while (!tStack.empty()) 
     
    471432                 
    472433                                // split viewcell polygons with respect to split plane 
    473                                 splits += interior->SplitPolygons(*tData.mPolygons,  
     434                                splits += interior->SplitPolygons(*tData.mPolygons, 
    474435                                                                                                  *frontPolys,  
    475436                                                                                                  *backPolys, 
    476                                                                                                   coincident, 
    477                                                                                                   sStoreSplitPolys); 
     437                                                                                                  coincident); 
    478438                                 
    479439                                // extract view cells associated with the split polygons 
    480440                                ViewCell *frontViewCell = mRootCell; 
    481441                                ViewCell *backViewCell = mRootCell; 
    482          
     442                         
     443                                BspTraversalData frontData(interior->GetFront(),  
     444                                                                                   frontPolys,  
     445                                                                                   tData.mDepth + 1, 
     446                                                                                   mRootCell,    
     447                                                                                   tData.mRays, 
     448                                                                                   tData.mPvs, 
     449                                                                                   mBox.SurfaceArea(), 
     450                                                                                   new BspNodeGeometry()); 
     451 
     452                                BspTraversalData backData(interior->GetBack(),  
     453                                                                                  backPolys, 
     454                                                                                  tData.mDepth + 1, 
     455                                                                                  mRootCell,     
     456                                                                                  tData.mRays, 
     457                                                                                  tData.mPvs, 
     458                                                                                  mBox.SurfaceArea(), 
     459                                                                                  new BspNodeGeometry()); 
     460 
    483461                                if (!mGenerateViewCells) 
    484462                                { 
    485                                         ExtractViewCells(&backViewCell, 
    486                                                                          &frontViewCell, 
    487                                                                          coincident,  
    488                                                                          interior->mPlane,  
    489                                                                          frontPolys->empty(),  
    490                                                                          backPolys->empty()); 
     463                                        ExtractViewCells(frontData, 
     464                                                                         backData, 
     465                                                                         coincident, 
     466                                                                         interior->mPlane); 
    491467                                } 
    492468 
    493469                                // don't need coincident polygons anymore 
    494                                 interior->ProcessPolygons(&coincident, sStoreSplitPolys); 
     470                                CLEAR_CONTAINER(coincident); 
    495471 
    496472                                mStat.splits += splits; 
    497473 
    498474                                // push the children on the stack 
    499                                 tStack.push(BspTraversalData(interior->GetFront(),  
    500                                                                                          frontPolys,  
    501                                                                                          tData.mDepth + 1,  
    502                                                                                          frontViewCell, 
    503                                                                                          tData.mRays)); 
    504  
    505                                 tStack.push(BspTraversalData(interior->GetBack(),  
    506                                                                                          backPolys,  
    507                                                                                          tData.mDepth + 1,  
    508                                                                                          backViewCell, 
    509                                                                                          new BoundedRayContainer())); 
     475                                tStack.push(frontData); 
     476                                tStack.push(backData); 
    510477                        } 
    511478 
     
    704671        mRoot = new BspLeaf(); 
    705672 
    706         BspTraversalData tData(mRoot, polys, 0, mRootCell, rays); 
     673        BspNodeGeometry *cell = new BspNodeGeometry(); 
     674        ConstructGeometry(mRoot, *cell); 
     675 
     676        BspTraversalData tData(mRoot, polys, 0, mRootCell, rays,  
     677                                                   ComputePvsSize(*rays), cell->GetArea(), cell); 
     678 
    707679        tStack.push(tData); 
    708680 
     
    728700        //-- terminate traversal   
    729701        if (((int)tData.mPolygons->size() <= sTermMaxPolygons) ||  
    730                 ((int)tData.mRays->size() <= sTermMaxRays) || 
    731                 (tData.mDepth >= sTermMaxDepth)) 
     702                ((int)tData.mRays->size() <= sTermMaxRays)         || 
     703                ((int)tData.mPvs <= sTermMinPvs)            || 
     704                 (tData.mDepth >= sTermMaxDepth)) 
    732705                 
    733706        { 
     
    754727                //-- clean up 
    755728                 
    756                 // remaining polygons are discarded or added to node 
    757                 leaf->ProcessPolygons(tData.mPolygons, sStoreSplitPolys); 
    758                 DEL_PTR(tData.mPolygons); 
     729                // discard polygons 
     730                CLEAR_CONTAINER(*tData.mPolygons); 
    759731                // discard rays 
    760732                CLEAR_CONTAINER(*tData.mRays); 
     733 
     734                DEL_PTR(tData.mPolygons); 
    761735                DEL_PTR(tData.mRays); 
    762  
     736                DEL_PTR(tData.mCell); 
     737                 
    763738                return leaf; 
    764739        } 
     
    774749        BoundedRayContainer *backRays = new BoundedRayContainer(); 
    775750         
     751        BspTraversalData tFrontData(NULL, new PolygonContainer(), tData.mDepth + 1, mRootCell,  
     752                                                                new BoundedRayContainer(), 0, NULL, 0); 
     753        BspTraversalData tBackData(NULL, new PolygonContainer(), tData.mDepth + 1, mRootCell,  
     754                                                           new BoundedRayContainer(), 0, NULL, 0); 
     755 
    776756        // create new interior node and two leaf nodes 
    777         BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode),  
    778                                                                                   *tData.mPolygons, 
    779                                                                                   *frontPolys, 
    780                                                                                   *backPolys, 
    781                                                                                   coincident, 
    782                                                                                   *tData.mRays, 
    783                                                                                   *frontRays, 
    784                                                                                   *backRays); 
    785         ViewCell *frontViewCell = mRootCell; 
    786         ViewCell *backViewCell = mRootCell; 
    787  
    788          
     757        BspInterior *interior = SubdivideNode(tData, 
     758                                                                                  tFrontData, 
     759                                                                                  tBackData, 
     760                                                                                  coincident); 
     761 
    789762#ifdef _DEBUG    
    790763        if (frontPolys->empty() && backPolys->empty() && (coincident.size() > 2)) 
     
    798771        if (!mGenerateViewCells) 
    799772        { 
    800                 ExtractViewCells(&backViewCell, 
    801                                                  &frontViewCell, 
     773                ExtractViewCells(tFrontData, 
     774                                                 tBackData, 
    802775                                                 coincident, 
    803                                                  interior->mPlane, 
    804                                                  backPolys->empty(), 
    805                                                  frontPolys->empty()); 
    806         } 
    807          
    808         // don't need coincident polygons anymore 
    809         interior->ProcessPolygons(&coincident, sStoreSplitPolys); 
     776                                                 interior->mPlane); 
     777                                                  
     778        } 
     779 
     780        // don't need coincident polygons anymory 
     781        CLEAR_CONTAINER(coincident); 
    810782 
    811783        // push the children on the stack 
    812         tStack.push(BspTraversalData(interior->GetBack(),  
    813                                                                  backPolys,  
    814                                                                  tData.mDepth + 1,  
    815                                                                  backViewCell,  
    816                                                                  backRays)); 
    817  
    818         tStack.push(BspTraversalData(interior->GetFront(),  
    819                                                                  frontPolys,  
    820                                                                  tData.mDepth + 1,  
    821                                                                  frontViewCell,  
    822                                                                  frontRays)); 
     784        tStack.push(tFrontData); 
     785        tStack.push(tBackData); 
    823786 
    824787        // cleanup 
     
    826789        DEL_PTR(tData.mPolygons); 
    827790        DEL_PTR(tData.mRays); 
     791        DEL_PTR(tData.mCell);            
    828792 
    829793        return interior; 
    830794} 
    831795 
    832 void BspTree::ExtractViewCells(ViewCell **backViewCell,  
    833                                                            ViewCell **frontViewCell, 
     796void BspTree::ExtractViewCells(BspTraversalData &frontData, 
     797                                                           BspTraversalData &backData,  
    834798                                                           const PolygonContainer &coincident, 
    835                                                            const Plane3 splitPlane,  
    836                                                            const bool extractBack, 
    837                                                            const bool extractFront) const 
    838 { 
    839         bool foundFront = !extractFront, foundBack = !extractBack; 
     799                                                           const Plane3 splitPlane) const 
     800{ 
     801        // if not empty, tree is further subdivided => don't have to find view cell 
     802        bool foundFront = !frontData.mPolygons->empty(); 
     803        bool foundBack = !frontData.mPolygons->empty(); 
    840804 
    841805        PolygonContainer::const_iterator it =  
     
    847811                if (DotProd((*it)->GetNormal(), splitPlane.mNormal) > 0) 
    848812                { 
    849                         *backViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 
     813                        backData.mViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 
    850814                        foundBack = true; 
    851815                } 
    852816                else 
    853817                { 
    854                         *frontViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 
     818                        frontData.mViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 
    855819                        foundFront = true; 
    856820                } 
    857821        } 
    858         //if (extractFront && foundFront)       Debug << "front view cell: " << *frontViewCell << endl; 
    859         //if (extractBack && foundBack) Debug << "back view cell: " << *backViewCell << endl; 
    860 } 
    861  
    862 BspInterior *BspTree::SubdivideNode(BspLeaf *leaf,  
    863                                                                         PolygonContainer &polys, 
    864                                                                         PolygonContainer &frontPolys, 
    865                                                                         PolygonContainer &backPolys, 
    866                                                                         PolygonContainer &coincident, 
    867                                                                         BoundedRayContainer &rays, 
    868                                                                         BoundedRayContainer &frontRays, 
    869                                                                         BoundedRayContainer &backRays) 
     822} 
     823 
     824BspInterior *BspTree::SubdivideNode(BspTraversalData &tData, 
     825                                                                        BspTraversalData &frontData, 
     826                                                                        BspTraversalData &backData, 
     827                                                                        PolygonContainer &coincident) 
    870828{ 
    871829        mStat.nodes += 2; 
    872830         
     831        BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode); 
    873832        // select subdivision plane 
    874833        BspInterior *interior =  
    875                 new BspInterior(SelectPlane(leaf, polys, rays));  
     834                new BspInterior(SelectPlane(leaf, tData, frontData, backData));  
    876835 
    877836#ifdef _DEBUG 
     
    880839         
    881840        // subdivide rays into front and back rays 
    882         SplitRays(interior->mPlane, rays, frontRays, backRays); 
     841        SplitRays(interior->mPlane, *tData.mRays, *frontData.mRays, *backData.mRays); 
    883842         
    884843        // subdivide polygons with plane 
    885         mStat.splits += interior->SplitPolygons(polys,  
    886                                                     frontPolys,  
    887                                                                                         backPolys,  
    888                                                                                         coincident,  
    889                                                                                         sStoreSplitPolys); 
     844        mStat.splits += interior->SplitPolygons(*tData.mPolygons,  
     845                                                    *frontData.mPolygons,  
     846                                                                                        *backData.mPolygons,  
     847                                                                                        coincident); 
    890848 
    891849        BspInterior *parent = leaf->GetParent(); 
     
    904862        // and setup child links 
    905863        interior->SetupChildLinks(new BspLeaf(interior), new BspLeaf(interior)); 
     864         
     865        frontData.mNode = interior->mFront; 
     866        backData.mNode = interior->mBack; 
    906867         
    907868        return interior; 
     
    10491010 
    10501011Plane3 BspTree::SelectPlane(BspLeaf *leaf,  
    1051                                                         PolygonContainer &polys,  
    1052                                                         const BoundedRayContainer &rays) 
    1053 { 
    1054         if (polys.empty() && rays.empty()) 
     1012                                                        BspTraversalData &data, 
     1013                                                        BspTraversalData &frontData, 
     1014                                                        BspTraversalData &backData) 
     1015{ 
     1016        if (data.mPolygons->empty() && data.mRays->empty()) 
    10551017        { 
    10561018                Debug << "Warning: No autopartition polygon candidate available\n"; 
     
    10611023         
    10621024                // create bounding box of region 
    1063                 Polygon3::IncludeInBox(polys, box); 
     1025                Polygon3::IncludeInBox(*data.mPolygons, box); 
    10641026 
    10651027                const int axis = box.Size().DrivingAxis(); 
     
    10711033         
    10721034        if ((sSplitPlaneStrategy & AXIS_ALIGNED) && 
    1073                 ((int)polys.size() > sTermMaxPolysForAxisAligned) && 
    1074                 ((int)rays.size() > sTermMaxRaysForAxisAligned) && 
     1035                ((int)data.mPolygons->size() > sTermMaxPolysForAxisAligned) && 
     1036                ((int)data.mRays->size() > sTermMaxRaysForAxisAligned) && 
    10751037                ((sTermMaxObjectsForAxisAligned < 0) ||  
    1076                   (Polygon3::ParentObjectsSize(polys) > sTermMaxObjectsForAxisAligned))) 
     1038                  (Polygon3::ParentObjectsSize(*data.mPolygons) > sTermMaxObjectsForAxisAligned))) 
    10771039        { 
    10781040                Plane3 plane; 
    1079                 if (SelectAxisAlignedPlane(plane, polys)) 
     1041                if (SelectAxisAlignedPlane(plane, *data.mPolygons)) 
    10801042                        return plane; 
    10811043        } 
     
    10841046        if (sSplitPlaneStrategy & RANDOM_POLYGON) 
    10851047        { 
    1086                 return polys[Random((int)polys.size())]->GetSupportingPlane(); 
     1048                Polygon3 *nextPoly = (*data.mPolygons)[Random((int)data.mPolygons->size())]; 
     1049                return nextPoly->GetSupportingPlane(); 
    10871050        } 
    10881051 
    10891052        // use heuristics to find appropriate plane 
    1090         return SelectPlaneHeuristics(leaf, polys, rays, sMaxPolyCandidates,  
    1091                                                                  sMaxRayCandidates); 
     1053        return SelectPlaneHeuristics(leaf, data, frontData, backData);  
    10921054} 
    10931055 
    10941056Plane3 BspTree::SelectPlaneHeuristics(BspLeaf *leaf, 
    1095                                                                           PolygonContainer &polys, 
    1096                                                                           const BoundedRayContainer &rays, 
    1097                                                                           const int maxPolyCandidates, 
    1098                                                                           const int maxRayCandidates) 
     1057                                                                          BspTraversalData &data, 
     1058                                                                          BspTraversalData &frontData, 
     1059                                                                          BspTraversalData &backData) 
    10991060{ 
    11001061        float lowestCost = MAX_FLOAT; 
    1101         int bestPlaneIdx = 0; 
    1102          
    1103         int limit = maxPolyCandidates > 0 ?  
    1104                 Min((int)polys.size(), maxPolyCandidates) : (int)polys.size(); 
     1062        Plane3 bestPlane; 
     1063         
     1064        int limit = sMaxPolyCandidates > 0 ?  
     1065                Min((int)data.mPolygons->size(), sMaxPolyCandidates) : (int)data.mPolygons->size(); 
    11051066         
    11061067        int candidateIdx = limit; 
    11071068 
    1108         // only for pvs criterium 
    1109         PolygonContainer cell; 
    1110         vector<Plane3 *> planes; 
    1111         vector<bool> sides; 
    1112         int pvsSize = 0; 
    1113  
    1114         if (sSplitPlaneStrategy & PVS) 
    1115         { 
    1116                 ConstructGeometry(leaf, cell); 
    1117                 ExtractSplitPlanes(leaf, planes, sides); 
    1118                 pvsSize = ComputePvsSize(rays); 
    1119         } 
    1120  
    11211069        for (int i = 0; i < limit; ++ i) 
    11221070        { 
    1123                 candidateIdx = GetNextCandidateIdx(candidateIdx, polys); 
    1124                  
     1071                candidateIdx = GetNextCandidateIdx(candidateIdx, *data.mPolygons); 
     1072                 
     1073                Polygon3 *poly = (*data.mPolygons)[candidateIdx]; 
    11251074                // evaluate current candidate 
    11261075                const float candidateCost =  
    1127                         SplitPlaneCost(polys[candidateIdx]->GetSupportingPlane(),  
    1128                                                    polys, rays, cell, planes, sides, pvsSize); 
    1129  
    1130                 //Debug << polys[candidateIdx] << endl; 
     1076                        SplitPlaneCost(poly->GetSupportingPlane(), data, frontData, backData); 
     1077 
     1078                Debug << "cost: " << candidateCost << ", lowest: " << lowestCost << endl; 
     1079 
    11311080                if (candidateCost < lowestCost) 
    11321081                { 
    1133                         bestPlaneIdx = candidateIdx; 
     1082                        bestPlane = poly->GetSupportingPlane(); 
    11341083                        lowestCost = candidateCost; 
    11351084                } 
    11361085        } 
    11371086         
    1138         //limit = maxRaysCandidates > 0 ? Min((int)rays.size(), maxRayCandidates) : (int)rays.size(); 
    1139         bool chooseFromRays = false; 
    1140         int bestIdx[3]; 
    1141  
    1142         for (int i = 0; i < maxRayCandidates; ++ i) 
    1143         { 
    1144                 Vector3 pt[3]; 
    1145                 int idx[3]; 
    1146  
    1147                 for (int j = 0; j < 3; j ++) 
    1148                 { 
    1149                         idx[j] = Random((int)rays.size() * 2); 
     1087        //limit = maxRaysCandidates > 0 ? Min((int)rays.size(), maxRayCandidates) : (int)rays.size();    
     1088        const BoundedRayContainer *rays = data.mRays; 
     1089 
     1090        for (int i = 0; i < sMaxRayCandidates; ++ i) 
     1091        { 
     1092                Plane3 plane; 
     1093 
     1094                if (1) 
     1095                { 
     1096                        Vector3 pt[3]; 
     1097                        int idx[3]; 
     1098                         
     1099                        for (int j = 0; j < 3; j ++) 
     1100                        { 
     1101                                idx[j] = Random((int)rays->size() * 2); 
    11501102                                 
    1151                         if (idx[j] < (int)rays.size()) 
    1152                                 pt[j] = rays[idx[j]]->mRay->Extrap(rays[idx[j]]->mMinT); 
    1153                         else 
    1154                         { 
    1155                                 idx[j] -= (int)rays.size(); 
    1156                                 pt[j] = rays[idx[j]]->mRay->Extrap(rays[idx[j]]->mMaxT); 
    1157                         } 
    1158                                          
    1159                 } 
    1160  
    1161                 const float candidateCost = 
    1162                         SplitPlaneCost(Plane3(pt[0], pt[1], pt[2]),  
    1163                                                    polys, rays, cell, planes, sides, pvsSize); 
     1103                                BoundedRay *bRay = (*rays)[idx[j]]; 
     1104                                Ray *ray = bRay->mRay; 
     1105 
     1106                                if (idx[j] < (int)rays->size()) 
     1107                                        pt[j] = ray->Extrap(bRay->mMinT); 
     1108                                else 
     1109                                { 
     1110                                        idx[j] -= (int)rays->size(); 
     1111                                        pt[j] = ray->Extrap(bRay->mMaxT); 
     1112                                } 
     1113                        }        
     1114                 
     1115                        plane = Plane3(pt[0], pt[1], pt[2]); 
     1116                } 
     1117                else 
     1118                { 
     1119                        candidateIdx = Random((int)rays->size()); 
     1120                        BoundedRay *bRay = (*rays)[candidateIdx]; 
     1121 
     1122                        Ray *ray = bRay->mRay; 
     1123                                                 
     1124                        const Vector3 minPt = ray->Extrap(bRay->mMinT); 
     1125                        const Vector3 maxPt = ray->Extrap(bRay->mMaxT); 
     1126 
     1127                        const Vector3 pt = (maxPt + minPt) * 0.5; 
     1128 
     1129                        const Vector3 normal = ray->GetDir(); 
     1130                         
     1131                        plane = Plane3(normal, pt); 
     1132                } 
     1133                 
     1134                const float candidateCost =  
     1135                        SplitPlaneCost(plane, data, frontData, backData); 
    11641136 
    11651137                if (candidateCost < lowestCost) 
    11661138                { 
    1167                         chooseFromRays = true; 
    1168                         bestIdx[0] = idx[0]; bestIdx[1]= idx[1]; bestIdx[2] = idx[2]; 
     1139                        Debug << "choose ray plane: " << lowestCost << endl; 
     1140                        bestPlane = plane; 
    11691141                         
    11701142                        lowestCost = candidateCost; 
    11711143                } 
    1172         } 
    1173  
    1174         CLEAR_CONTAINER(cell); 
    1175  
    1176         if (chooseFromRays) 
    1177         { 
    1178                 Debug << "choose ray plane: " << lowestCost << endl; 
    1179                 return Plane3(rays[bestIdx[0]]->mRay->Extrap(rays[bestIdx[0]]->mMaxT), 
    1180                                           rays[bestIdx[1]]->mRay->Extrap(rays[bestIdx[1]]->mMaxT), 
    1181                                           rays[bestIdx[2]]->mRay->Extrap(rays[bestIdx[2]]->mMaxT)); 
     1144                else 
     1145                        Debug << "ray cost: " << candidateCost << ", lowest: " << lowestCost << endl; 
    11821146        } 
    11831147 
    11841148        //Debug << "Plane lowest cost: " << lowestCost << endl; 
    1185         return polys[bestPlaneIdx]->GetSupportingPlane(); 
     1149        return bestPlane; 
    11861150} 
    11871151 
     
    13371301float BspTree::SplitPlaneCost(const Plane3 &candidatePlane,  
    13381302                                                          const BoundedRayContainer &rays, 
    1339                                                           const float frontArea, 
    1340                                                           const float backArea, 
    1341                                                           const int pvsSize) const 
     1303                                                          const int pvs, 
     1304                                                          const float area, 
     1305                                                          const BspNodeGeometry &cell,  
     1306                                                          BspTraversalData &frontData, 
     1307                                                          BspTraversalData &backData) const 
    13421308{ 
    13431309        float val = 0; 
     
    13451311        float sumBalancedRays = 0; 
    13461312        float sumRaySplits = 0; 
    1347         float frontPvs = 0; 
    1348         float backPvs = 0; 
    1349  
    1350         float totalSize = 0; 
    1351          
    1352         // create three unique ids for pvs heuristics 
    1353         Intersectable::NewMail(); const int backId = ViewCell::sMailId; 
    1354         Intersectable::NewMail(); const int frontId = ViewCell::sMailId; 
    1355         Intersectable::NewMail(); const int frontAndBackId = ViewCell::sMailId; 
    1356  
    1357         int frontRays = 0; 
    1358         int backRays = 0; 
    1359                  
     1313         
     1314        int backId = 0; 
     1315        int frontId = 0; 
     1316        int frontAndBackId = 0; 
     1317 
     1318        frontData.mPvs = 0; 
     1319        backData.mPvs = 0; 
     1320        frontData.mArea = 0; 
     1321        backData.mArea = 0; 
     1322 
     1323        // probability that view point lies in child 
     1324        float pOverall = 0; 
     1325        float pFront = 0; 
     1326        float pBack = 0; 
     1327 
     1328        if (sSplitPlaneStrategy & PVS) 
     1329        { 
     1330                // create three unique ids for pvs heuristics 
     1331                Intersectable::NewMail(); backId = ViewCell::sMailId; 
     1332                Intersectable::NewMail(); frontId = ViewCell::sMailId; 
     1333                Intersectable::NewMail(); frontAndBackId = ViewCell::sMailId; 
     1334 
     1335                if (1) // use front and back cell areas to approximate volume 
     1336                { 
     1337                        //-- compute area 
     1338                 
     1339                        // construct child geometry with regard to the candidate split plane 
     1340                        frontData.mCell = cell.ConstructChild(*this, candidatePlane, true); 
     1341                        backData.mCell = cell.ConstructChild(*this, candidatePlane, false); 
     1342 
     1343                        frontData.mArea = frontData.mCell->GetArea(); 
     1344                        backData.mArea = backData.mCell->GetArea(); 
     1345 
     1346                        pFront = frontData.mArea; 
     1347                        pBack = backData.mArea; 
     1348 
     1349                        pOverall = area; 
     1350                } 
     1351                else 
     1352                { 
     1353                        pOverall = (float)rays.size(); 
     1354                } 
     1355        } 
     1356                         
    13601357        BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 
    13611358 
     
    13861383                                // assure that we only count a object  
    13871384                                // once for the front and once for the back side of the plane 
    1388                                 AddToPvs(*ray->intersections[0].mObject,  
    1389                                                    frontPvs, backPvs,  
    1390                                                    cf, frontId, backId, frontAndBackId); 
     1385                                AddToPvs(*ray->intersections[0].mObject, frontData.mPvs, backData.mPvs,  
     1386                                                 cf, frontId, backId, frontAndBackId); 
    13911387                        } 
    13921388 
    13931389                        // the source object in the origin of the ray 
    1394                         AddToPvs(*ray->sourceObject.mObject,  
    1395                                            frontPvs, backPvs,  
    1396                                            cf, frontId, backId, frontAndBackId); 
    1397  
     1390                        AddToPvs(*ray->sourceObject.mObject, frontData.mPvs, backData.mPvs,  
     1391                                         cf, frontId, backId, frontAndBackId); 
     1392 
     1393                        // use #rays to approximate volume 
    13981394                        if (0) 
    13991395                        { 
    14001396                                if ((cf == Ray::BACK) || (cf == Ray::FRONT_BACK) || (cf == Ray::BACK_FRONT)) 
    1401                                         ++ backRays; 
     1397                                        ++ pFront; 
    14021398                                if ((cf == Ray::FRONT) || (cf == Ray::FRONT_BACK) || (cf == Ray::BACK_FRONT)) 
    1403                                         ++ frontRays; 
     1399                                        ++ pBack; 
    14041400                        } 
    14051401                } 
    14061402        } 
    14071403 
    1408         if (sSplitPlaneStrategy & LEAST_RAY_SPLITS) 
    1409                 if (!rays.empty()) 
     1404        if ((sSplitPlaneStrategy & LEAST_RAY_SPLITS) && !rays.empty()) 
    14101405                        val += sLeastRaySplitsFactor * sumRaySplits / (float)rays.size(); 
    14111406 
    1412         if (sSplitPlaneStrategy & BALANCED_RAYS) 
    1413                 if (!rays.empty()) 
     1407        if ((sSplitPlaneStrategy & BALANCED_RAYS) && !rays.empty()) 
    14141408                        val += sBalancedRaysFactor * fabs(sumBalancedRays) / (float)rays.size(); 
    14151409 
    1416         if (sSplitPlaneStrategy & PVS) 
    1417                 if (0 && !rays.empty()) // HACK (should divide by maximal possible pvs) 
    1418                         val += sPvsFactor * (frontPvs * (float)frontRays + (backPvs * (float)backRays)) / (float)rays.size();  
    1419                 else 
    1420                         val += sPvsFactor * (frontPvs * frontArea + (backPvs * backArea)) / 
    1421                                 ((frontArea + backArea) * (float)pvsSize); 
    1422  
    1423         //Debug << "pvs: " << pvsSize << " val " << val << endl; 
     1410        if ((sSplitPlaneStrategy & PVS) && area && pvs) 
     1411                val += sPvsFactor * (frontData.mPvs * pFront + (backData.mPvs * pBack)) /       (pOverall * (float)pvs * 2); 
     1412 
     1413        Debug << "pvs: " << pvs << " totalArea: " << area  
     1414                  << " frontpvs: " << frontData.mPvs << " pFront: " << pFront  
     1415                  << " backpvs: " << backData.mPvs << " pBack: " << pBack  
     1416                  << " val " << val << endl; 
     1417 
    14241418        return val; 
    14251419} 
    14261420 
    14271421void BspTree::AddToPvs(Intersectable &obj, 
    1428                                            float &frontPvs, 
    1429                                            float &backPvs, 
     1422                                           int &frontPvs, 
     1423                                           int &backPvs, 
    14301424                                           const int cf,  
    14311425                                           const int frontId,  
     
    14411435                        (obj.mMailbox != frontAndBackId)) 
    14421436                { 
    1443                         frontPvs += 1.0; 
     1437                        ++ frontPvs; 
    14441438 
    14451439                        if (obj.mMailbox != backId) 
     
    14541448                        (obj.mMailbox != frontAndBackId)) 
    14551449                { 
    1456                         backPvs += 1.0; 
     1450                        ++ backPvs; 
    14571451 
    14581452                        if (obj.mMailbox != frontId) 
     
    14681462                { 
    14691463                        if (obj.mMailbox != frontId) 
    1470                                 frontPvs += 1.0; 
     1464                                ++ frontPvs; 
    14711465                        if (obj.mMailbox != backId) 
    1472                                 backPvs += 1.0; 
     1466                                ++ backPvs; 
    14731467                 
    14741468                        obj.mMailbox = frontAndBackId; 
     
    14771471} 
    14781472 
    1479 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane,  
    1480                                                           const PolygonContainer &polys,                                                           
    1481                                                           const BoundedRayContainer &rays, 
    1482                                                           const PolygonContainer &cell, 
    1483                                                           const vector<Plane3 *> &planes, 
    1484                                                           const vector<bool> &sides, 
    1485                                                           const int pvsSize) const 
     1473float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 
     1474                                                          BspTraversalData &data, 
     1475                                                          BspTraversalData &frontData, 
     1476                                                          BspTraversalData &backData) const 
    14861477{ 
    14871478        float val = 0; 
     
    15031494                (sSplitPlaneStrategy & BLOCKED_RAYS)) 
    15041495        { 
    1505         val += SplitPlaneCost(candidatePlane, polys); 
     1496                val += SplitPlaneCost(candidatePlane, *data.mPolygons); 
    15061497        } 
    15071498 
     
    15111502                (sSplitPlaneStrategy & PVS)) 
    15121503        { 
    1513                 float frontArea = 0; 
    1514                 float backArea = 0; 
    1515  
    1516                 if (sSplitPlaneStrategy & PVS) 
    1517                 { 
    1518                         PolygonContainer frontCell; 
    1519                         PolygonContainer backCell; 
    1520  
    1521                         // construct child geometry with regard to the candidate split plane 
    1522                         ConstructChildGeometry(frontCell, cell, planes, sides, candidatePlane, true); 
    1523                         ConstructChildGeometry(backCell, cell, planes, sides, candidatePlane, false); 
    1524  
    1525                         frontArea = Polygon3::GetArea(frontCell); 
    1526                         backArea = Polygon3::GetArea(backCell); 
    1527  
    1528                         CLEAR_CONTAINER(frontCell); 
    1529                         CLEAR_CONTAINER(backCell); 
    1530                 } 
    1531                  
    1532                 val += SplitPlaneCost(candidatePlane, rays, frontArea, backArea, pvsSize); 
     1504                val += SplitPlaneCost(candidatePlane, *data.mRays, data.mPvs,  
     1505                                                          data.mArea, *data.mCell, frontData, backData); 
    15331506        } 
    15341507 
     
    15621535        //-- termination criteria for autopartition 
    15631536        environment->GetIntValue("BspTree.Termination.maxDepth", sTermMaxDepth); 
     1537        environment->GetIntValue("BspTree.Termination.minPvs", sTermMinPvs); 
    15641538        environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons); 
    15651539        environment->GetIntValue("BspTree.Termination.maxRays", sTermMaxRays); 
     
    15791553        environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy); 
    15801554        environment->GetFloatValue("BspTree.AxisAligned.splitBorder", sSplitBorder); 
    1581          
    1582         environment->GetBoolValue("BspTree.Visualization.storePolys", sStoreSplitPolys); 
    15831555 
    15841556        environment->GetFloatValue("BspTree.Construction.sideTolerance", Vector3::sDistTolerance); 
     
    15911563 
    15921564    Debug << "BSP max depth: " << sTermMaxDepth << endl; 
     1565        Debug << "BSP min PVS: " << sTermMinPvs << endl; 
    15931566        Debug << "BSP max polys: " << sTermMaxPolygons << endl; 
    15941567        Debug << "BSP max rays: " << sTermMaxRays << endl; 
     
    16731646                mStat.minDepth = data.mDepth; 
    16741647 
     1648        // store minimal and maximal pvs 
     1649        /*if (data.mPvs > mStat.pvs) 
     1650                mStat.pvs = data.mPvs; 
     1651         
     1652        if (data.mPvs < mStat.pvs) 
     1653                mStat.pvs = data.mPvs;*/ 
     1654 
    16751655        // accumulate depth to compute average 
    16761656        mStat.accumDepth += data.mDepth; 
     
    16791659        Debug << "BSP stats: " 
    16801660                  << "Depth: " << data.mDepth << " (max: " << sTermMaxDepth << "), " 
     1661                   << "PVS: " << data.mPvs << " (max: " << sTermMinPvs << "), " 
    16811662                  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << sTermMaxPolygons << "), " 
    16821663                  << "#rays: " << (int)data.mRays->size() << " (max: " << sTermMaxRays << "), "  
     
    19751956                { 
    19761957                case Ray::COINCIDENT: 
    1977                         frontRays.push_back(bRay); 
     1958                        //frontRays.push_back(bRay); 
    19781959                        break; 
    19791960                case Ray::BACK: 
     
    20242005 
    20252006void BspTree::ExtractSplitPlanes(BspNode *n,  
    2026                                                                  vector<Plane3 *> &planes,  
     2007                                                                 vector<Plane3> &planes,  
    20272008                                                                 vector<bool> &sides) const 
    20282009{ 
     
    20402021                        BspInterior *interior = dynamic_cast<BspInterior *>(n); 
    20412022 
    2042                         planes.push_back(dynamic_cast<BspInterior *>(interior)->GetPlane()); 
     2023                        planes.push_back(* dynamic_cast<BspInterior *>(interior)->GetPlane()); 
    20432024                        sides.push_back(interior->mFront == lastNode); 
    20442025                } 
     
    20472028} 
    20482029 
    2049 bool BspTree::ConstructChildGeometry(PolygonContainer &childCell, 
    2050                                                                          const PolygonContainer &cell, 
    2051                                                                          const vector<Plane3 *> &planes, 
    2052                                                                          const vector<bool> &sides, 
    2053                                                                          const Plane3 &splitPlane, 
    2054                                                                          const bool side) const 
    2055 { 
     2030void BspTree::ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const 
     2031{ 
     2032        stack<BspNode *> tStack; 
     2033 
     2034        vector<Plane3> planes; 
     2035        vector<bool> sides; 
     2036 
     2037        ExtractSplitPlanes(n, cell.mPlanes, cell.mSides); 
     2038 
     2039        PolygonContainer candidatePolys; 
     2040 
     2041        // bounded planes are added to the polygons 
     2042        for (int i = 0; i < (int)cell.mPlanes.size(); ++ i) 
     2043        { 
     2044                candidatePolys.push_back(GetBoundingBox().CrossSection(cell.mPlanes[i])); 
     2045        } 
     2046 
     2047        // add faces of bounding box (also could be faces of the cell) 
     2048        for (int i = 0; i < 6; ++ i) 
     2049        { 
     2050                VertexContainer vertices; 
     2051         
     2052                for (int j = 0; j < 4; ++ j) 
     2053                        vertices.push_back(mBox.GetFace(i).mVertices[j]); 
     2054 
     2055                candidatePolys.push_back(new Polygon3(vertices)); 
     2056        } 
     2057 
     2058        for (int i = 0; i < (int)candidatePolys.size(); ++ i) 
     2059        { 
     2060                bool inside = true; 
     2061 
     2062                // polygon is split by all other planes 
     2063                for (int j = 0; (j < cell.mPlanes.size()) && inside; ++ j) 
     2064                { 
     2065                        if (i == j) // same plane 
     2066                                continue; 
     2067 
     2068                        VertexContainer splitPts; 
     2069                        Polygon3 *frontPoly, *backPoly; 
     2070 
     2071                        const int cf = candidatePolys[i]->ClassifyPlane(cell.mPlanes[j]); 
     2072                         
     2073                        switch (cf) 
     2074                        { 
     2075                                case Polygon3::SPLIT: 
     2076                                        frontPoly = new Polygon3(); 
     2077                                        backPoly = new Polygon3(); 
     2078                                 
     2079                                        candidatePolys[i]->Split(cell.mPlanes[j], *frontPoly,  
     2080                                                                                         *backPoly, splitPts); 
     2081                                        DEL_PTR(candidatePolys[i]); 
     2082 
     2083                                        if(sides[j] == true) 
     2084                                        { 
     2085                                                candidatePolys[i] = frontPoly; 
     2086                                                DEL_PTR(backPoly); 
     2087                                        } 
     2088                                        else 
     2089                                        { 
     2090                                                candidatePolys[i] = backPoly; 
     2091                                                DEL_PTR(frontPoly); 
     2092                                        } 
     2093                                         
     2094                                        break; 
     2095 
     2096                                case Polygon3::BACK_SIDE: 
     2097                                        if (cell.mSides[j])  
     2098                                                inside = false; 
     2099                                        break; 
     2100                                case Polygon3::FRONT_SIDE: 
     2101                                        if (!cell.mSides[j]) 
     2102                                                inside = false; 
     2103                                        break; 
     2104                                case Polygon3::COINCIDENT: 
     2105                                        break; 
     2106                                default: 
     2107                                        break; 
     2108                        } 
     2109                } 
     2110                 
     2111                if (inside) 
     2112                        cell.mPolys.push_back(candidatePolys[i]); 
     2113                else 
     2114                        DEL_PTR(candidatePolys[i]); 
     2115        } 
     2116} 
     2117 
     2118void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 
     2119{ 
     2120        stack<BspNode *> tStack; 
     2121 
     2122        vector<Plane3> planes; 
     2123        vector<bool> sides; 
     2124 
     2125        ExtractSplitPlanes(n, planes, sides); 
     2126 
     2127        PolygonContainer candidatePolys; 
     2128 
     2129        // bounded planes are added to the polygons 
     2130        for (int i = 0; i < (int)planes.size(); ++ i) 
     2131        { 
     2132                candidatePolys.push_back(GetBoundingBox().CrossSection(planes[i])); 
     2133        } 
     2134 
     2135        // add faces of bounding box (also could be faces of the cell) 
     2136        for (int i = 0; i < 6; ++ i) 
     2137        { 
     2138                VertexContainer vertices; 
     2139         
     2140                for (int j = 0; j < 4; ++ j) 
     2141                        vertices.push_back(mBox.GetFace(i).mVertices[j]); 
     2142 
     2143                candidatePolys.push_back(new Polygon3(vertices)); 
     2144        } 
     2145 
     2146        for (int i = 0; i < (int)candidatePolys.size(); ++ i) 
     2147        { 
     2148                bool inside = true; 
     2149 
     2150                // polygon is split by all other planes 
     2151                for (int j = 0; (j < planes.size()) && inside; ++ j) 
     2152                { 
     2153                        if (i == j) // same plane 
     2154                                continue; 
     2155 
     2156                        VertexContainer splitPts; 
     2157                        Polygon3 *frontPoly, *backPoly; 
     2158 
     2159                        const int cf = candidatePolys[i]->ClassifyPlane(planes[j]); 
     2160                         
     2161                        switch (cf) 
     2162                        { 
     2163                                case Polygon3::SPLIT: 
     2164                                        frontPoly = new Polygon3(); 
     2165                                        backPoly = new Polygon3(); 
     2166 
     2167                                        candidatePolys[i]->Split(planes[j], *frontPoly,  
     2168                                                                                         *backPoly, splitPts); 
     2169                                        DEL_PTR(candidatePolys[i]); 
     2170 
     2171                                        if(sides[j] == true) 
     2172                                        { 
     2173                                                candidatePolys[i] = frontPoly; 
     2174                                                DEL_PTR(backPoly); 
     2175                                        } 
     2176                                        else 
     2177                                        { 
     2178                                                candidatePolys[i] = backPoly; 
     2179                                                DEL_PTR(frontPoly); 
     2180                                        } 
     2181                                         
     2182                                        break; 
     2183 
     2184                                case Polygon3::BACK_SIDE: 
     2185                                        if (sides[j])  
     2186                                                inside = false; 
     2187                                        break; 
     2188                                case Polygon3::FRONT_SIDE: 
     2189                                        if (!sides[j]) 
     2190                                                inside = false; 
     2191                                        break; 
     2192                                case Polygon3::COINCIDENT: 
     2193                                        break; 
     2194                                default: 
     2195                                        break; 
     2196                        } 
     2197                } 
     2198                 
     2199                if (inside) 
     2200                        cell.push_back(candidatePolys[i]); 
     2201                else 
     2202                        DEL_PTR(candidatePolys[i]); 
     2203        } 
     2204} 
     2205 
     2206void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const 
     2207{ 
     2208        vector<BspLeaf *> leaves = vc->mBspLeaves; 
     2209 
     2210        vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
     2211 
     2212        for (it = leaves.begin(); it != it_end; ++ it) 
     2213                ConstructGeometry(*it, cell); 
     2214} 
     2215 
     2216int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,  
     2217                                                   const bool onlyUnmailed) const 
     2218{ 
     2219        PolygonContainer cell; 
     2220 
     2221        ConstructGeometry(n, cell); 
     2222 
     2223        stack<BspNode *> nodeStack; 
     2224        nodeStack.push(mRoot); 
     2225                 
     2226        // planes needed to verify that we found neighbor leaf. 
     2227        vector<Plane3> planes; 
     2228        vector<bool> sides; 
     2229 
     2230        ExtractSplitPlanes(n, planes, sides); 
     2231 
     2232        while (!nodeStack.empty())  
     2233        { 
     2234                BspNode *node = nodeStack.top(); 
     2235                nodeStack.pop(); 
     2236 
     2237                if (node->IsLeaf()) 
     2238                { 
     2239            if (node != n && (!onlyUnmailed || !node->Mailed())) 
     2240                        { 
     2241                                // test all planes of current node on neighbour 
     2242                                PolygonContainer neighborCandidate; 
     2243                                ConstructGeometry(node, neighborCandidate); 
     2244                                 
     2245                                bool isAdjacent = true; 
     2246                                for (int i = 0; (i < planes.size()) && isAdjacent; ++ i) 
     2247                                { 
     2248                                        const int cf =  
     2249                                                Polygon3::ClassifyPlane(neighborCandidate, planes[i]); 
     2250 
     2251                                        if ((cf == Polygon3::BACK_SIDE) && sides[i]) 
     2252                                                isAdjacent = false; 
     2253                                        else if ((cf == Polygon3::FRONT_SIDE) && !sides[i]) 
     2254                                                isAdjacent = false; 
     2255                                } 
     2256 
     2257                                if (isAdjacent) 
     2258                                        neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 
     2259 
     2260                                CLEAR_CONTAINER(neighborCandidate); 
     2261                        } 
     2262                } 
     2263                else  
     2264                { 
     2265                        BspInterior *interior = dynamic_cast<BspInterior *>(node); 
     2266         
     2267                        const int cf = Polygon3::ClassifyPlane(cell, interior->mPlane); 
     2268 
     2269                        if (cf == Polygon3::FRONT_SIDE) 
     2270                                nodeStack.push(interior->mFront); 
     2271                        else 
     2272                                if (cf == Polygon3::BACK_SIDE) 
     2273                                        nodeStack.push(interior->mBack); 
     2274                                else  
     2275                                { 
     2276                                        // random decision 
     2277                                        nodeStack.push(interior->mBack); 
     2278                                        nodeStack.push(interior->mFront); 
     2279                                } 
     2280                } 
     2281        } 
     2282         
     2283        CLEAR_CONTAINER(cell); 
     2284        return (int)neighbors.size(); 
     2285} 
     2286 
     2287BspLeaf *BspTree::GetRandomLeaf(const Plane3 &halfspace) 
     2288{ 
     2289    stack<BspNode *> nodeStack; 
     2290        nodeStack.push(mRoot); 
     2291         
     2292        int mask = rand(); 
     2293   
     2294        while (!nodeStack.empty())  
     2295        { 
     2296                BspNode *node = nodeStack.top(); 
     2297                nodeStack.pop(); 
     2298           
     2299                if (node->IsLeaf())  
     2300                { 
     2301                        return dynamic_cast<BspLeaf *>(node); 
     2302                }  
     2303                else  
     2304                { 
     2305                        BspInterior *interior = dynamic_cast<BspInterior *>(node); 
     2306                         
     2307                        BspNode *next; 
     2308         
     2309                        PolygonContainer cell; 
     2310 
     2311                        // todo: not very efficient: constructs full cell everytime 
     2312                        ConstructGeometry(interior, cell); 
     2313 
     2314                        const int cf = Polygon3::ClassifyPlane(cell, halfspace); 
     2315 
     2316                        if (cf == Polygon3::BACK_SIDE) 
     2317                                next = interior->mFront; 
     2318                        else 
     2319                                if (cf == Polygon3::FRONT_SIDE) 
     2320                                        next = interior->mFront; 
     2321                        else  
     2322                        { 
     2323                                // random decision 
     2324                                if (mask & 1) 
     2325                                        next = interior->mBack; 
     2326                                else 
     2327                                        next = interior->mFront; 
     2328                                mask = mask >> 1; 
     2329                        } 
     2330 
     2331                        nodeStack.push(next); 
     2332                } 
     2333        } 
     2334         
     2335        return NULL; 
     2336} 
     2337 
     2338BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 
     2339{ 
     2340        stack<BspNode *> nodeStack; 
     2341         
     2342        nodeStack.push(mRoot); 
     2343 
     2344        int mask = rand(); 
     2345         
     2346        while (!nodeStack.empty())  
     2347        { 
     2348                BspNode *node = nodeStack.top(); 
     2349                nodeStack.pop(); 
     2350                 
     2351                if (node->IsLeaf())  
     2352                { 
     2353                        if ( (!onlyUnmailed || !node->Mailed()) ) 
     2354                                return dynamic_cast<BspLeaf *>(node); 
     2355                } 
     2356                else  
     2357                { 
     2358                        BspInterior *interior = dynamic_cast<BspInterior *>(node); 
     2359 
     2360                        // random decision 
     2361                        if (mask & 1) 
     2362                                nodeStack.push(interior->mBack); 
     2363                        else 
     2364                                nodeStack.push(interior->mFront); 
     2365 
     2366                        mask = mask >> 1; 
     2367                } 
     2368        } 
     2369         
     2370        return NULL; 
     2371} 
     2372 
     2373int BspTree::ComputePvsSize(const BoundedRayContainer &rays) const 
     2374{ 
     2375        int pvsSize = 0; 
     2376 
     2377        BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 
     2378 
     2379        Intersectable::NewMail(); 
     2380 
     2381        for (rit = rays.begin(); rit != rays.end(); ++ rit) 
     2382        { 
     2383                Ray *ray = (*rit)->mRay; 
     2384                 
     2385                if (!ray->intersections.empty()) 
     2386                { 
     2387                        if (!ray->intersections[0].mObject->Mailed()) 
     2388                        { 
     2389                                ray->intersections[0].mObject->Mail(); 
     2390                                ++ pvsSize; 
     2391                        } 
     2392                } 
     2393                if (!ray->sourceObject.mObject->Mailed()) 
     2394                { 
     2395                        ray->sourceObject.mObject->Mail(); 
     2396                        ++ pvsSize; 
     2397                } 
     2398        } 
     2399 
     2400        return pvsSize; 
     2401} 
     2402 
     2403/************************************************************* 
     2404 *            BspNodeGeometry Implementation                 * 
     2405 *************************************************************/ 
     2406 
     2407BspNodeGeometry::BspNodeGeometry(const PolygonContainer &polys,  
     2408                                                                 const vector<Plane3> &planes,  
     2409                                                                 const vector<bool> &sides): 
     2410mPolys(polys), mPlanes(planes), mSides(sides) 
     2411{}                                          
     2412 
     2413BspNodeGeometry::BspNodeGeometry(const vector<Plane3> &planes,  
     2414                                                                 const vector<bool> &sides): 
     2415mPlanes(planes), mSides(sides) 
     2416{} 
     2417 
     2418BspNodeGeometry::~BspNodeGeometry() 
     2419{ 
     2420        CLEAR_CONTAINER(mPolys); 
     2421} 
     2422 
     2423float BspNodeGeometry::GetArea() const  
     2424{  
     2425        return Polygon3::GetArea(mPolys); 
     2426} 
     2427 
     2428BspNodeGeometry *BspNodeGeometry::ConstructChild(const BspTree &tree, 
     2429                                                                                                 const Plane3 &splitPlane, 
     2430                                                                                                 const bool side) const 
     2431{ 
     2432        BspNodeGeometry *childCell = new BspNodeGeometry(mPlanes, mSides); 
     2433 
    20562434        // get cross section of new polygon 
    2057         Polygon3 *planePoly = GetBoundingBox().CrossSection(splitPlane); 
     2435        Polygon3 *planePoly = tree.GetBoundingBox().CrossSection(splitPlane); 
    20582436 
    20592437        // polygon is split by all other planes 
    2060         for (int i = 0; (i < (int)planes.size()) && planePoly; ++ i) 
    2061         { 
    2062                 const int cf = planePoly->ClassifyPlane(*planes[i]); 
     2438        for (int i = 0; (i < (int)mPlanes.size()) && planePoly; ++ i) 
     2439        { 
     2440                const int cf = planePoly->ClassifyPlane(mPlanes[i]); 
    20632441                         
    20642442                // split new polygon with all previous planes 
     
    20722450                                        Polygon3 *backPoly = new Polygon3(); 
    20732451 
    2074                                         planePoly->Split(*planes[i], *frontPoly, *backPoly, splitPts); 
     2452                                        planePoly->Split(mPlanes[i], *frontPoly, *backPoly, splitPts); 
    20752453                                        DEL_PTR(planePoly); 
    20762454 
    2077                                         if(sides[i] == true) 
     2455                                        if(mSides[i] == true) 
    20782456                                        { 
    20792457                                                planePoly = frontPoly; 
     
    20912469                                break; 
    20922470                        case Polygon3::BACK_SIDE: 
    2093                                 if (sides[i])  
     2471                                if (mSides[i])  
    20942472                                        DEL_PTR(planePoly); 
    20952473                                break; 
    20962474                        case Polygon3::FRONT_SIDE: 
    2097                                 if (!sides[i]) 
     2475                                if (!mSides[i]) 
    20982476                                        DEL_PTR(planePoly); 
    20992477                                break; 
     
    21082486        { 
    21092487                //geometry is not changed at all, hence just copy polygons 
    2110                 PolygonContainer::const_iterator it, it_end = cell.end(); 
    2111                  
    2112                 for (it = cell.begin(); it != it_end; ++ it) 
    2113                         childCell.push_back(new Polygon3((*it)->mVertices)); 
    2114  
    2115                 return false; 
     2488                PolygonContainer::const_iterator it, it_end = mPolys.end(); 
     2489                for (it = mPolys.begin(); it != it_end; ++ it) 
     2490                        childCell->mPolys.push_back(new Polygon3((*it)->mVertices)); 
     2491                 
     2492                return childCell; 
    21162493        } 
    21172494 
    21182495        //-- plane poly splits all other cell polygons 
    2119         for (int i = 0; i < (int)cell.size(); ++ i) 
    2120         { 
    2121                 const int cf = cell[i]->ClassifyPlane(splitPlane); 
     2496        for (int i = 0; i < (int)mPolys.size(); ++ i) 
     2497        { 
     2498                const int cf = mPolys[i]->ClassifyPlane(splitPlane); 
    21222499                         
    21232500                // split new polygon with all previous planes 
     
    21262503                        case Polygon3::SPLIT: 
    21272504                                { 
    2128                                         Polygon3 *poly = new Polygon3(cell[i]->mVertices); 
     2505                                        Polygon3 *poly = new Polygon3(mPolys[i]->mVertices); 
    21292506 
    21302507                                        Polygon3 *frontPoly = new Polygon3(); 
     
    21492526                                                DEL_PTR(poly); 
    21502527                                        else 
    2151                                                 childCell.push_back(poly); 
     2528                                                childCell->mPolys.push_back(poly); 
    21522529                                } 
    21532530                                 
     
    21552532                        case Polygon3::BACK_SIDE: 
    21562533                                if (!side)  
    2157                                         childCell.push_back(new Polygon3(cell[i]->mVertices));                   
     2534                                        childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices));                         
    21582535                                break; 
    21592536                        case Polygon3::FRONT_SIDE: 
    21602537                                if (side) 
    2161                                         childCell.push_back(new Polygon3(cell[i]->mVertices));   
     2538                                        childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices));         
    21622539                                break; 
    21632540                        case Polygon3::COINCIDENT: 
    2164                                 childCell.push_back(new Polygon3(cell[i]->mVertices)); 
     2541                                childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices)); 
    21652542                                break; 
    21662543                        default: 
     
    21712548 
    21722549        //-- finally add the new polygon 
    2173         childCell.push_back(planePoly); 
    2174          
    2175         return true; 
    2176 } 
    2177  
    2178  
    2179 void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 
    2180 { 
    2181         stack<BspNode *> tStack; 
    2182  
    2183         vector<Plane3 *> planes; 
    2184         vector<bool> sides; 
    2185  
    2186         ExtractSplitPlanes(n, planes, sides); 
    2187  
    2188         PolygonContainer candidatePolys; 
    2189  
    2190         // bounded planes are added to the polygons 
    2191         for (int i = 0; i < (int)planes.size(); ++ i) 
    2192         { 
    2193                 candidatePolys.push_back(GetBoundingBox().CrossSection(*planes[i])); 
    2194         } 
    2195  
    2196         // add faces of bounding box (also could be faces of the cell) 
    2197         for (int i = 0; i < 6; ++ i) 
    2198         { 
    2199                 VertexContainer vertices; 
    2200          
    2201                 for (int j = 0; j < 4; ++ j) 
    2202                         vertices.push_back(mBox.GetFace(i).mVertices[j]); 
    2203  
    2204                 candidatePolys.push_back(new Polygon3(vertices)); 
    2205         } 
    2206  
    2207         for (int i = 0; i < (int)candidatePolys.size(); ++ i) 
    2208         { 
    2209                 bool inside = true; 
    2210  
    2211                 // polygon is split by all other planes 
    2212                 for (int j = 0; (j < planes.size()) && inside; ++ j) 
    2213                 { 
    2214                         Plane3 *plane = planes[j]; 
    2215  
    2216                         if (i == j) // same plane 
    2217                                 continue; 
    2218  
    2219                         VertexContainer splitPts; 
    2220                         Polygon3 *frontPoly, *backPoly; 
    2221  
    2222                         const int cf = candidatePolys[i]->ClassifyPlane(*plane); 
    2223                          
    2224                         switch (cf) 
    2225                         { 
    2226                                 case Polygon3::SPLIT: 
    2227                                         frontPoly = new Polygon3(); 
    2228                                         backPoly = new Polygon3(); 
    2229  
    2230                                         candidatePolys[i]->Split(*plane, *frontPoly,  
    2231                                                                                          *backPoly, splitPts); 
    2232                                         DEL_PTR(candidatePolys[i]); 
    2233  
    2234                                         if(sides[j] == true) 
    2235                                         { 
    2236                                                 candidatePolys[i] = frontPoly; 
    2237                                                 DEL_PTR(backPoly); 
    2238                                         } 
    2239                                         else 
    2240                                         { 
    2241                                                 candidatePolys[i] = backPoly; 
    2242                                                 DEL_PTR(frontPoly); 
    2243                                         } 
    2244                                          
    2245                                         break; 
    2246  
    2247                                 case Polygon3::BACK_SIDE: 
    2248                                         if (sides[j])  
    2249                                                 inside = false; 
    2250                                         break; 
    2251                                 case Polygon3::FRONT_SIDE: 
    2252                                         if (!sides[j]) 
    2253                                                 inside = false; 
    2254                                         break; 
    2255                                 case Polygon3::COINCIDENT: 
    2256                                         break; 
    2257                                 default: 
    2258                                         break; 
    2259                         } 
    2260                 } 
    2261                  
    2262                 if (inside) 
    2263                         cell.push_back(candidatePolys[i]); 
    2264                 else 
    2265                         DEL_PTR(candidatePolys[i]); 
    2266         } 
    2267 } 
    2268  
    2269 void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const 
    2270 { 
    2271         vector<BspLeaf *> leaves = vc->mBspLeaves; 
    2272  
    2273         vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
    2274  
    2275         for (it = leaves.begin(); it != it_end; ++ it) 
    2276                 ConstructGeometry(*it, cell); 
    2277 } 
    2278  
    2279 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,  
    2280                                                    const bool onlyUnmailed) const 
    2281 { 
    2282         PolygonContainer cell; 
    2283  
    2284         ConstructGeometry(n, cell); 
    2285  
    2286         stack<BspNode *> nodeStack; 
    2287         nodeStack.push(mRoot); 
    2288                  
    2289         // planes needed to verify that we found neighbor leaf. 
    2290         vector<Plane3 *> planes; 
    2291         vector<bool> sides; 
    2292  
    2293         ExtractSplitPlanes(n, planes, sides); 
    2294  
    2295         while (!nodeStack.empty())  
    2296         { 
    2297                 BspNode *node = nodeStack.top(); 
    2298                 nodeStack.pop(); 
    2299  
    2300                 if (node->IsLeaf()) 
    2301                 { 
    2302             if (node != n && (!onlyUnmailed || !node->Mailed())) 
    2303                         { 
    2304                                 // test all planes of current node on neighbour 
    2305                                 PolygonContainer neighborCandidate; 
    2306                                 ConstructGeometry(node, neighborCandidate); 
    2307                                  
    2308                                 bool isAdjacent = true; 
    2309                                 for (int i = 0; (i < planes.size()) && isAdjacent; ++ i) 
    2310                                 { 
    2311                                         const int cf =  
    2312                                                 Polygon3::ClassifyPlane(neighborCandidate, *planes[i]); 
    2313  
    2314                                         if ((cf == Polygon3::BACK_SIDE) && sides[i]) 
    2315                                                 isAdjacent = false; 
    2316                                         else if ((cf == Polygon3::FRONT_SIDE) && !sides[i]) 
    2317                                                 isAdjacent = false; 
    2318                                 } 
    2319  
    2320                                 if (isAdjacent) 
    2321                                         neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 
    2322  
    2323                                 CLEAR_CONTAINER(neighborCandidate); 
    2324                         } 
    2325                 } 
    2326                 else  
    2327                 { 
    2328                         BspInterior *interior = dynamic_cast<BspInterior *>(node); 
    2329          
    2330                         const int cf = Polygon3::ClassifyPlane(cell, interior->mPlane); 
    2331  
    2332                         if (cf == Polygon3::FRONT_SIDE) 
    2333                                 nodeStack.push(interior->mFront); 
    2334                         else 
    2335                                 if (cf == Polygon3::BACK_SIDE) 
    2336                                         nodeStack.push(interior->mBack); 
    2337                                 else  
    2338                                 { 
    2339                                         // random decision 
    2340                                         nodeStack.push(interior->mBack); 
    2341                                         nodeStack.push(interior->mFront); 
    2342                                 } 
    2343                 } 
    2344         } 
    2345          
    2346         CLEAR_CONTAINER(cell); 
    2347         return (int)neighbors.size(); 
    2348 } 
    2349  
    2350 BspLeaf *BspTree::GetRandomLeaf(const Plane3 &halfspace) 
    2351 { 
    2352     stack<BspNode *> nodeStack; 
    2353         nodeStack.push(mRoot); 
    2354          
    2355         int mask = rand(); 
    2356    
    2357         while (!nodeStack.empty())  
    2358         { 
    2359                 BspNode *node = nodeStack.top(); 
    2360                 nodeStack.pop(); 
    2361            
    2362                 if (node->IsLeaf())  
    2363                 { 
    2364                         return dynamic_cast<BspLeaf *>(node); 
    2365                 }  
    2366                 else  
    2367                 { 
    2368                         BspInterior *interior = dynamic_cast<BspInterior *>(node); 
    2369                          
    2370                         BspNode *next; 
    2371          
    2372                         PolygonContainer cell; 
    2373  
    2374                         // todo: not very efficient: constructs full cell everytime 
    2375                         ConstructGeometry(interior, cell); 
    2376  
    2377                         const int cf = Polygon3::ClassifyPlane(cell, halfspace); 
    2378  
    2379                         if (cf == Polygon3::BACK_SIDE) 
    2380                                 next = interior->mFront; 
    2381                         else 
    2382                                 if (cf == Polygon3::FRONT_SIDE) 
    2383                                         next = interior->mFront; 
    2384                         else  
    2385                         { 
    2386                                 // random decision 
    2387                                 if (mask & 1) 
    2388                                         next = interior->mBack; 
    2389                                 else 
    2390                                         next = interior->mFront; 
    2391                                 mask = mask >> 1; 
    2392                         } 
    2393  
    2394                         nodeStack.push(next); 
    2395                 } 
    2396         } 
    2397          
    2398         return NULL; 
    2399 } 
    2400  
    2401 BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 
    2402 { 
    2403         stack<BspNode *> nodeStack; 
    2404          
    2405         nodeStack.push(mRoot); 
    2406  
    2407         int mask = rand(); 
    2408          
    2409         while (!nodeStack.empty())  
    2410         { 
    2411                 BspNode *node = nodeStack.top(); 
    2412                 nodeStack.pop(); 
    2413                  
    2414                 if (node->IsLeaf())  
    2415                 { 
    2416                         if ( (!onlyUnmailed || !node->Mailed()) ) 
    2417                                 return dynamic_cast<BspLeaf *>(node); 
    2418                 } 
    2419                 else  
    2420                 { 
    2421                         BspInterior *interior = dynamic_cast<BspInterior *>(node); 
    2422  
    2423                         // random decision 
    2424                         if (mask & 1) 
    2425                                 nodeStack.push(interior->mBack); 
    2426                         else 
    2427                                 nodeStack.push(interior->mFront); 
    2428  
    2429                         mask = mask >> 1; 
    2430                 } 
    2431         } 
    2432          
    2433         return NULL; 
    2434 } 
    2435  
    2436 int BspTree::ComputePvsSize(const BoundedRayContainer &rays) const 
    2437 { 
    2438         int pvsSize = 0; 
    2439  
    2440         BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 
    2441  
    2442         Intersectable::NewMail(); 
    2443  
    2444         for (rit = rays.begin(); rit != rays.end(); ++ rit) 
    2445         { 
    2446                 Ray *ray = (*rit)->mRay; 
    2447                  
    2448                 if (!ray->intersections.empty()) 
    2449                 { 
    2450                         if (!ray->intersections[0].mObject->Mailed()) 
    2451                         { 
    2452                                 ray->intersections[0].mObject->Mail(); 
    2453                                 ++ pvsSize; 
    2454                         } 
    2455                 } 
    2456                 if (!ray->sourceObject.mObject->Mailed()) 
    2457                 { 
    2458                         ray->sourceObject.mObject->Mail(); 
    2459                         ++ pvsSize; 
    2460                 } 
    2461         } 
    2462  
    2463         return pvsSize; 
    2464 } 
     2550        childCell->mPolys.push_back(planePoly); 
     2551        childCell->mPlanes.push_back(splitPlane); 
     2552        childCell->mSides.push_back(side); 
     2553 
     2554        return childCell; 
     2555} 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h

    r384 r390  
    44#include "Mesh.h" 
    55#include "Containers.h" 
     6#include "Polygon3.h" 
    67#include <stack> 
    78 
     
    1112class BspTree;   
    1213class BspInterior; 
    13 class Polygon3; 
     14//class Polygon3; 
    1415class AxisAlignedBox3; 
    1516class Ray; 
     17 
     18class BspNodeGeometry 
     19{ 
     20public: 
     21        BspNodeGeometry() 
     22        {}; 
     23 
     24        BspNodeGeometry(const PolygonContainer &polys,  
     25                                        const vector<Plane3> &planes,  
     26                                        const vector<bool> &sides); 
     27        BspNodeGeometry(const vector<Plane3> &planes,  
     28                                        const vector<bool> &sides);         
     29 
     30        ~BspNodeGeometry(); 
     31 
     32        float GetArea() const; 
     33         
     34        /** Computes new cell based on the old cell definition and a new split plane 
     35                @param side indicates which side of the halfspace  
     36                @returns true if plane contributes to the cell. 
     37        */ 
     38        BspNodeGeometry *ConstructChild(const BspTree &tree, 
     39                                                                        const Plane3 &splitPlane, 
     40                                                                        const bool side) const; 
     41 
     42        vector<Plane3> mPlanes; 
     43        vector<bool> mSides; 
     44        PolygonContainer mPolys; 
     45}; 
    1646 
    1747/** Data structure used for optimized ray casting. 
     
    176206public: 
    177207        BspNode(); 
    178         virtual ~BspNode(); 
     208        virtual ~BspNode(){}; 
    179209        BspNode(BspInterior *parent); 
    180210 
     
    192222        */ 
    193223        BspInterior *GetParent(); 
     224 
    194225        /** Sets parent node. 
    195226        */ 
    196227        void SetParent(BspInterior *parent); 
    197228 
    198         /** Returns pointer to polygons. 
    199         */ 
    200         PolygonContainer *GetPolygons(); 
    201         /** Stores polygons in node or discards them according to storePolys. 
    202         */ 
    203         void ProcessPolygons(PolygonContainer *polys, const bool storePolys); 
    204  
     229         
    205230        static int mailID; 
    206231        int mailbox; 
     
    210235        bool Mailed() const { return mailbox == mailID; } 
    211236 
    212 //int mViewCellIdx; 
    213237protected: 
    214238 
    215239        /// parent of this node 
    216240        BspInterior *mParent; 
    217  
    218         /// store polygons created during BSP splits 
    219         PolygonContainer *mPolygons; 
    220241}; 
    221242 
     
    247268                @param backPolys returns the polygons in the back of the split plane 
    248269                @param coincident returns the polygons coincident to the split plane 
    249                 @param storePolys if the polygons should be stored in the node 
    250                  
     270 
    251271                @returns the number of splits    
    252272        */ 
     
    254274                                          PolygonContainer &frontPolys,  
    255275                                          PolygonContainer &backPolys,  
    256                                           PolygonContainer &coincident, 
    257                                           const bool storePolys = false); 
    258  
    259         /** Stores polygon in node or discards them according to storePolys. 
    260                 @param polys the polygons 
    261                 @param storePolys if the polygons should be stored or discarded 
    262         */ 
    263         void ProcessPolygon(Polygon3 **poly, const bool storePolys); 
     276                                          PolygonContainer &coincident); 
    264277 
    265278        friend ostream &operator<<(ostream &s, const BspInterior &A) 
     
    337350                /// rays piercing this node 
    338351                BoundedRayContainer *mRays; 
    339  
     352                /// area of current node 
     353                float mArea; 
     354                BspNodeGeometry *mCell; 
     355 
     356                /// pvs size 
     357                int mPvs; 
     358                 
    340359                BspTraversalData(): 
    341360                mNode(NULL), 
     
    343362                mDepth(0), 
    344363                mViewCell(NULL), 
    345                 mRays(NULL) 
     364                mRays(NULL), 
     365                mPvs(0), 
     366                mArea(0.0), 
     367                mCell(NULL) 
    346368                {} 
    347369                 
     
    350372                                                 const int depth,  
    351373                                                 ViewCell *viewCell, 
    352                                                  BoundedRayContainer *rays):  
     374                                                 BoundedRayContainer *rays, 
     375                                                 int pvs, 
     376                                                 float area, 
     377                                                 BspNodeGeometry *cell):  
    353378                mNode(node),  
    354379                mPolygons(polys),  
    355380                mDepth(depth),  
    356381                mViewCell(viewCell), 
    357                 mRays(rays) 
     382                mRays(rays), 
     383                mPvs(pvs), 
     384                mArea(area), 
     385                mCell(cell) 
    358386                {} 
    359387    }; 
     
    445473        void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const; 
    446474 
     475        void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const; 
     476 
    447477        /** Returns random leaf of BSP tree. 
    448478                @param halfspace defines the halfspace from which the leaf is taken. 
     
    454484        */ 
    455485        BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false); 
    456  
    457         /** Computes new cell based on the old cell definition and a new split plane 
    458                 @param side indicates which side of the halfspace  
    459                 @returns true if plane contributes to the cell. 
    460         */ 
    461         bool ConstructChildGeometry(PolygonContainer &childCell, 
    462                                                             const PolygonContainer &cell, 
    463                                                             const vector<Plane3 *> &planes, 
    464                                                             const vector<bool> &sides, 
    465                                                             const Plane3 &splitPlane, 
    466                                                             const bool side) const; 
    467  
    468486 
    469487        /** Returns true if merge criteria are reached. 
     
    530548        */ 
    531549        Plane3 SelectPlane(BspLeaf *leaf,  
    532                                            PolygonContainer &polys, 
    533                                            const BoundedRayContainer &ray); 
     550                                           BspTraversalData &data, 
     551                                           BspTraversalData &frontData, 
     552                                           BspTraversalData &backData); 
    534553 
    535554        /** Evaluates the contribution of the candidate split plane. 
     
    542561        */ 
    543562        float SplitPlaneCost(const Plane3 &candidatePlane, 
    544                                                  const PolygonContainer &polys,                                                   
    545                                                  const BoundedRayContainer &rays, 
    546                                                  const PolygonContainer &cell, 
    547                                                  const vector<Plane3 *> &plane, 
    548                                                  const vector<bool> &sides, 
    549                                                  const int pvsSize) const; 
     563                                                 BspTraversalData &data, 
     564                                                 BspTraversalData &frontData, 
     565                                                 BspTraversalData &backData) const; 
    550566 
    551567        /** Strategies where the effect of the split plane is tested 
     
    557573 
    558574        /** Strategies where the effect of the split plane is tested 
    559             on all input polygons. 
     575            on all input rays. 
    560576 
    561577                @returns the cost of the candidate split plane 
    562578        */ 
    563         float SplitPlaneCost(const Plane3 &candidatePlane, 
     579        float SplitPlaneCost(const Plane3 &candidatePlane,  
    564580                                                 const BoundedRayContainer &rays, 
    565                                                  const float frontArea, 
    566                                                  const float backArea, 
    567                                                  const int pvsSize) const; 
     581                                                 const int pvs, 
     582                                                 const float area, 
     583                                                 const BspNodeGeometry &cell,  
     584                                                 BspTraversalData &frontData, 
     585                                                 BspTraversalData &backData) const; 
    568586 
    569587        /** Filters next view cell down the tree and inserts it into the appropriate leaves 
     
    589607                @returns the root of the subdivision 
    590608        */ 
    591         BspInterior *SubdivideNode(BspLeaf *leaf,  
    592                                                            PolygonContainer &polys, 
    593                                                            PolygonContainer &frontPolys, 
    594                                                            PolygonContainer &backPolys, 
    595                                                            PolygonContainer &coincident, 
    596                                                            BoundedRayContainer &rays, 
    597                                                            BoundedRayContainer &frontRays, 
    598                                                            BoundedRayContainer &backRays); 
     609 
     610        BspInterior *SubdivideNode(BspTraversalData &tData, 
     611                                                           BspTraversalData &frontData, 
     612                                                           BspTraversalData &backData, 
     613                                                           PolygonContainer &coincident); 
    599614 
    600615        /** Filters polygons down the tree. 
     
    614629                @param polygons container of polygons 
    615630                @param rays bundle of rays on which the split can be based 
    616                 @param maxPolyCandidates the maximal number of tested polygon candidates 
    617                 @param maxRayCandidates the maximal number of ray candidates 
    618631        */ 
    619632        Plane3 SelectPlaneHeuristics(BspLeaf *leaf, 
    620                                          PolygonContainer &polys,  
    621                                                                  const BoundedRayContainer &rays, 
    622                                                                  const int maxPolyCandidates, 
    623                                                                  const int maxRayCandidates); 
     633                                                                 BspTraversalData &data, 
     634                                                                 BspTraversalData &frontData, 
     635                                                                 BspTraversalData &backData); 
    624636 
    625637        /** Extracts the meshes of the objects and adds them to polygons.  
     
    663675                @param extractFront if a front view cell is extracted 
    664676        */ 
    665         void ExtractViewCells(ViewCell **backViewCell,  
    666                                                   ViewCell **frontViewCell, 
     677        void ExtractViewCells(BspTraversalData &frontData, 
     678                                                  BspTraversalData &backData,  
    667679                                                  const PolygonContainer &coincident, 
    668                                                   const Plane3 splitPlane,  
    669                                                   const bool extractBack, 
    670                                                   const bool extractFront) const; 
     680                                                  const Plane3 splitPlane) const; 
    671681         
    672682        /** Computes best cost ratio for the suface area heuristics for axis aligned 
     
    723733        /** Extracts the split planes representing the space bounded by node n. 
    724734        */ 
    725         void ExtractSplitPlanes(BspNode *n, vector<Plane3 *> &planes, vector<bool> &sides) const; 
     735        void ExtractSplitPlanes(BspNode *n, vector<Plane3> &planes, vector<bool> &sides) const; 
    726736 
    727737        /** Computes the pvs of the front and back leaf with a given classification. 
    728738        */ 
    729739        void AddToPvs(Intersectable &obj,  
    730                                         float &frontPvs, 
    731                                         float &backPvs, 
    732                                         const int cf,  
    733                                         const int frontId,  
    734                                         const int backId,  
    735                                         const int frontAndBackId) const; 
     740                                  int &frontPvs, 
     741                                  int &backPvs, 
     742                                  const int cf,  
     743                                  const int frontId,  
     744                                  const int backId,  
     745                                  const int frontAndBackId) const; 
    736746         
    737747        int ComputePvsSize(const BoundedRayContainer &rays) const; 
     
    779789        /// maximal possible depth 
    780790        static int sTermMaxDepth; 
     791        /// mininam pvs 
     792        static int sTermMinPvs; 
    781793        /// strategy to get the best split plane 
    782794        static int sSplitPlaneStrategy; 
     
    809821        static float sPvsFactor; 
    810822 
    811         /// if polygons should be stored in the tree 
    812         static bool sStoreSplitPolys; 
    813  
    814823        //-- thresholds used for view cells are merging 
    815824        static int sMinPvsDif; 
  • trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp

    r386 r390  
    547547                SetFilled(); 
    548548 
    549         //ViewCellContainer foundViewCells; 
    550  
    551         if (BspTree::sStoreSplitPolys) 
    552         { 
    553                 while (!tStack.empty())  
    554                 { 
    555             BspNode *node = tStack.top(); 
    556      
    557                         tStack.pop(); 
    558          
    559                         PolygonContainer::const_iterator it; 
    560                         PolygonContainer::const_iterator it_end = node->GetPolygons()->end(); 
    561  
    562                         for (it = node->GetPolygons()->begin(); it != it_end; ++ it) 
    563                                 ExportPolygon(*it); 
    564                          
    565                         if (!node->IsLeaf())  
    566                         { 
    567                                 BspInterior *interior = dynamic_cast<BspInterior *>(node); 
    568        
    569                                 tStack.push(interior->GetFront()); 
    570                                 tStack.push(interior->GetBack()); 
    571  
    572                         } 
    573                 } 
    574         } 
    575549        // export view cells 
    576550        ExportBspViewCellPartition(tree);        
Note: See TracChangeset for help on using the changeset viewer.