Changeset 600


Ignore:
Timestamp:
02/06/06 19:09:53 (18 years ago)
Author:
mattausch
Message:
 
Location:
trunk/VUT/GtpVisibilityPreprocessor
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env

    r598 r600  
    1313#;../data/vienna/vienna-plane.x3d 
    1414#       filename ../data/vienna/viewcells-25-sel.x3d 
    15 #       filename ../data/atlanta/atlanta2.x3d 
     15        filename ../data/atlanta/atlanta2.x3d 
    1616#       filename ../data/soda/soda.dat 
    17         filename ../data/soda/soda5.dat 
     17#       filename ../data/soda/soda5.dat 
    1818} 
    1919 
     
    2525        type vss 
    2626#       type rss 
    27         detectEmptyViewSpace true 
     27        detectEmptyViewSpace false 
    2828} 
    2929 
     
    3636        loadInitialSamples  false 
    3737        storeInitialSamples false 
    38         useViewSpaceBox true 
     38        useViewSpaceBox false 
    3939#       testBeamSampling true 
    4040} 
     
    176176        # samples used for view cell construction 
    177177        Construction { 
    178                 samples 600000 
    179                 samplesPerPass 200000 
     178                samples 2000000 
     179                samplesPerPass 500000 
    180180        } 
    181181 
    182182        #number of active view cells 
    183         active 256 
     183        active 2048 
    184184        maxStaticMemory 40 
    185185 
    186         exportToFile false 
     186        exportToFile true 
    187187        loadFromFile false 
    188188 
    189189        #type kdTree 
    190         type vspKdTree 
     190        #type vspKdTree 
    191191        #type bspTree 
    192192        type vspBspTree 
     
    209209                maxCostRatio 0.1 
    210210                minViewCells 1 
    211                 avgCostMaxDeviation 0.8 
    212                 maxMergesPerPass 500  
     211                avgCostMaxDeviation 0.01 
     212                maxMergesPerPass 500 
    213213                useRaysForMerge false 
    214214                refine false 
    215215                compress false 
    216                 merge false 
     216                merge true 
    217217        } 
    218218 
     
    288288VspBspTree { 
    289289        Construction { 
    290                 samples 300000 
     290                samples 1000000 
    291291                epsilon 0.005 
    292292                randomize false 
     
    301301        # pvs                  = 1024 
    302302         
    303         splitPlaneStrategy 1024 
     303        splitPlaneStrategy 1026 
    304304         
    305305        # maximal candidates for split planes 
    306         maxPolyCandidates 0 
     306        maxPolyCandidates 200 
    307307 
    308308         
     
    322322        Termination { 
    323323                # parameters used for autopartition 
    324                 minRays                 -150 
     324                minRays                 500 
    325325                minPolygons             -1 
    326                 maxDepth                30 
    327                 minPvs                  -10 
    328                 #minProbability         0.0001 
    329                 minProbability          -1 
    330 #               maxRayContribution      0.3 
    331                 maxRayContribution      2.3 
    332 #               maxCostRatio            0.9 
    333                 maxCostRatio            3.9 
     326                maxDepth                25 
     327                minPvs                  -1 
     328                minProbability          0.0000001 
     329                maxRayContribution      0.3 
     330                maxCostRatio            0.9 
    334331                missTolerance           3 
    335  
    336                  
    337                 maxViewCells            512 
     332                 
     333                maxViewCells            30000 
    338334                 
    339335                # used for pvs criterium 
     
    341337                 
    342338                AxisAligned { 
    343                         minRays                 1 
     339                        minRays                 20000 
    344340                        maxRayContribution      9.9 
    345341                } 
    346342        } 
    347343         
    348         splitUseOnlyDrivingAxis true 
     344        splitUseOnlyDrivingAxis false 
    349345         
    350346        Visualization { 
    351347                # x3d visualization of the split planes 
    352                 exportSplits true 
     348                exportSplits false 
    353349        } 
    354350} 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp

    r590 r600  
    2222        bool operator() (T v1, T v2) const 
    2323        { 
    24                 return (v1->GetTimeStamp() < v2->GetTimeStamp()); 
     24                return (v1->GetMergeCost() < v2->GetMergeCost()); 
    2525        } 
    2626}; 
     
    107107mValid(true), 
    108108mParent(NULL), 
    109 mTimeStamp(0), 
     109mMergeCost(0), 
    110110mIsActive(false) 
    111111{ 
     
    119119mValid(true), 
    120120mParent(NULL), 
    121 mTimeStamp(0), 
     121mMergeCost(0), 
    122122mIsActive(false) 
    123123{ 
     
    230230 
    231231 
    232 void ViewCell::SetTimeStamp(const int timeStamp) 
    233 { 
    234         mTimeStamp = timeStamp; 
    235 } 
    236  
    237  
    238 int ViewCell::GetTimeStamp() const 
    239 { 
    240         return mTimeStamp; 
     232void ViewCell::SetMergeCost(const float mergeCost) 
     233{ 
     234        mMergeCost = mergeCost; 
     235} 
     236 
     237 
     238float ViewCell::GetMergeCost() const 
     239{ 
     240        return mMergeCost; 
    241241} 
    242242 
     
    445445        float variance = 0; 
    446446        int totalPvs = 0; 
    447         float totalCost = 0; 
     447        float totalRenderCost = 0; 
    448448 
    449449        //-- compute statistics values of initial view cells 
    450         mViewCellsManager->EvaluateRenderStatistics(totalCost, 
     450        mViewCellsManager->EvaluateRenderStatistics(totalRenderCost, 
    451451                                                                                                mExpectedCost, 
    452452                                                                                                mDeviation, 
     
    471471        Debug << "deviation: " << mDeviation << endl; 
    472472        Debug << "avg render cost: " << mAvgRenderCost << endl; 
    473         Debug << "expected cost: " <<mExpectedCost << endl; 
     473        Debug << "expected cost: " << mExpectedCost << endl; 
    474474 
    475475 
     
    498498 
    499499        // frequency stats are updated 
    500         const int statsOut = 100; 
     500        const int statsOut = 1; 
    501501 
    502502        // passes are needed for statistics, because we don't want to record 
     
    521521 
    522522        //-- use priority queue to merge leaf pairs 
    523  
    524         while (!mMergeQueue.empty())// && (realNumActiveViewCells > mMergeMinViewCells)) 
     523// HACK 
     524        //const float maxAvgCost = 350; 
     525        while (!mMergeQueue.empty())//NumActiveViewCells > mMergeMinViewCells)) 
    525526        { 
    526527                //-- reset merge queue if the ratio of current expected cost / real expected cost 
     
    588589                { 
    589590                        ViewCell::NewMail(); 
    590                                                  
     591 
     592                        //-- update statistical values 
    591593                        -- realNumActiveViewCells; 
    592594                        ++ mergeStats.merged; 
    593595                        ++ mergedPerPass; 
    594596 
    595  
    596                         //-- update statistical values 
     597                        const float renderCostIncr = mc.GetRenderCost(); 
     598                        const float mergeCostIncr = mc.GetMergeCost(); 
     599 
     600                        totalRenderCost += renderCostIncr; 
     601                        mDeviation += mc.GetDeviationIncr(); 
     602                         
     603                         
     604                        // merge the view cells of leaf1 and leaf2 
     605                        int pvsDiff; 
     606                        ViewCellInterior *mergedVc =  
     607                                MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff); 
     608 
    597609 
    598610                        // total render cost and deviation has changed 
     
    600612                        // cost heuristics, but cannot recompute costs on each increase of the  
    601613                        // expected cost 
    602  
    603                         totalCost += mc.GetRenderCost(); 
    604                         mDeviation += mc.GetDeviationIncr(); 
    605                                                  
    606                         realExpectedCost = totalCost / (float)realNumActiveViewCells; 
    607                          
    608                         const float currentMergeCost = mc.GetMergeCost(); 
    609  
    610                         // merge the view cells of leaf1 and leaf2 
    611                         int pvsDiff; 
    612                         ViewCellInterior *mergedVc =  
    613                                 MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff); 
    614  
    615614                        totalPvs += pvsDiff; 
    616  
    617                         // set timestamp 
    618                         mergedVc->SetTimeStamp(mergeStats.merged); 
    619  
     615                        realExpectedCost = totalRenderCost / (float)realNumActiveViewCells; 
    620616                        realAvgRenderCost = (float)totalPvs / (float)realNumActiveViewCells; 
     617         
     618                        // set merge cost to this node 
     619                        mergedVc->SetMergeCost(totalRenderCost); 
     620 
    621621#if VC_HISTORY 
    622622                        if (mc.mLeftViewCell->IsSibling(mc.mRightViewCell)) 
     
    632632                                        << "#Merged\n" << mergeStats.merged << endl  
    633633                                        << "#Viewcells\n" << realNumActiveViewCells << endl  
    634                                         << "#CurrentCost\n" << currentMergeCost << endl 
    635                                         << "#RelativeCost\n" << currentMergeCost / mOverallCost << endl 
    636                                         << "#CurrentPvs\n" << mc.GetLeftViewCell()->GetPvs().GetSize() << endl 
    637                                         << "#MergedSiblings\n" << mergeStats.siblings << endl 
    638                                         << "#AvgTreeDist\n" << mergeStats.AvgTreeDist() << endl 
    639                                         << "#UsedExpectedCost\n" << mExpectedCost << endl 
    640                                         << "#RealExpectedCost\n" << realExpectedCost << endl 
    641                                         << "#RealAvgRenderCost\n" << realAvgRenderCost << endl 
    642                                         << "#AvgRenderCost\n" << mAvgRenderCost << endl 
    643                                         << "#expectedCostRatio\n" << mExpectedCost / realExpectedCost << endl 
    644                                         << "#Deviation\n" << mDeviation / (float)realNumActiveViewCells << endl 
    645                                         << "#TotalDeviation\n" << mDeviation<< endl; 
     634                                        << "#RenderCostIncrease\n" << renderCostIncr << endl 
     635                                        << "#TotalRenderCost\n" << totalRenderCost << endl 
     636                                        << "#CurrentPvs\n" << mergedVc->GetPvs().GetSize() << endl 
     637                                        << "#ExpectedCost\n" << realExpectedCost << endl 
     638                                        << "#AvgRenderCost\n" << realAvgRenderCost << endl 
     639                                        << "#Deviation\n" << mDeviation << endl 
     640                                        << "#TotalPvs\n" << totalPvs << endl 
     641                                        << "#PvsSizeDecrease\n" << -pvsDiff << endl; 
    646642                        } 
    647643                } 
     
    682678                }*/ 
    683679                ViewCellInterior *root = mViewCellsManager->MergeViewCells(activeViewCells); 
    684  
    685                 root->SetTimeStamp(mergeStats.merged + 1); 
     680                root->SetMergeCost(totalRenderCost); 
    686681                mRoot = root; 
    687682        } 
     
    692687        } 
    693688 
     689 
     690        while (!mMergeQueue.empty()) 
     691        { 
     692                mMergeQueue.pop(); 
     693        } 
     694         
     695         
    694696        // TODO delete because makes no sense here 
    695697        mergeStats.expectedRenderCost = realExpectedCost; 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h

    r590 r600  
    169169 
    170170 
    171         void SetTimeStamp(const int timeStamp); 
    172         int GetTimeStamp() const; 
     171        void SetMergeCost(const float mergeCost); 
     172        float GetMergeCost() const; 
    173173        static void NewMail(const int reserve = 1) { 
    174174                sMailId += sReservedMailboxes; 
     
    201201        float mArea; 
    202202 
    203         int mTimeStamp; 
     203        float mMergeCost; 
    204204 
    205205        bool mValid; 
     
    265265class ViewCellsTree 
    266266{ 
     267        friend class ViewCellsManager; 
    267268public: 
    268269        ViewCellsTree(ViewCellsManager *vcm); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp

    r590 r600  
    414414                << maxCostNodes * 100 / (double)Leaves() << endl; 
    415415 
    416         app << "#N_PMINPROBABILITYAREALEAVES  ( Percentage of leaves with mininum probability )\n" 
     416        app << "#N_PMINPROBABILITYLEAVES  ( Percentage of leaves with mininum probability )\n" 
    417417                << minProbabilityNodes * 100 / (double)Leaves() << endl; 
    418418 
     
    864864} 
    865865 
     866 
    866867bool BspTree::TerminationCriteriaMet(const BspTraversalData &data) const 
    867868{ 
     
    875876                 (data.GetAvgRayContribution() > mTermMaxRayContribution)); 
    876877} 
     878 
    877879 
    878880BspNode *BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData) 
     
    19861988 
    19871989        Intersectable::NewMail(); 
     1990        ViewCell::NewMail(); 
    19881991 
    19891992        Vector3 entp = origin; 
     
    22292232{ 
    22302233        ViewCellContainer leaves; 
    2231         mViewCellsManager->GetViewCellsTree()->CollectLeaves(vc, leaves); 
     2234        mViewCellsTree->CollectLeaves(vc, leaves); 
    22322235 
    22332236        ViewCellContainer::const_iterator it, it_end = leaves.end(); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp

    r598 r600  
    5858         
    5959         
    60         environment->GetIntValue("ViewCells.active", mNumMergedViewCells); 
     60        environment->GetIntValue("ViewCells.active", mNumActiveViewCells); 
    6161        environment->GetBoolValue("ViewCells.PostProcess.compress", mCompressViewCells); 
    6262        environment->GetBoolValue("ViewCells.Visualization.useCuttingPlane", mUseCuttingPlaneForViz); 
     
    178178                                                Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION; 
    179179 
     180                if (0) 
    180181                dirSamples = !dirSamples; // toggle sampling method 
    181182                numSamples += CastPassSamples(mSamplesPerPass,  
     
    692693        int axis = 0; 
    693694 
    694         const float factor = 0.55; 
     695        const float factor = 0.35; 
    695696        Vector3 point = mViewSpaceBox.Min() +  mViewSpaceBox.Size() * factor; 
    696697 
     
    10321033                if (exporter) 
    10331034                { 
     1035                         
     1036                        if (0 && mExportRays) 
     1037                                exporter->ExportRays(rays, RgbColor(1, 1, 1)); 
     1038 
     1039                         
     1040                        if (mExportGeometry) 
     1041                                exporter->ExportGeometry(objects); 
     1042 
    10341043                        //exporter->SetWireframe(); 
    10351044                        exporter->SetFilled(); 
    10361045                        ExportViewCellsForViz(exporter); 
    10371046 
    1038                         if (0 && mExportRays) 
    1039                                 exporter->ExportRays(rays, RgbColor(1, 1, 1)); 
    1040  
    1041                         if (mExportGeometry) 
    1042                                 exporter->ExportGeometry(objects); 
    10431047 
    10441048                        delete exporter; 
     
    10631067                // we can use the view cells tree hierarchy to get the right set 
    10641068                mViewCellsTree->CollectBestViewCellSet(mViewCells,  
    1065                                                                                            mNumMergedViewCells); 
     1069                                                                                           mNumActiveViewCells); 
    10661070        } 
    10671071} 
     
    11131117 
    11141118        //-- post processing of bsp view cells 
     1119 
    11151120    int vcSize = 0; 
    11161121        int pvsSize = 0; 
     
    11241129 
    11251130    Debug << ss << endl; 
    1126  
    1127         if (1) // export view cells 
    1128         { 
    1129                 cout << "exporting initial view cells (=leaves) ... "; 
    1130                 Exporter *exporter = Exporter::GetExporter("view_cells.x3d"); 
    1131  
    1132                 if (exporter) 
    1133                 { 
    1134                         //exporter->SetWireframe(); 
    1135                         exporter->SetFilled(); 
    1136                         ExportViewCellsForViz(exporter); 
    1137  
    1138                         if (mExportGeometry) 
    1139                         { 
    1140                                 Material m; 
    1141                                 m.mDiffuseColor = RgbColor(0, 1, 0); 
    1142                                 exporter->SetForcedMaterial(m); 
    1143                          
    1144                                 exporter->SetWireframe(); 
    1145  
    1146                                 exporter->ExportGeometry(objects); 
    1147                         } 
    1148  
    1149                         delete exporter; 
    1150                 } 
    1151                 cout << "finished" << endl; 
    1152         } 
    11531131 
    11541132         
     
    11771155        } 
    11781156 
    1179         // reset view cells and stats 
     1157    // reset view cells and stats 
    11801158        ResetViewCells(); 
     1159 
     1160        int savedColorCode  = mColorCode; 
     1161 
     1162        //BspLeaf::NewMail(); 
     1163        if (1) // export merged view cells 
     1164        { 
     1165                mColorCode = 0; 
     1166                cout << "reseting view cells ... "; 
     1167                ResetViewCells(); 
     1168                cout << "finished" << endl; 
     1169 
     1170                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 
     1171                Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 
     1172 
     1173                cout << "exporting view cells after merge ... "; 
     1174 
     1175                if (exporter) 
     1176                { 
     1177                        if (mExportGeometry) 
     1178                                exporter->ExportGeometry(objects); 
     1179 
     1180                        //exporter->SetWireframe(); 
     1181                        exporter->SetFilled(); 
     1182                        ExportViewCellsForViz(exporter); 
     1183 
     1184 
     1185                        delete exporter; 
     1186                } 
     1187                cout << "finished" << endl; 
     1188        } 
     1189 
     1190        if (1) // export merged view cells 
     1191        { 
     1192                mColorCode = 1; 
     1193 
     1194                Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d"); 
     1195         
     1196                cout << "exporting view cells after merge (pvs size) ... ";      
     1197 
     1198                if (exporter) 
     1199                { 
     1200                        //exporter->SetWireframe(); 
     1201                         
     1202                        if (mExportGeometry) 
     1203                                exporter->ExportGeometry(objects); 
     1204 
     1205                        //exporter->SetWireframe(); 
     1206                        exporter->SetFilled(); 
     1207                        ExportViewCellsForViz(exporter); 
     1208 
     1209                        delete exporter; 
     1210                } 
     1211                cout << "finished" << endl; 
     1212        } 
     1213 
     1214        mColorCode = savedColorCode; 
     1215 
    11811216        FinalizeViewCells(true); 
    11821217         
    1183         // HACK: removes view cells in bsp leaves with active ones 
    1184         if (0) 
    1185                 AddCurrentViewCellsToHierarchy(); 
    1186  
    11871218        // write view cells to disc 
    11881219        if (mExportViewCells) 
     
    12161247                return; 
    12171248         
    1218         //BspLeaf::NewMail(); 
    1219         if (1) // export merged view cells 
    1220         { 
    1221  
    1222                 cout << "reseting view cells ... "; 
    1223                 ResetViewCells(); 
    1224  
     1249        int savedColorCode = mColorCode; 
     1250 
     1251         
     1252         
     1253        if (1) // export final view cells 
     1254        { 
     1255                mColorCode = 1; 
     1256 
     1257                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 
     1258         
     1259                cout << "exporting view cells after merge (pvs size) ... ";      
     1260 
     1261                if (exporter) 
     1262                { 
     1263                        //exporter->SetWireframe(); 
     1264                         
     1265                        if (mExportGeometry) 
     1266                                exporter->ExportGeometry(objects); 
     1267 
     1268                        //exporter->SetWireframe(); 
     1269                        exporter->SetFilled(); 
     1270                        ExportViewCellsForViz(exporter); 
     1271 
     1272                        delete exporter; 
     1273                } 
    12251274                cout << "finished" << endl; 
    1226  
    1227                 Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 
    1228                 Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 
    1229  
    1230                 cout << "exporting view cells after merge ... "; 
    1231  
    1232                 if (exporter) 
    1233                 { 
    1234                         if (0) 
    1235                                 exporter->SetWireframe(); 
    1236                         else 
    1237                                 exporter->SetFilled(); 
    1238  
    1239                         ExportViewCellsForViz(exporter); 
    1240  
    1241                         if (mExportGeometry) 
    1242                         { 
    1243                                 Material m; 
    1244                                 m.mDiffuseColor = RgbColor(0, 1, 0); 
    1245                                 exporter->SetForcedMaterial(m); 
    1246                                 exporter->SetFilled(); 
    1247  
    1248                                 exporter->ExportGeometry(objects); 
    1249                         } 
    1250  
    1251                         delete exporter; 
    1252                 } 
    1253                 cout << "finished" << endl; 
    1254         } 
     1275        } 
     1276 
     1277        mColorCode = savedColorCode; 
    12551278 
    12561279        //-- visualization of the BSP splits 
     
    12651288        } 
    12661289 
     1290        // export single view cells 
    12671291        ExportBspPvs(objects); 
    12681292} 
     
    14061430                                                                          ViewCell *vc) const 
    14071431{ 
    1408                 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 
     1432        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 
     1433 
     1434        float importance = 0; 
     1435        static Material m; 
     1436 
     1437        switch (mColorCode) 
     1438        { 
     1439        case 0: // Random 
     1440                { 
     1441                        if (vcValid) 
     1442                        { 
     1443                                m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f); 
     1444                                m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f); 
     1445                                m.mDiffuseColor.b = 0.5f + RandomValue(0.0f, 0.5f); 
     1446                        } 
     1447                        else 
     1448                        { 
     1449                                m.mDiffuseColor.r = 0.0f; 
     1450                                m.mDiffuseColor.g = 1.0f; 
     1451                                m.mDiffuseColor.b = 0.0f; 
     1452                        } 
     1453 
     1454                        exporter->SetForcedMaterial(m); 
     1455                        return; 
     1456                } 
     1457                 
     1458        case 1: // pvs 
     1459                { 
     1460                        importance = (float)vc->GetPvs().GetSize() / 
     1461                                (float)mViewCellsStats.maxPvs; 
     1462 
     1463                } 
     1464                break; 
     1465        case 2: // merges 
     1466                { 
     1467            int lSize = mViewCellsTree->GetSize(vc); 
     1468                        importance = (float)lSize / (float)mViewCellsStats.maxLeaves; 
     1469                } 
     1470                //break; 
     1471        case 3: // merge tree differene 
     1472                { 
     1473                        // TODO 
     1474                        //importance = (float)GetMaxTreeDiff(vc) / 
     1475                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2); 
     1476 
     1477                } 
     1478                break; 
     1479        default: 
     1480                break; 
     1481        } 
     1482 
     1483        // special color code for invalid view cells 
     1484        m.mDiffuseColor.r = importance; 
     1485        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 
     1486        m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f; 
     1487 
     1488        //Debug << "importance: " << importance << endl; 
     1489        exporter->SetForcedMaterial(m); 
     1490} 
     1491 
     1492 
     1493void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
     1494                                                                                                 ViewCell *vc, 
     1495                                                                                                 const Plane3 *cuttingPlane) const 
     1496{ 
     1497        if (vc->GetMesh()) 
     1498        { 
     1499                exporter->ExportMesh(vc->GetMesh()); 
     1500                return; 
     1501        } 
     1502 
     1503        BspNodeGeometry geom; 
     1504        mBspTree->ConstructGeometry(vc, geom); 
     1505 
     1506 
     1507        if (cuttingPlane) 
     1508        { 
     1509                BspNodeGeometry front; 
     1510                BspNodeGeometry back; 
     1511 
     1512                geom.SplitGeometry(front, 
     1513                                                   back, 
     1514                                                   *cuttingPlane, 
     1515                                                   mViewSpaceBox,  
     1516                                                   0.0001f); 
     1517 
     1518                if ((int)back.mPolys.size() >= 3) 
     1519                        exporter->ExportPolygons(back.mPolys); 
     1520        } 
     1521        else 
     1522        { 
     1523                 
     1524                exporter->ExportPolygons(geom.mPolys); 
     1525        } 
     1526} 
     1527 
     1528 
     1529void BspViewCellsManager::CreateMesh(ViewCell *vc) 
     1530{ 
     1531        if (vc->GetMesh()) 
     1532                delete vc->GetMesh(); 
     1533 
     1534        BspNodeGeometry geom; 
     1535         
     1536        mBspTree->ConstructGeometry(vc, geom); 
     1537 
     1538        Mesh *mesh = new Mesh(); 
     1539        geom.AddToMesh(*mesh); 
     1540        vc->SetMesh(mesh); 
     1541        mMeshContainer.push_back(mesh); 
     1542} 
     1543 
     1544 
     1545void BspViewCellsManager::Finalize(ViewCell *viewCell,  
     1546                                                                   const bool createMesh) 
     1547{ 
     1548        CreateMesh(viewCell); 
     1549 
     1550        float area = 0; 
     1551        float volume = 0; 
     1552 
     1553        ViewCellContainer leaves; 
     1554        mViewCellsTree->CollectLeaves(viewCell, leaves); 
     1555 
     1556        ViewCellContainer::const_iterator it, it_end = leaves.end(); 
     1557 
     1558        for (it = leaves.begin(); it != it_end; ++ it) 
     1559        { 
     1560                BspNodeGeometry geom; 
     1561                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 
     1562                mBspTree->ConstructGeometry(leaf, geom); 
     1563 
     1564                area += geom.GetArea(); 
     1565                volume += geom.GetVolume(); 
     1566        } 
     1567 
     1568        viewCell->SetVolume(volume); 
     1569        viewCell->SetArea(area); 
     1570} 
     1571 
     1572 
     1573ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point) const 
     1574{ 
     1575        if (!mBspTree) 
     1576                return NULL; 
     1577 
     1578        if (!mViewSpaceBox.IsInside(point)) 
     1579                return NULL; 
     1580         
     1581        return mBspTree->GetViewCell(point); 
     1582} 
     1583 
     1584 
     1585void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
     1586                                                                                                 vector<MergeCandidate> &candidates) 
     1587{ 
     1588        cout << "collecting merge candidates ... " << endl; 
     1589 
     1590        if (mUseRaysForMerge) 
     1591        { 
     1592                mBspTree->CollectMergeCandidates(rays, candidates); 
     1593        } 
     1594        else 
     1595        { 
     1596                vector<BspLeaf *> leaves; 
     1597                mBspTree->CollectLeaves(leaves); 
     1598                mBspTree->CollectMergeCandidates(leaves, candidates); 
     1599        } 
     1600 
     1601        cout << "fininshed collecting candidates" << endl; 
     1602} 
     1603 
     1604 
     1605 
     1606bool BspViewCellsManager::ExportViewCells(const string filename) 
     1607{ 
     1608        cout << "exporting view cells to xml ... "; 
     1609        std::ofstream stream; 
     1610 
     1611        // for output we need unique ids for each view cell 
     1612        CreateUniqueViewCellIds(); 
     1613 
     1614 
     1615        stream.open(filename.c_str()); 
     1616        stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl; 
     1617        stream << "<Visibility_Solution>" << endl; 
     1618 
     1619        //-- the view space bounding box 
     1620        stream << "<ViewSpaceBox"  
     1621                   << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\"" 
     1622                   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl; 
     1623 
     1624        //-- the type of the view cells hierarchy 
     1625        //stream << "<Hierarchy name=\"bspTree\" />" << endl; 
     1626        stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free 
     1627        //-- load the view cells itself, i.e., the ids and the pvs 
     1628        stream << "<ViewCells>" << endl; 
     1629        ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 
     1630        for (it = mViewCells.begin(); it != it_end; ++ it) 
     1631                ExportViewCell(*it, stream); 
     1632 
     1633        stream << "</ViewCells>" << endl; 
     1634 
     1635        //-- load the hierarchy 
     1636        stream << "<Hierarchy>" << endl; 
     1637        mBspTree->Export(stream); 
     1638        stream << endl << "</Hierarchy>" << endl; 
     1639 
     1640        stream << "</Visibility_Solution>" << endl; 
     1641        stream.close(); 
     1642 
     1643        cout << "finished" << endl; 
     1644 
     1645        return true; 
     1646} 
     1647 
     1648 
     1649void BspViewCellsManager::AddCurrentViewCellsToHierarchy() 
     1650{ 
     1651        ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 
     1652        for (it = mViewCells.begin(); it != it_end; ++ it) 
     1653        { 
     1654                ViewCell *vc = *it; 
     1655                ViewCellContainer leaves; 
     1656                mViewCellsTree->CollectLeaves(vc, leaves); 
     1657                 
     1658                ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
     1659 
     1660                for (lit = leaves.begin(); lit != lit_end; ++ lit) 
     1661                { 
     1662                        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit); 
     1663                        bspVc->mLeaf->SetViewCell(vc); 
     1664                } 
     1665        } 
     1666} 
     1667 
     1668/************************************************************************/ 
     1669/*                   KdViewCellsManager implementation                  */ 
     1670/************************************************************************/ 
     1671 
     1672 
     1673 
     1674KdViewCellsManager::KdViewCellsManager(KdTree *kdTree): 
     1675ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100) 
     1676{ 
     1677} 
     1678 
     1679float KdViewCellsManager::GetProbability(ViewCell *viewCell) 
     1680{ 
     1681        // compute view cell area / volume as subsititute for probability 
     1682#if 0 
     1683        return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 
     1684#endif 
     1685#if 1 
     1686        return GetArea(viewCell) / GetAccVcArea(); 
     1687#endif 
     1688#if 0 
     1689        return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 
     1690#endif 
     1691} 
     1692 
     1693 
     1694float KdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const 
     1695{ 
     1696        return viewCell->GetPvs().GetSize() * objRendercost; 
     1697} 
     1698 
     1699 
     1700void KdViewCellsManager::CollectViewCells() 
     1701{ 
     1702        //mKdTree->CollectViewCells(mViewCells); TODO 
     1703} 
     1704 
     1705 
     1706int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 
     1707                                                                  const VssRayContainer &rays) 
     1708{ 
     1709        // if view cells already constructed 
     1710        if (ViewCellsConstructed()) 
     1711                return 0; 
     1712 
     1713        mKdTree->Construct(); 
     1714 
     1715        mTotalAreaValid = false; 
     1716        // create the view cells 
     1717        mKdTree->CreateAndCollectViewCells(mViewCells); 
     1718 
     1719        // cast rays 
     1720        ComputeSampleContributions(rays, true, false); 
     1721 
     1722        EvaluateViewCellsStats(); 
     1723        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 
     1724 
     1725        return 0; 
     1726} 
     1727 
     1728 
     1729bool KdViewCellsManager::ViewCellsConstructed() const 
     1730{ 
     1731        return mKdTree->GetRoot() != NULL; 
     1732} 
     1733 
     1734int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 
     1735                                                                        const VssRayContainer &rays) 
     1736{ 
     1737        return 0; 
     1738} 
     1739 
     1740void KdViewCellsManager::Visualize(const ObjectContainer &objects, 
     1741                                                                   const VssRayContainer &sampleRays) 
     1742{ 
     1743        if (!ViewCellsConstructed()) 
     1744                return; 
     1745 
     1746        // using view cells instead of the kd PVS of objects 
     1747        const bool useViewCells = true; 
     1748        bool exportRays = false; 
     1749 
     1750        int limit = min(mVisualizationSamples, (int)sampleRays.size()); 
     1751        const int pvsOut = min((int)objects.size(), 10); 
     1752        VssRayContainer *rays = new VssRayContainer[pvsOut]; 
     1753 
     1754        if (useViewCells) 
     1755        { 
     1756                const int leafOut = 10; 
     1757 
     1758                ViewCell::NewMail(); 
     1759 
     1760                //-- some rays for output 
     1761                const int raysOut = min((int)sampleRays.size(), mVisualizationSamples); 
     1762                Debug << "visualization using " << raysOut << " samples" << endl; 
     1763 
     1764                //-- some random view cells and rays for output 
     1765                vector<KdLeaf *> kdLeaves; 
     1766 
     1767                for (int i = 0; i < leafOut; ++ i) 
     1768                        kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf())); 
     1769 
     1770                for (int i = 0; i < kdLeaves.size(); ++ i) 
     1771                { 
     1772                        KdLeaf *leaf = kdLeaves[i]; 
     1773                        RayContainer vcRays; 
     1774 
     1775                        cout << "creating output for view cell " << i << " ... "; 
     1776#if 0 
     1777                        // check whether we can add the current ray to the output rays 
     1778                        for (int k = 0; k < raysOut; ++ k) 
     1779                        { 
     1780                                Ray *ray = sampleRays[k]; 
     1781 
     1782                                for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 
     1783                                { 
     1784                                        BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf; 
     1785 
     1786                                        if (leaf->GetViewCell() == leaf2->GetViewCell()) 
     1787                                        { 
     1788                                                vcRays.push_back(ray); 
     1789                                        } 
     1790                                } 
     1791                        } 
     1792#endif 
     1793                        Intersectable::NewMail(); 
     1794 
     1795                        ViewCell *vc = leaf->mViewCell; 
     1796 
     1797                        //bspLeaves[j]->Mail(); 
     1798                        char s[64]; sprintf(s, "kd-pvs%04d.x3d", i); 
     1799 
     1800                        Exporter *exporter = Exporter::GetExporter(s); 
     1801                        exporter->SetFilled(); 
     1802 
     1803                        exporter->SetWireframe(); 
     1804                        //exporter->SetFilled(); 
     1805 
     1806                        Material m;//= RandomMaterial(); 
     1807                        m.mDiffuseColor = RgbColor(1, 1, 0); 
     1808                        exporter->SetForcedMaterial(m); 
     1809 
     1810                        AxisAlignedBox3 box = mKdTree->GetBox(leaf); 
     1811                        exporter->ExportBox(box); 
     1812 
     1813                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
     1814                                << ", piercing rays=" << (int)vcRays.size() << endl; 
     1815 
     1816                        // export rays piercing this view cell 
     1817                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0)); 
     1818 
     1819                        m.mDiffuseColor = RgbColor(1, 0, 0); 
     1820                        exporter->SetForcedMaterial(m); 
     1821 
     1822                        // exporter->SetWireframe(); 
     1823                        exporter->SetFilled(); 
     1824 
     1825                        ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end(); 
     1826                        // output PVS of view cell 
     1827                        for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it) 
     1828                        { 
     1829                                Intersectable *intersect = (*it).first; 
     1830                                if (!intersect->Mailed()) 
     1831                                { 
     1832                                        exporter->ExportIntersectable(intersect); 
     1833                                        intersect->Mail(); 
     1834                                } 
     1835                        } 
     1836 
     1837                        DEL_PTR(exporter); 
     1838                        cout << "finished" << endl; 
     1839                } 
     1840 
     1841                DEL_PTR(rays); 
     1842        } 
     1843        else // using kd PVS of objects 
     1844        { 
     1845                for (int i = 0; i < limit; ++ i) 
     1846                { 
     1847                        VssRay *ray = sampleRays[i]; 
     1848 
     1849                        // check whether we can add this to the rays 
     1850                        for (int j = 0; j < pvsOut; j++) 
     1851                        { 
     1852                                if (objects[j] == ray->mTerminationObject) 
     1853                                { 
     1854                                        rays[j].push_back(ray); 
     1855                                } 
     1856                        } 
     1857                } 
     1858 
     1859                if (exportRays) 
     1860                { 
     1861                        Exporter *exporter = NULL; 
     1862                        exporter = Exporter::GetExporter("sample-rays.x3d"); 
     1863                        exporter->SetWireframe(); 
     1864                        exporter->ExportKdTree(*mKdTree); 
     1865 
     1866                        for (i=0; i < pvsOut; i++) 
     1867                                exporter->ExportRays(rays[i], RgbColor(1, 0, 0)); 
     1868 
     1869                        exporter->SetFilled(); 
     1870 
     1871                        delete exporter; 
     1872                } 
     1873 
     1874                for (int k=0; k < pvsOut; k++) 
     1875                { 
     1876                        Intersectable *object = objects[k]; 
     1877                        char s[64]; 
     1878                        sprintf(s, "sample-pvs%04d.x3d", k); 
     1879 
     1880                        Exporter *exporter = Exporter::GetExporter(s); 
     1881                        exporter->SetWireframe(); 
     1882 
     1883                        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); 
     1884                        Intersectable::NewMail(); 
     1885 
     1886                        // avoid adding the object to the list 
     1887                        object->Mail(); 
     1888                        ObjectContainer visibleObjects; 
     1889 
     1890                        for (; i != object->mKdPvs.mEntries.end(); i++) 
     1891                        { 
     1892                                KdNode *node = (*i).first; 
     1893                                exporter->ExportBox(mKdTree->GetBox(node)); 
     1894 
     1895                                mKdTree->CollectObjects(node, visibleObjects); 
     1896                        } 
     1897 
     1898                        exporter->ExportRays(rays[k],  RgbColor(0, 1, 0)); 
     1899                        exporter->SetFilled(); 
     1900 
     1901                        for (int j = 0; j < visibleObjects.size(); j++) 
     1902                                exporter->ExportIntersectable(visibleObjects[j]); 
     1903 
     1904                        Material m; 
     1905                        m.mDiffuseColor = RgbColor(1, 0, 0); 
     1906                        exporter->SetForcedMaterial(m); 
     1907                        exporter->ExportIntersectable(object); 
     1908 
     1909                        delete exporter; 
     1910                } 
     1911        } 
     1912} 
     1913 
     1914 
     1915void KdViewCellsManager::ExportColor(Exporter *exporter, 
     1916                                                                         ViewCell *vc) const 
     1917{ 
     1918        // TODO 
     1919} 
     1920 
     1921ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     1922{ 
     1923        return new KdViewCell(mesh); 
     1924} 
     1925 
     1926 
     1927void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
     1928                                                                                                ViewCell *vc, 
     1929                                                                                                const Plane3 *cuttingPlane) const 
     1930{ 
     1931        ViewCellContainer leaves; 
     1932 
     1933        mViewCellsTree->CollectLeaves(vc, leaves); 
     1934        ViewCellContainer::const_iterator it, it_end = leaves.end(); 
     1935 
     1936        for (it = leaves.begin(); it != it_end; ++ it) 
     1937        { 
     1938                KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it); 
     1939         
     1940                exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf)); 
     1941        } 
     1942} 
     1943 
     1944 
     1945int KdViewCellsManager::GetType() const 
     1946{ 
     1947        return ViewCellsManager::KD; 
     1948} 
     1949 
     1950 
     1951 
     1952KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf) 
     1953{ 
     1954        KdNode *node = leaf; 
     1955 
     1956        while (node->mParent && node->mDepth > mKdPvsDepth) 
     1957                node = node->mParent; 
     1958        return node; 
     1959} 
     1960 
     1961int KdViewCellsManager::CastLineSegment(const Vector3 &origin, 
     1962                                                                                const Vector3 &termination, 
     1963                                                                                ViewCellContainer &viewcells) 
     1964{ 
     1965        return mKdTree->CastLineSegment(origin, termination, viewcells); 
     1966} 
     1967 
     1968 
     1969void KdViewCellsManager::CreateMesh(ViewCell *vc) 
     1970{ 
     1971        // TODO 
     1972} 
     1973 
     1974 
     1975 
     1976void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
     1977                                                                                                vector<MergeCandidate> &candidates) 
     1978{ 
     1979        // TODO 
     1980} 
     1981 
     1982 
     1983/**********************************************************************/ 
     1984/*                   VspKdViewCellsManager implementation             */ 
     1985/**********************************************************************/ 
     1986 
     1987 
     1988VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree): 
     1989ViewCellsManager(), mVspKdTree(vspKdTree) 
     1990{ 
     1991        environment->GetIntValue("VspKdTree.Construction.samples", mInitialSamples); 
     1992        mVspKdTree->SetViewCellsManager(this); 
     1993} 
     1994 
     1995float VspKdViewCellsManager::GetProbability(ViewCell *viewCell) 
     1996{ 
     1997        // volume or area substitutes for view point probability 
     1998#if 0 
     1999        return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 
     2000#else 
     2001        return GetArea(viewCell) / GetAccVcArea(); 
     2002#endif 
     2003} 
     2004 
     2005 
     2006float VspKdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const 
     2007{ 
     2008        return viewCell->GetPvs().GetSize() * objRendercost; 
     2009} 
     2010 
     2011 
     2012void VspKdViewCellsManager::CollectViewCells() 
     2013{ 
     2014        mVspKdTree->CollectViewCells(mViewCells); 
     2015} 
     2016 
     2017 
     2018int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 
     2019                                                                                                const VssRayContainer &rays) 
     2020{ 
     2021        // if view cells already constructed 
     2022        if (ViewCellsConstructed()) 
     2023                return 0; 
     2024 
     2025        VssRayContainer constructionRays; 
     2026        VssRayContainer savedRays; 
     2027 
     2028        GetRaySets(rays, 
     2029                           mInitialSamples, 
     2030                           constructionRays, 
     2031                           &savedRays); 
     2032 
     2033        Debug << "constructing vsp kd tree using " 
     2034                  << (int)constructionRays.size() << " samples" << endl; 
     2035 
     2036        mVspKdTree->Construct(constructionRays, &mViewSpaceBox); 
     2037        Debug << mVspKdTree->GetStatistics() << endl; 
     2038 
     2039        // export leaf building blocks 
     2040        ExportLeaves(objects, rays); 
     2041 
     2042        // finally merge kd leaf building blocks to view cells 
     2043        const int merged = mVspKdTree->MergeViewCells(rays); 
     2044 
     2045        // collapse siblings belonging to the same view cell 
     2046        mVspKdTree->RefineViewCells(rays); 
     2047 
     2048        // collapse siblings belonging to the same view cell 
     2049        mVspKdTree->CollapseTree(); 
     2050 
     2051        // evaluale view cell stats 
     2052        ResetViewCells(); 
     2053 
     2054        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 
     2055 
     2056        long startTime = GetTime(); 
     2057        // recast rest of rays 
     2058        ComputeSampleContributions(savedRays, true, false); 
     2059 
     2060        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 
     2061                  << " secs" << endl; 
     2062 
     2063        return merged; 
     2064} 
     2065 
     2066bool VspKdViewCellsManager::ViewCellsConstructed() const 
     2067{ 
     2068        return mVspKdTree->GetRoot() != NULL; 
     2069} 
     2070 
     2071 
     2072ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     2073{ 
     2074        return new VspKdViewCell(mesh); 
     2075} 
     2076 
     2077int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects, 
     2078                                                                           const VssRayContainer &rays) 
     2079{ 
     2080        if (!ViewCellsConstructed()) 
     2081                return 0; 
     2082 
     2083        // recalculate stats 
     2084        EvaluateViewCellsStats(); 
     2085 
     2086        return 0; 
     2087} 
     2088 
     2089 
     2090void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects, 
     2091                                                                                 const VssRayContainer &sampleRays) 
     2092{ 
     2093        if (!ViewCellsConstructed()) 
     2094                return; 
     2095 
     2096        //-- export leaf building blocks 
     2097        Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d"); 
     2098        if (!exporter) 
     2099                return; 
     2100 
     2101        if (mExportGeometry) 
     2102                exporter->ExportGeometry(objects); 
     2103         
     2104        //exporter->SetWireframe(); 
     2105        //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize); 
     2106        exporter->ExportVspKdTree(*mVspKdTree); 
     2107 
     2108        if (mExportRays) 
     2109        { 
     2110                const float prob = (float)mVisualizationSamples 
     2111                        / ((float)sampleRays.size() + Limits::Small); 
     2112 
     2113                exporter->SetWireframe(); 
     2114 
     2115                //-- collect uniformly distributed rays 
     2116                VssRayContainer rays; 
     2117 
     2118                for (int i = 0; i < sampleRays.size(); ++ i) 
     2119                { 
     2120                        if (RandomValue(0,1) < prob) 
     2121                                rays.push_back(sampleRays[i]); 
     2122                } 
     2123                exporter->ExportRays(rays, RgbColor(1, 0, 0)); 
     2124        } 
     2125 
     2126        delete exporter; 
     2127} 
     2128 
     2129void VspKdViewCellsManager::Visualize(const ObjectContainer &objects, 
     2130                                                                          const VssRayContainer &sampleRays) 
     2131{ 
     2132        if (!ViewCellsConstructed()) 
     2133                return; 
     2134 
     2135        //-- export single view cells 
     2136        for (int i = 0; i < 10; ++ i) 
     2137        { 
     2138                char s[64]; 
     2139                sprintf(s, "vsp_viewcell%04d.x3d", i); 
     2140                Exporter *exporter = Exporter::GetExporter(s); 
     2141                const int idx = 
     2142                        (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1)); 
     2143 
     2144                VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]); 
     2145 
     2146                cout << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl; 
     2147                Debug << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl; 
     2148                //-- export geometry 
     2149                Material m; 
     2150                m.mDiffuseColor = RgbColor(0, 1, 1); 
     2151 
     2152                exporter->SetForcedMaterial(m); 
     2153                exporter->SetWireframe(); 
     2154 
     2155                ExportViewCellGeometry(exporter, vc); 
     2156 
     2157                //-- export stored rays 
     2158                 
     2159                if (mExportRays) 
     2160                { 
     2161                        ViewCellContainer leaves; 
     2162                        mViewCellsTree->CollectLeaves(vc, leaves); 
     2163 
     2164                        ViewCellContainer::const_iterator it, 
     2165                                it_end = leaves.end(); 
     2166 
     2167                        for (it = leaves.begin(); it != it_end; ++ it) 
     2168                        { 
     2169                                VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it); 
     2170                                VspKdLeaf *leaf = vspKdVc->mLeaf; 
     2171                                AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf); 
     2172 
     2173                                VssRayContainer vssRays; 
     2174 
     2175                                VssRayContainer castRays; 
     2176                                VssRayContainer initRays; 
     2177 
     2178                                leaf->GetRays(vssRays); 
     2179 
     2180                                VssRayContainer::const_iterator it, it_end = vssRays.end(); 
     2181                                const float prop = 200.0f / (float)vssRays.size(); 
     2182 
     2183                                for (it = vssRays.begin(); it != it_end; ++ it) 
     2184                                { 
     2185                                        if (Random(1) < prop) 
     2186                                                if ((*it)->mTerminationObject == NULL) 
     2187                                                        castRays.push_back(*it); 
     2188                                                else 
     2189                                                        initRays.push_back(*it); 
     2190                                } 
     2191 
     2192                                exporter->ExportRays(castRays, RgbColor(1, 0, 0)); 
     2193                                exporter->ExportRays(initRays, RgbColor(0, 1, 0)); 
     2194                        } 
     2195                } 
     2196         
     2197                //-- output PVS of view cell 
     2198                m.mDiffuseColor = RgbColor(1, 0, 0); 
     2199                exporter->SetForcedMaterial(m); 
     2200 
     2201                Intersectable::NewMail(); 
     2202 
     2203                ObjectPvsMap::const_iterator it, 
     2204                        it_end = vc->GetPvs().mEntries.end(); 
     2205 
     2206                exporter->SetFilled(); 
     2207 
     2208                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
     2209                { 
     2210                        Intersectable *intersect = (*it).first; 
     2211 
     2212                        if (!intersect->Mailed()) 
     2213                        { 
     2214                                Material m = RandomMaterial(); 
     2215                                exporter->SetForcedMaterial(m); 
     2216 
     2217                                exporter->ExportIntersectable(intersect); 
     2218                                intersect->Mail(); 
     2219                        } 
     2220                } 
     2221 
     2222                delete exporter; 
     2223        } 
     2224 
     2225        //-- export final view cells 
     2226        Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d"); 
     2227 
     2228        //if (exportGeometry) exporter->SetWireframe(); 
     2229        //else exporter->SetFilled(); 
     2230 
     2231        ExportViewCellsForViz(exporter); 
     2232 
     2233        if (mExportGeometry) 
     2234        { 
     2235                exporter->SetFilled(); 
     2236                exporter->ExportGeometry(objects); 
     2237        } 
     2238 
     2239        if (mExportRays) 
     2240        { 
     2241                const float prob = (float)mVisualizationSamples 
     2242                        / ((float)sampleRays.size() + Limits::Small); 
     2243 
     2244                exporter->SetWireframe(); 
     2245 
     2246                VssRayContainer rays; 
     2247 
     2248                for (int i = 0; i < sampleRays.size(); ++ i) 
     2249                { 
     2250                  if (RandomValue(0,1) < prob) 
     2251                        rays.push_back(sampleRays[i]); 
     2252                } 
     2253                exporter->ExportRays(rays, RgbColor(1, 0, 0)); 
     2254        } 
     2255 
     2256        delete exporter; 
     2257} 
     2258 
     2259int VspKdViewCellsManager::GetType() const 
     2260{ 
     2261        return VSP_KD; 
     2262} 
     2263 
     2264 
     2265int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin, 
     2266                                                                                   const Vector3 &termination, 
     2267                                                                                   ViewCellContainer &viewcells) 
     2268{ 
     2269        return mVspKdTree->CastLineSegment(origin, termination, viewcells); 
     2270} 
     2271 
     2272 
     2273void VspKdViewCellsManager::ExportColor(Exporter *exporter, 
     2274                                                                                ViewCell *vc) const 
     2275{ 
     2276        if (mColorCode == 0) // Random color 
     2277                return; 
     2278 
     2279        float importance = 0; 
     2280 
     2281        switch (mColorCode) 
     2282        { 
     2283        case 1: // pvs 
     2284                { 
     2285                        importance = (float)vc->GetPvs().GetSize() / 
     2286                                (float)mViewCellsStats.maxPvs; 
     2287                } 
     2288                break; 
     2289        case 2: // merged leaves 
     2290                { 
     2291                int lSize = mViewCellsTree->GetSize(vc); 
     2292                        importance = (float)lSize / 
     2293                                (float)mViewCellsStats.maxLeaves; 
     2294                } 
     2295                break; 
     2296        case 3: // merged tree depth difference 
     2297                { 
     2298                        //importance = (float)GetMaxTreeDiff(vc) / 
     2299                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2); 
     2300                } 
     2301                break; 
     2302        default: 
     2303                break; 
     2304        } 
     2305 
     2306        Material m; 
     2307        m.mDiffuseColor.b = 1.0f; 
     2308        m.mDiffuseColor.r = importance; 
     2309        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 
     2310        //Debug << "importance: " << importance << endl; 
     2311        exporter->SetForcedMaterial(m); 
     2312} 
     2313 
     2314 
     2315void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
     2316                                                                                                   ViewCell *vc, 
     2317                                                                                                   const Plane3 *cuttingPlane) const 
     2318{ 
     2319        VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc); 
     2320 
     2321        Mesh m; 
     2322 
     2323        ViewCellContainer leaves; 
     2324        mViewCellsTree->CollectLeaves(vc, leaves); 
     2325 
     2326        ViewCellContainer::const_iterator it, it_end = leaves.end(); 
     2327 
     2328        for (it = leaves.begin(); it != it_end; ++ it) 
     2329        { 
     2330                VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf; 
     2331                mVspKdTree->GetBBox(l).AddBoxToMesh(&m); 
     2332        } 
     2333 
     2334        exporter->ExportMesh(&m); 
     2335} 
     2336 
     2337 
     2338void VspKdViewCellsManager::CreateMesh(ViewCell *vc) 
     2339{ 
     2340        //TODO 
     2341} 
     2342 
     2343 
     2344void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
     2345                                                                                                   vector<MergeCandidate> &candidates) 
     2346{ 
     2347        // TODO 
     2348} 
     2349 
     2350 
     2351/**************************************************************************/ 
     2352/*                   VspBspViewCellsManager implementation                */ 
     2353/**************************************************************************/ 
     2354 
     2355 
     2356VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree): 
     2357ViewCellsManager(), mVspBspTree(vspBspTree) 
     2358{ 
     2359        environment->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 
     2360        mVspBspTree->SetViewCellsManager(this); 
     2361        mVspBspTree->mViewCellsTree = mViewCellsTree; 
     2362} 
     2363 
     2364 
     2365VspBspViewCellsManager::~VspBspViewCellsManager() 
     2366{ 
     2367} 
     2368 
     2369 
     2370float VspBspViewCellsManager::GetProbability(ViewCell *viewCell) 
     2371{ 
     2372        if (0 && mVspBspTree->mUseAreaForPvs) 
     2373                return GetArea(viewCell) / GetAccVcArea(); 
     2374        else 
     2375                return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 
     2376} 
     2377 
     2378 
     2379void VspBspViewCellsManager::CollectViewCells() 
     2380{ 
     2381        // view cells tree constructed 
     2382        if (!ViewCellsTreeConstructed()) 
     2383        { 
     2384                mVspBspTree->CollectViewCells(mViewCells, false); 
     2385        } 
     2386        else  
     2387        { 
     2388                // we can use the view cells tree hierarchy to get the right set 
     2389                mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells); 
     2390        } 
     2391 
     2392} 
     2393 
     2394 
     2395float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell, 
     2396                                                                                        float objRendercost) const 
     2397{ 
     2398        return viewCell->GetPvs().GetSize() * objRendercost; 
     2399} 
     2400 
     2401 
     2402bool VspBspViewCellsManager::ViewCellsConstructed() const 
     2403{ 
     2404        return mVspBspTree->GetRoot() != NULL; 
     2405} 
     2406 
     2407 
     2408ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     2409{ 
     2410        return new BspViewCell(mesh); 
     2411} 
     2412 
     2413 
     2414/*void VspBspViewCellsManager::CollectNodes(ViewCell *vc, vector<BspNode *>nodes) 
     2415{ 
     2416        void ViewCellsTree::CollectLeaves(ViewCell *vc, vector<BspNode *> &nodes) const 
     2417         
     2418        if (vc->IsLeaf()) 
     2419        { 
     2420                BspViewCell *bvc = dynamic_cast<BspViewCell *>(vc); 
     2421                nodes->push_back(bvc->mLeaf); 
     2422        } 
     2423        else 
     2424        { 
     2425                ViewCellContainer::const_iterator it, it_end = interior->mChildren.end(); 
     2426 
     2427                for (it = interior->mChildren.begin; it != it_end; ++ it) 
     2428                { 
     2429                        vector<BspNode *> mynodes; 
     2430                        CollectNodes(*it, mynodes); 
     2431 
     2432                        if (mynodes[0]->GetParent() && (mynodes[0]->GetParent() == mynodes[1]->GetParent())) 
     2433                        { 
     2434                                nodes.push_back(nodes[0]->GetParent()); 
     2435                        } 
     2436 
     2437                } 
     2438        } 
     2439}*/ 
     2440 
     2441 
     2442int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 
     2443                                                                                                 const VssRayContainer &rays) 
     2444{ 
     2445        // if view cells were already constructed 
     2446        if (ViewCellsConstructed()) 
     2447                return 0; 
     2448 
     2449        Debug << "Constructing bsp view cells" << endl; 
     2450 
     2451        int sampleContributions = 0; 
     2452 
     2453        VssRayContainer sampleRays; 
     2454 
     2455        int limit = min (mInitialSamples, (int)rays.size()); 
     2456 
     2457        VssRayContainer constructionRays; 
     2458        VssRayContainer savedRays; 
     2459 
     2460        Debug << "samples used for subdivision: " << mInitialSamples  
     2461                  << " rays: " << (int)rays.size() << endl; 
     2462 
     2463        GetRaySets(rays, mInitialSamples, constructionRays, &savedRays); 
     2464 
     2465        Debug << "initial rays: " << (int)constructionRays.size() << endl; 
     2466        Debug << "saved rays: " << (int)savedRays.size() << endl; 
     2467 
     2468        mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size()); 
     2469 
     2470        mVspBspTree->Construct(constructionRays, &mViewSpaceBox); 
     2471 
     2472        Debug << mVspBspTree->GetStatistics() << endl; 
     2473 
     2474        // collapse invalid regions 
     2475        cout << "collapsing invalid tree regions ... "; 
     2476        long startTime = GetTime(); 
     2477        int collapsedLeaves = mVspBspTree->CollapseTree(); 
     2478        Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3  
     2479                  << " seconds" << endl; 
     2480 
     2481    cout << "finished" << endl; 
     2482 
     2483        cout << "reseting view cell stats ... "; 
     2484        ResetViewCells(); 
     2485        cout << "finished" << endl; 
     2486 
     2487        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 
     2488 
     2489        if (1) // export initial view cells 
     2490        { 
     2491                cout << "exporting initial view cells (=leaves) ... "; 
     2492                Exporter *exporter = Exporter::GetExporter("view_cells.x3d"); 
     2493 
     2494                if (exporter) 
     2495                { 
     2496                        if (0 && mExportRays) 
     2497                                exporter->ExportRays(rays, RgbColor(1, 1, 1)); 
     2498 
     2499                        if (mExportGeometry) 
     2500                                exporter->ExportGeometry(objects); 
     2501 
     2502                        //exporter->SetWireframe(); 
     2503                        exporter->SetFilled(); 
     2504                        ExportViewCellsForViz(exporter); 
     2505 
     2506                        delete exporter; 
     2507                } 
     2508                cout << "finished" << endl; 
     2509        } 
     2510 
     2511        startTime = GetTime(); 
     2512 
     2513        // reset view cells and stats 
     2514        ResetViewCells(); 
     2515 
     2516        cout << "Computing remaining ray contributions ... "; 
     2517        // recast rest of rays 
     2518        ComputeSampleContributions(savedRays, true, false); 
     2519        cout << "finished" << endl; 
     2520 
     2521        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 
     2522                  << " secs" << endl; 
     2523 
     2524        cout << "construction finished" << endl; 
     2525 
     2526        return sampleContributions; 
     2527} 
     2528 
     2529 
     2530void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays, 
     2531                                                                                        const ObjectContainer &objects) 
     2532{ 
     2533        //-- post processing of bsp view cells 
     2534    int vcSize = 0; 
     2535        int pvsSize = 0; 
     2536 
     2537        mRenderer->RenderScene(); 
     2538        SimulationStatistics ss; 
     2539        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 
     2540    Debug << ss << endl; 
     2541 
     2542        //-- merge or subdivide view cells 
     2543        int merged = 0; 
     2544        if (mMergeViewCells) 
     2545        { 
     2546                cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl; 
     2547                long startTime = GetTime(); 
     2548 
     2549         
     2550                // TODO: should be done BEFORE the ray casting 
     2551                merged = mViewCellsTree->ConstructMergeTree(rays, objects); 
     2552 
     2553                //-- stats and visualizations 
     2554                cout << "finished merging" << endl; 
     2555                cout << "merged " << merged << " view cells in " 
     2556                         << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 
     2557 
     2558                Debug << "Postprocessing: Merged " << merged << " view cells in " 
     2559                          << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 
     2560        } 
     2561 
     2562        int savedColorCode = mColorCode; 
     2563         
     2564        //BspLeaf::NewMail(); 
     2565        if (1) // export merged view cells 
     2566        { 
     2567                mColorCode = 0; 
     2568                cout << "reseting view cells ... "; 
     2569                ResetViewCells(); 
     2570 
     2571                cout << "finished" << endl; 
     2572 
     2573                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 
     2574                Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 
     2575 
     2576                cout << "exporting view cells after merge ... "; 
     2577 
     2578                if (exporter) 
     2579                { 
     2580                        if (0) 
     2581                                exporter->SetWireframe(); 
     2582                        else 
     2583                                exporter->SetFilled(); 
     2584 
     2585                        ExportViewCellsForViz(exporter); 
     2586 
     2587                        if (mExportGeometry) 
     2588                        { 
     2589                                Material m; 
     2590                                m.mDiffuseColor = RgbColor(0, 1, 0); 
     2591                                exporter->SetForcedMaterial(m); 
     2592                                exporter->SetFilled(); 
     2593 
     2594                                exporter->ExportGeometry(objects); 
     2595                        } 
     2596 
     2597                        delete exporter; 
     2598                } 
     2599                cout << "finished" << endl; 
     2600        } 
     2601 
     2602        if (1) // export merged view cells 
     2603        { 
     2604                mColorCode = 1; 
     2605 
     2606                Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d"); 
     2607         
     2608                cout << "exporting view cells after merge (pvs size) ... ";      
     2609 
     2610                if (exporter) 
     2611                { 
     2612                        if (0) 
     2613                                exporter->SetWireframe(); 
     2614                        else 
     2615                                exporter->SetFilled(); 
     2616 
     2617                        ExportViewCellsForViz(exporter); 
     2618 
     2619                        if (mExportGeometry) 
     2620                        { 
     2621                                Material m; 
     2622                                m.mDiffuseColor = RgbColor(0, 1, 0); 
     2623                                exporter->SetForcedMaterial(m); 
     2624                                exporter->SetFilled(); 
     2625 
     2626                                exporter->ExportGeometry(objects); 
     2627                        } 
     2628 
     2629                        delete exporter; 
     2630                } 
     2631                cout << "finished" << endl; 
     2632        } 
     2633 
     2634        mColorCode = savedColorCode; 
     2635 
     2636} 
     2637 
     2638 
     2639void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays, 
     2640                                                                                         const ObjectContainer &objects) 
     2641{ 
     2642        Debug << "render time before refine:" << endl; 
     2643        mRenderer->RenderScene(); 
     2644        SimulationStatistics ss; 
     2645        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 
     2646    Debug << ss << endl; 
     2647 
     2648        cout << "Refining the merged view cells ... "; 
     2649        long startTime = GetTime(); 
     2650 
     2651        // refining the merged view cells 
     2652        const int refined = mViewCellsTree->RefineViewCells(rays, objects); 
     2653 
     2654        //-- stats and visualizations 
     2655        cout << "finished" << endl; 
     2656        cout << "refined " << refined << " view cells in " 
     2657                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 
     2658 
     2659        Debug << "Postprocessing: refined " << refined << " view cells in " 
     2660                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 
     2661} 
     2662 
     2663 
     2664int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects, 
     2665                                                                                const VssRayContainer &rays) 
     2666{ 
     2667        if (!ViewCellsConstructed()) 
     2668        { 
     2669                Debug << "postprocess error: no view cells constructed" << endl; 
     2670                return 0; 
     2671        } 
     2672 
     2673 
     2674        // view cells already finished before post processing step (i.e. because they were loaded) 
     2675        if (mViewCellsFinished) 
     2676        { 
     2677                FinalizeViewCells(true); 
     2678                EvaluateViewCellsStats(); 
     2679 
     2680                return 0; 
     2681        } 
     2682 
     2683 
     2684        // check if new view cells turned invalid 
     2685        SetValidity(mMinPvsSize, mMaxPvsSize);  
     2686        // update valid view space according to valid view cells 
     2687        mVspBspTree->ValidateTree(); 
     2688 
     2689        // recompute view cell statistics 
     2690        mViewCellsStats.Reset(); 
     2691        EvaluateViewCellsStats(); 
     2692 
     2693        // has to be recomputed 
     2694        mTotalAreaValid = false; 
     2695 
     2696 
     2697        VssRayContainer postProcessRays; 
     2698        GetRaySets(rays, mPostProcessSamples, postProcessRays); 
     2699 
     2700        Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl; 
     2701 
     2702        Debug << "\nview cell partition after sampling:\n" << mViewCellsStats << endl << endl; 
     2703 
     2704        // should maybe be done here to allow merge working with area or volume 
     2705        // and to correct the rendering statistics 
     2706        if (0) 
     2707        { 
     2708                FinalizeViewCells(false); 
     2709        } 
     2710 
     2711        //-- merge the individual view cells 
     2712        MergeViewCells(postProcessRays, objects); 
     2713         
     2714 
     2715        //-- refines the merged view cells 
     2716        if (0) 
     2717                RefineViewCells(postProcessRays, objects); 
     2718 
     2719         
     2720        if (1) 
     2721        {                
     2722                float totalCost, erc, var, dev, avg; 
     2723                int totalpvs; 
     2724 
     2725                mViewCellsStats.Reset(); 
     2726 
     2727        EvaluateRenderStatistics(totalCost, erc, dev, var, totalpvs, avg); 
     2728                 
     2729                Debug << "statistics after merge "   
     2730                          << " erc: " << erc  
     2731                          << " dev: " << dev 
     2732                          << " totalpvs: " << totalpvs  
     2733                          << " avg: " << avg << endl; 
     2734        } 
     2735 
     2736        //-- render simulation after merge 
     2737  cout << "\nevaluating bsp view cells render time before compress ... "; 
     2738  dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene(); 
     2739  SimulationStatistics ss; 
     2740  dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 
     2741   
     2742  cout << " finished" << endl; 
     2743  cout << ss << endl; 
     2744  Debug << ss << endl; 
     2745 
     2746 
     2747 
     2748        //-- compression 
     2749 
     2750        if (ViewCellsTreeConstructed() && mCompressViewCells) 
     2751        { 
     2752                int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 
     2753                Debug << "number of entries before compress: " << pvsEntries << endl; 
     2754 
     2755                mViewCellsTree->CompressViewCellsPvs(); 
     2756 
     2757                pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 
     2758                Debug << "number of entries after compress: " << pvsEntries << endl; 
     2759        } 
     2760 
     2761 
     2762        //-- export refined (shuffled) view cells 
     2763        if (0) 
     2764        { 
     2765                cout << "exporting shuffled view cells ... "; 
     2766 
     2767                Exporter *exporter = Exporter::GetExporter("shuffled_view_cells.x3d"); 
     2768                if (exporter) 
     2769                { 
     2770                        if (1) 
     2771                        { 
     2772                                exporter->SetWireframe(); 
     2773                                exporter->ExportBox(mViewSpaceBox); 
     2774                                exporter->SetFilled(); 
     2775                        } 
     2776 
     2777                        if (mExportGeometry) 
     2778                        { 
     2779                                exporter->ExportGeometry(objects); 
     2780                        } 
     2781 
     2782                        ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 
     2783 
     2784                        Material vm, lm; 
     2785 
     2786                        for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 
     2787                        { 
     2788                                ViewCell *vc = *vit; 
     2789 
     2790                                vm = RandomMaterial(); 
     2791 
     2792                                lm = vm; 
     2793 
     2794                                vm.mDiffuseColor.r -= 0.45f; 
     2795                                vm.mDiffuseColor.g -= 0.45f; 
     2796                                vm.mDiffuseColor.b -= 0.45f; 
     2797 
     2798 
     2799                                ViewCellContainer leaves; 
     2800                                mViewCellsTree->CollectLeaves(vc, leaves); 
     2801 
     2802                                ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
     2803 
     2804                                for (lit = leaves.begin(); lit != lit_end; ++ lit) 
     2805                                { 
     2806                                        BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 
     2807 
     2808                                        if (leaf->Mailed()) 
     2809                                                exporter->SetForcedMaterial(lm); 
     2810                                        else 
     2811                                                exporter->SetForcedMaterial(vm); 
     2812 
     2813                                        BspNodeGeometry geom; 
     2814                                        mVspBspTree->ConstructGeometry(leaf, geom); 
     2815                                        exporter->ExportPolygons(geom.mPolys); 
     2816                                } 
     2817                        } 
     2818 
     2819                        delete exporter; 
     2820                } 
     2821 
     2822 
     2823                cout << "finished" << endl; 
     2824        } 
     2825 
     2826        // collapse sibling leaves that share the same view cell 
     2827        if (0) 
     2828                mVspBspTree->CollapseTree(); 
     2829 
     2830        // recompute view cell list and statistics 
     2831        ResetViewCells(); 
     2832 
     2833        // real meshes are only contructed only at this stage 
     2834        FinalizeViewCells(true); 
     2835 
     2836        // write view cells to disc 
     2837        if (mExportViewCells) 
     2838        { 
     2839                char buff[100]; 
     2840                environment->GetStringValue("ViewCells.filename", buff); 
     2841                string vcFilename(buff); 
     2842 
     2843                ExportViewCells(buff); 
     2844        } 
     2845 
     2846        return 0; 
     2847} 
     2848 
     2849 
     2850int VspBspViewCellsManager::GetType() const 
     2851{ 
     2852        return VSP_BSP; 
     2853} 
     2854 
     2855 
     2856bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const 
     2857{ 
     2858        if (!ViewCellsConstructed()) 
     2859                return ViewCellsManager::GetViewPoint(viewPoint); 
     2860 
     2861        // TODO: set reasonable limit 
     2862        const int limit = 20; 
     2863 
     2864        for (int i = 0; i < limit; ++ i) 
     2865        { 
     2866                viewPoint = mViewSpaceBox.GetRandomPoint(); 
     2867                if (mVspBspTree->ViewPointValid(viewPoint)) 
     2868                { 
     2869                        return true; 
     2870                } 
     2871        } 
     2872        Debug << "failed to find valid view point, taking " << viewPoint << endl; 
     2873        return false; 
     2874} 
     2875 
     2876 
     2877bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const 
     2878{ 
     2879  // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic 
     2880  // validy update in preprocessor for all managers) 
     2881  return ViewCellsManager::ViewPointValid(viewPoint); 
     2882 
     2883  //    return mViewSpaceBox.IsInside(viewPoint) && 
     2884  //               mVspBspTree->ViewPointValid(viewPoint); 
     2885} 
     2886 
     2887 
     2888void VspBspViewCellsManager::Visualize(const ObjectContainer &objects, 
     2889                                                                           const VssRayContainer &sampleRays) 
     2890{ 
     2891        if (!ViewCellsConstructed()) 
     2892                return; 
     2893 
     2894        VssRayContainer visRays; 
     2895        GetRaySets(sampleRays, mVisualizationSamples, visRays); 
     2896 
     2897         
     2898        if (1) // export view cells 
     2899        {// hack pvs 
     2900                int savedColorCode = mColorCode; 
     2901                mColorCode = 1; 
     2902                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 
     2903                 
     2904                if (exporter) 
     2905                { 
     2906                        cout << "exporting view cells after post process ... "; 
     2907 
     2908                        if (0) 
     2909                        { 
     2910                                exporter->SetWireframe(); 
     2911                                exporter->ExportBox(mViewSpaceBox); 
     2912                                exporter->SetFilled(); 
     2913                        } 
     2914 
     2915                        if (mExportGeometry) 
     2916                        { 
     2917                                exporter->ExportGeometry(objects); 
     2918                        } 
     2919 
     2920                        // export rays 
     2921                        if (mExportRays) 
     2922                        { 
     2923                                exporter->ExportRays(visRays, RgbColor(0, 1, 0)); 
     2924                        } 
     2925 
     2926                        ExportViewCellsForViz(exporter); 
     2927                        delete exporter; 
     2928                        cout << "finished" << endl; 
     2929                } 
     2930 
     2931                mColorCode = savedColorCode; 
     2932        } 
     2933 
     2934        if (0) 
     2935        { 
     2936                cout << "exporting depth map ... "; 
     2937 
     2938                Exporter *exporter = Exporter::GetExporter("depth_map.x3d"); 
     2939                if (exporter) 
     2940                { 
     2941                        if (1) 
     2942                        { 
     2943                                exporter->SetWireframe(); 
     2944                                exporter->ExportBox(mViewSpaceBox); 
     2945                                exporter->SetFilled(); 
     2946                        } 
     2947 
     2948                        if (mExportGeometry) 
     2949                        { 
     2950                                exporter->ExportGeometry(objects); 
     2951                        } 
     2952 
     2953                        const int maxDepth = mVspBspTree->mBspStats.maxDepth; 
     2954 
     2955                        ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 
     2956 
     2957                        for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 
     2958                        { 
     2959                                ViewCell *vc = *vit; 
     2960 
     2961                                ViewCellContainer leaves; 
     2962                                mViewCellsTree->CollectLeaves(vc, leaves); 
     2963 
     2964                                ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
     2965 
     2966                                for (lit = leaves.begin(); lit != lit_end; ++ lit) 
     2967                                { 
     2968                                        BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 
     2969 
     2970                                        Material m;  
     2971 
     2972                                        float relDepth = (float)leaf->GetDepth() / (float)maxDepth; 
     2973                                        m.mDiffuseColor.r = relDepth; 
     2974                                        m.mDiffuseColor.g = 0.0f; 
     2975                                        m.mDiffuseColor.b = 1.0f - relDepth; 
     2976 
     2977                    exporter->SetForcedMaterial(m); 
     2978                                 
     2979 
     2980                                        BspNodeGeometry geom; 
     2981                                        mVspBspTree->ConstructGeometry(leaf, geom); 
     2982                                        exporter->ExportPolygons(geom.mPolys); 
     2983                                } 
     2984                        } 
     2985 
     2986                        delete exporter; 
     2987                } 
     2988 
     2989 
     2990                cout << "finished" << endl; 
     2991        } 
     2992 
     2993        //-- visualization of the BSP splits 
     2994        bool exportSplits = false; 
     2995        environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits); 
     2996 
     2997        if (exportSplits) 
     2998        { 
     2999                cout << "exporting splits ... "; 
     3000                ExportSplits(objects, visRays); 
     3001                cout << "finished" << endl; 
     3002        } 
     3003 
     3004        //-- export single view cells 
     3005        ExportBspPvs(objects, visRays); 
     3006} 
     3007 
     3008 
     3009void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects, 
     3010                                                                                  const VssRayContainer &rays) 
     3011{ 
     3012        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 
     3013 
     3014        if (exporter) 
     3015        { 
     3016                Material m; 
     3017                m.mDiffuseColor = RgbColor(1, 0, 0); 
     3018                exporter->SetForcedMaterial(m); 
     3019                exporter->SetWireframe(); 
     3020 
     3021                exporter->ExportBspSplits(*mVspBspTree, true); 
     3022 
     3023                // take forced material, else big scenes cannot be viewed 
     3024                m.mDiffuseColor = RgbColor(0, 1, 0); 
     3025                exporter->SetForcedMaterial(m); 
     3026                exporter->SetFilled(); 
     3027 
     3028                exporter->ResetForcedMaterial(); 
     3029 
     3030                // export rays 
     3031                if (mExportRays) 
     3032                        exporter->ExportRays(rays, RgbColor(1, 1, 0)); 
     3033 
     3034                if (mExportGeometry) 
     3035                        exporter->ExportGeometry(objects); 
     3036 
     3037                delete exporter; 
     3038        } 
     3039} 
     3040 
     3041 
     3042void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects, 
     3043                                                                                  const VssRayContainer &rays) 
     3044{ 
     3045        const int leafOut = 10; 
     3046 
     3047        ViewCell::NewMail(); 
     3048 
     3049        cout << "visualization using " << mVisualizationSamples << " samples" << endl; 
     3050        Debug << "\nOutput view cells: " << endl; 
     3051 
     3052        // sort view cells to visualize the largest view cells 
     3053        if (0) 
     3054                stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt); 
     3055 
     3056        int limit = min(leafOut, (int)mViewCells.size()); 
     3057 
     3058        int raysOut; 
     3059 
     3060        //-- some rays for output 
     3061        if (1) 
     3062                raysOut = min((int)rays.size(), mVisualizationSamples); 
     3063 
     3064        for (int i = 0; i < limit; ++ i) 
     3065        { 
     3066                cout << "creating output for view cell " << i << " ... "; 
     3067 
     3068                VssRayContainer vcRays; 
     3069                Intersectable::NewMail(); 
     3070                ViewCell *vc; 
     3071         
     3072                if (0) // largest view cell pvs first 
     3073                        vc = mViewCells[i]; 
     3074                else 
     3075                        vc = mViewCells[Random((int)mViewCells.size())]; 
     3076 
     3077                vector<ViewCell *> leaves; 
     3078                mViewCellsTree->CollectLeaves(vc, leaves); 
     3079 
     3080        if (1) 
     3081                { 
     3082                        // check whether we can add the current ray to the output rays 
     3083                        for (int k = 0; k < raysOut; ++ k) 
     3084                        { 
     3085                                VssRay *ray = rays[k]; 
     3086                                for     (int j = 0; j < (int)ray->mViewCells.size(); ++ j) 
     3087                                { 
     3088                                        ViewCell *rayvc = ray->mViewCells[j]; 
     3089 
     3090                                        if (leaves[0] == rayvc) 
     3091                                                vcRays.push_back(ray); 
     3092                                } 
     3093                        } 
     3094                } 
     3095 
     3096                //bspLeaves[j]->Mail(); 
     3097                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 
     3098                Exporter *exporter = Exporter::GetExporter(s); 
     3099                exporter->SetWireframe(); 
     3100 
     3101                Material m;//= RandomMaterial(); 
     3102                m.mDiffuseColor = RgbColor(0, 1, 0); 
     3103                exporter->SetForcedMaterial(m); 
     3104 
     3105                ExportViewCellGeometry(exporter, vc); 
     3106 
     3107 
     3108                Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) 
     3109                          << ", piercing rays=" << (int)vcRays.size() << endl; 
     3110                        //  << ", leaves=" << (int)vc->mLeaves.size() << endl; 
     3111 
     3112                 
     3113                //-- export rays piercing this view cell 
     3114                if (1) 
     3115                { 
     3116                        exporter->ExportRays(vcRays, RgbColor(1, 1, 1)); 
     3117                } 
     3118                else 
     3119                { 
     3120 
     3121                        ViewCellContainer leaves; 
     3122                        mViewCellsTree->CollectLeaves(vc, leaves); 
     3123 
     3124                        ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
     3125 
     3126                        for (lit = leaves.begin(); lit != lit_end; ++ lit) 
     3127                        { 
     3128                                BspLeaf *l = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 
     3129                                exporter->ExportRays(l->mVssRays); 
     3130                        } 
     3131                } 
     3132 
     3133         
     3134                m.mDiffuseColor = RgbColor(1, 0, 0); 
     3135                exporter->SetForcedMaterial(m); 
     3136 
     3137                ObjectPvsMap::const_iterator it, 
     3138                        it_end = vc->GetPvs().mEntries.end(); 
     3139 
     3140                exporter->SetFilled(); 
     3141 
     3142         
     3143                // output PVS of view cell 
     3144                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
     3145                { 
     3146                 
     3147                        Intersectable *intersect = (*it).first; 
     3148 
     3149                        if (!intersect->Mailed()) 
     3150                        { 
     3151                                Material m = RandomMaterial(); 
     3152                                exporter->SetForcedMaterial(m); 
     3153 
     3154                                exporter->ExportIntersectable(intersect); 
     3155                                intersect->Mail(); 
     3156                        } 
     3157                } 
     3158 
     3159                 
     3160                DEL_PTR(exporter); 
     3161                cout << "finished" << endl; 
     3162        } 
     3163 
     3164        Debug << endl; 
     3165} 
     3166 
     3167 
     3168int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin, 
     3169                                                                                        const Vector3 &termination, 
     3170                                                                                        ViewCellContainer &viewcells) 
     3171{ 
     3172        return mVspBspTree->CastLineSegment(origin, termination, viewcells); 
     3173} 
     3174 
     3175 
     3176void VspBspViewCellsManager::ExportColor(Exporter *exporter, 
     3177                                                                                 ViewCell *vc) const 
     3178{ 
     3179        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 
    14093180 
    14103181        float importance = 0; 
     
    14423213                { 
    14433214            int lSize = mViewCellsTree->GetSize(vc); 
    1444          
    1445                         importance = (float)lSize / (float)mViewCellsStats.maxLeaves; 
    1446                 } 
    1447                 //break; 
    1448         case 3: // merge tree differene 
    1449                 { 
    1450                         // TODO 
    1451                         //importance = (float)GetMaxTreeDiff(vc) / 
    1452                         //      (float)(mVspBspTree->GetStatistics().maxDepth * 2); 
    1453  
    1454                 } 
    1455                 break; 
    1456         default: 
    1457                 break; 
    1458         } 
    1459  
    1460         // special color code for invalid view cells 
    1461         m.mDiffuseColor.r = importance; 
    1462         m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 
    1463         m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f; 
    1464  
    1465         //Debug << "importance: " << importance << endl; 
    1466         exporter->SetForcedMaterial(m); 
    1467 } 
    1468  
    1469  
    1470 void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
    1471                                                                                                  ViewCell *vc, 
    1472                                                                                                  const Plane3 *cuttingPlane) const 
    1473 { 
    1474         if (vc->GetMesh()) 
    1475         { 
    1476                 exporter->ExportMesh(vc->GetMesh()); 
    1477          
    1478                 return; 
    1479         } 
    1480  
    1481         BspNodeGeometry geom; 
    1482         mBspTree->ConstructGeometry(vc, geom); 
    1483  
    1484  
    1485         if (cuttingPlane) 
    1486         { 
    1487                 BspNodeGeometry front; 
    1488                 BspNodeGeometry back; 
    1489  
    1490                 geom.SplitGeometry(front, 
    1491                                                    back, 
    1492                                                    *cuttingPlane, 
    1493                                                    mViewSpaceBox,  
    1494                                                    0.0001); 
    1495  
    1496                 exporter->ExportPolygons(back.mPolys); 
    1497         } 
    1498         else 
    1499         { 
    1500                 exporter->ExportPolygons(geom.mPolys); 
    1501         } 
    1502 } 
    1503  
    1504  
    1505 void BspViewCellsManager::CreateMesh(ViewCell *vc) 
    1506 { 
    1507         if (vc->GetMesh()) 
    1508                 delete vc->GetMesh(); 
    1509  
    1510         BspNodeGeometry geom; 
    1511          
    1512         mBspTree->ConstructGeometry(vc, geom); 
    1513  
    1514         Mesh *mesh = new Mesh(); 
    1515         geom.AddToMesh(*mesh); 
    1516         vc->SetMesh(mesh); 
    1517         mMeshContainer.push_back(mesh); 
    1518 } 
    1519  
    1520  
    1521 void BspViewCellsManager::Finalize(ViewCell *viewCell,  
    1522                                                                    const bool createMesh) 
    1523 { 
    1524         CreateMesh(viewCell); 
    1525  
    1526         float area = 0; 
    1527         float volume = 0; 
    1528  
    1529         ViewCellContainer leaves; 
    1530         mViewCellsTree->CollectLeaves(viewCell, leaves); 
    1531  
    1532         ViewCellContainer::const_iterator it, it_end = leaves.end(); 
    1533  
    1534         for (it = leaves.begin(); it != it_end; ++ it) 
    1535         { 
    1536                 BspNodeGeometry geom; 
    1537                 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 
    1538                 mBspTree->ConstructGeometry(leaf, geom); 
    1539  
    1540                 area += geom.GetArea(); 
    1541                 volume += geom.GetVolume(); 
    1542         } 
    1543  
    1544         viewCell->SetVolume(volume); 
    1545         viewCell->SetArea(area); 
    1546 } 
    1547  
    1548  
    1549 ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point) const 
    1550 { 
    1551         if (!mBspTree) 
    1552                 return NULL; 
    1553  
    1554         if (!mViewSpaceBox.IsInside(point)) 
    1555                 return NULL; 
    1556          
    1557         return mBspTree->GetViewCell(point); 
    1558 } 
    1559  
    1560  
    1561 void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
    1562                                                                                                  vector<MergeCandidate> &candidates) 
    1563 { 
    1564         cout << "collecting merge candidates ... " << endl; 
    1565  
    1566         if (mUseRaysForMerge) 
    1567         { 
    1568                 mBspTree->CollectMergeCandidates(rays, candidates); 
    1569         } 
    1570         else 
    1571         { 
    1572                 vector<BspLeaf *> leaves; 
    1573                 mBspTree->CollectLeaves(leaves); 
    1574                 mBspTree->CollectMergeCandidates(leaves, candidates); 
    1575         } 
    1576  
    1577         cout << "fininshed collecting candidates" << endl; 
    1578 } 
    1579  
    1580  
    1581  
    1582 bool BspViewCellsManager::ExportViewCells(const string filename) 
    1583 { 
    1584         cout << "exporting view cells to xml ... "; 
    1585         std::ofstream stream; 
    1586  
    1587         // for output we need unique ids for each view cell 
    1588         CreateUniqueViewCellIds(); 
    1589  
    1590  
    1591         stream.open(filename.c_str()); 
    1592         stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl; 
    1593         stream << "<Visibility_Solution>" << endl; 
    1594  
    1595         //-- the view space bounding box 
    1596         stream << "<ViewSpaceBox"  
    1597                    << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\"" 
    1598                    << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl; 
    1599  
    1600         //-- the type of the view cells hierarchy 
    1601         //stream << "<Hierarchy name=\"bspTree\" />" << endl; 
    1602         stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free 
    1603         //-- load the view cells itself, i.e., the ids and the pvs 
    1604         stream << "<ViewCells>" << endl; 
    1605         ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 
    1606         for (it = mViewCells.begin(); it != it_end; ++ it) 
    1607                 ExportViewCell(*it, stream); 
    1608  
    1609         stream << "</ViewCells>" << endl; 
    1610  
    1611         //-- load the hierarchy 
    1612         stream << "<Hierarchy>" << endl; 
    1613         mBspTree->Export(stream); 
    1614         stream << endl << "</Hierarchy>" << endl; 
    1615  
    1616         stream << "</Visibility_Solution>" << endl; 
    1617         stream.close(); 
    1618  
    1619         cout << "finished" << endl; 
    1620  
    1621         return true; 
    1622 } 
    1623  
    1624  
    1625 void BspViewCellsManager::AddCurrentViewCellsToHierarchy() 
    1626 { 
    1627         ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 
    1628         for (it = mViewCells.begin(); it != it_end; ++ it) 
    1629         { 
    1630                 ViewCell *vc = *it; 
    1631                 ViewCellContainer leaves; 
    1632                 mViewCellsTree->CollectLeaves(vc, leaves); 
    1633                  
    1634                 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
    1635  
    1636                 for (lit = leaves.begin(); lit != lit_end; ++ lit) 
    1637                 { 
    1638                         BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit); 
    1639                         bspVc->mLeaf->SetViewCell(vc); 
    1640                 } 
    1641         } 
    1642 } 
    1643  
    1644 /************************************************************************/ 
    1645 /*                   KdViewCellsManager implementation                  */ 
    1646 /************************************************************************/ 
    1647  
    1648  
    1649  
    1650 KdViewCellsManager::KdViewCellsManager(KdTree *kdTree): 
    1651 ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100) 
    1652 { 
    1653 } 
    1654  
    1655 float KdViewCellsManager::GetProbability(ViewCell *viewCell) 
    1656 { 
    1657         // compute view cell area / volume as subsititute for probability 
    1658 #if 0 
    1659         return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 
    1660 #endif 
    1661 #if 1 
    1662         return GetArea(viewCell) / GetAccVcArea(); 
    1663 #endif 
    1664 #if 0 
    1665         return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 
    1666 #endif 
    1667 } 
    1668  
    1669  
    1670 float KdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const 
    1671 { 
    1672         return viewCell->GetPvs().GetSize() * objRendercost; 
    1673 } 
    1674  
    1675  
    1676 void KdViewCellsManager::CollectViewCells() 
    1677 { 
    1678         //mKdTree->CollectViewCells(mViewCells); TODO 
    1679 } 
    1680  
    1681  
    1682 int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 
    1683                                                                   const VssRayContainer &rays) 
    1684 { 
    1685         // if view cells already constructed 
    1686         if (ViewCellsConstructed()) 
    1687                 return 0; 
    1688  
    1689         mKdTree->Construct(); 
    1690  
    1691         mTotalAreaValid = false; 
    1692         // create the view cells 
    1693         mKdTree->CreateAndCollectViewCells(mViewCells); 
    1694  
    1695         // cast rays 
    1696         ComputeSampleContributions(rays, true, false); 
    1697  
    1698         EvaluateViewCellsStats(); 
    1699         Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 
    1700  
    1701         return 0; 
    1702 } 
    1703  
    1704  
    1705 bool KdViewCellsManager::ViewCellsConstructed() const 
    1706 { 
    1707         return mKdTree->GetRoot() != NULL; 
    1708 } 
    1709  
    1710 int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 
    1711                                                                         const VssRayContainer &rays) 
    1712 { 
    1713         return 0; 
    1714 } 
    1715  
    1716 void KdViewCellsManager::Visualize(const ObjectContainer &objects, 
    1717                                                                    const VssRayContainer &sampleRays) 
    1718 { 
    1719         if (!ViewCellsConstructed()) 
    1720                 return; 
    1721  
    1722         // using view cells instead of the kd PVS of objects 
    1723         const bool useViewCells = true; 
    1724         bool exportRays = false; 
    1725  
    1726         int limit = min(mVisualizationSamples, (int)sampleRays.size()); 
    1727         const int pvsOut = min((int)objects.size(), 10); 
    1728         VssRayContainer *rays = new VssRayContainer[pvsOut]; 
    1729  
    1730         if (useViewCells) 
    1731         { 
    1732                 const int leafOut = 10; 
    1733  
    1734                 ViewCell::NewMail(); 
    1735  
    1736                 //-- some rays for output 
    1737                 const int raysOut = min((int)sampleRays.size(), mVisualizationSamples); 
    1738                 Debug << "visualization using " << raysOut << " samples" << endl; 
    1739  
    1740                 //-- some random view cells and rays for output 
    1741                 vector<KdLeaf *> kdLeaves; 
    1742  
    1743                 for (int i = 0; i < leafOut; ++ i) 
    1744                         kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf())); 
    1745  
    1746                 for (int i = 0; i < kdLeaves.size(); ++ i) 
    1747                 { 
    1748                         KdLeaf *leaf = kdLeaves[i]; 
    1749                         RayContainer vcRays; 
    1750  
    1751                         cout << "creating output for view cell " << i << " ... "; 
    1752 #if 0 
    1753                         // check whether we can add the current ray to the output rays 
    1754                         for (int k = 0; k < raysOut; ++ k) 
    1755                         { 
    1756                                 Ray *ray = sampleRays[k]; 
    1757  
    1758                                 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 
    1759                                 { 
    1760                                         BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf; 
    1761  
    1762                                         if (leaf->GetViewCell() == leaf2->GetViewCell()) 
    1763                                         { 
    1764                                                 vcRays.push_back(ray); 
    1765                                         } 
    1766                                 } 
    1767                         } 
    1768 #endif 
    1769                         Intersectable::NewMail(); 
    1770  
    1771                         ViewCell *vc = leaf->mViewCell; 
    1772  
    1773                         //bspLeaves[j]->Mail(); 
    1774                         char s[64]; sprintf(s, "kd-pvs%04d.x3d", i); 
    1775  
    1776                         Exporter *exporter = Exporter::GetExporter(s); 
    1777                         exporter->SetFilled(); 
    1778  
    1779                         exporter->SetWireframe(); 
    1780                         //exporter->SetFilled(); 
    1781  
    1782                         Material m;//= RandomMaterial(); 
    1783                         m.mDiffuseColor = RgbColor(1, 1, 0); 
    1784                         exporter->SetForcedMaterial(m); 
    1785  
    1786                         AxisAlignedBox3 box = mKdTree->GetBox(leaf); 
    1787                         exporter->ExportBox(box); 
    1788  
    1789                         Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
    1790                                 << ", piercing rays=" << (int)vcRays.size() << endl; 
    1791  
    1792                         // export rays piercing this view cell 
    1793                         exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0)); 
    1794  
    1795                         m.mDiffuseColor = RgbColor(1, 0, 0); 
    1796                         exporter->SetForcedMaterial(m); 
    1797  
    1798                         // exporter->SetWireframe(); 
    1799                         exporter->SetFilled(); 
    1800  
    1801                         ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end(); 
    1802                         // output PVS of view cell 
    1803                         for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it) 
    1804                         { 
    1805                                 Intersectable *intersect = (*it).first; 
    1806                                 if (!intersect->Mailed()) 
    1807                                 { 
    1808                                         exporter->ExportIntersectable(intersect); 
    1809                                         intersect->Mail(); 
    1810                                 } 
    1811                         } 
    1812  
    1813                         DEL_PTR(exporter); 
    1814                         cout << "finished" << endl; 
    1815                 } 
    1816  
    1817                 DEL_PTR(rays); 
    1818         } 
    1819         else // using kd PVS of objects 
    1820         { 
    1821                 for (int i = 0; i < limit; ++ i) 
    1822                 { 
    1823                         VssRay *ray = sampleRays[i]; 
    1824  
    1825                         // check whether we can add this to the rays 
    1826                         for (int j = 0; j < pvsOut; j++) 
    1827                         { 
    1828                                 if (objects[j] == ray->mTerminationObject) 
    1829                                 { 
    1830                                         rays[j].push_back(ray); 
    1831                                 } 
    1832                         } 
    1833                 } 
    1834  
    1835                 if (exportRays) 
    1836                 { 
    1837                         Exporter *exporter = NULL; 
    1838                         exporter = Exporter::GetExporter("sample-rays.x3d"); 
    1839                         exporter->SetWireframe(); 
    1840                         exporter->ExportKdTree(*mKdTree); 
    1841  
    1842                         for (i=0; i < pvsOut; i++) 
    1843                                 exporter->ExportRays(rays[i], RgbColor(1, 0, 0)); 
    1844  
    1845                         exporter->SetFilled(); 
    1846  
    1847                         delete exporter; 
    1848                 } 
    1849  
    1850                 for (int k=0; k < pvsOut; k++) 
    1851                 { 
    1852                         Intersectable *object = objects[k]; 
    1853                         char s[64]; 
    1854                         sprintf(s, "sample-pvs%04d.x3d", k); 
    1855  
    1856                         Exporter *exporter = Exporter::GetExporter(s); 
    1857                         exporter->SetWireframe(); 
    1858  
    1859                         KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); 
    1860                         Intersectable::NewMail(); 
    1861  
    1862                         // avoid adding the object to the list 
    1863                         object->Mail(); 
    1864                         ObjectContainer visibleObjects; 
    1865  
    1866                         for (; i != object->mKdPvs.mEntries.end(); i++) 
    1867                         { 
    1868                                 KdNode *node = (*i).first; 
    1869                                 exporter->ExportBox(mKdTree->GetBox(node)); 
    1870  
    1871                                 mKdTree->CollectObjects(node, visibleObjects); 
    1872                         } 
    1873  
    1874                         exporter->ExportRays(rays[k],  RgbColor(0, 1, 0)); 
    1875                         exporter->SetFilled(); 
    1876  
    1877                         for (int j = 0; j < visibleObjects.size(); j++) 
    1878                                 exporter->ExportIntersectable(visibleObjects[j]); 
    1879  
    1880                         Material m; 
    1881                         m.mDiffuseColor = RgbColor(1, 0, 0); 
    1882                         exporter->SetForcedMaterial(m); 
    1883                         exporter->ExportIntersectable(object); 
    1884  
    1885                         delete exporter; 
    1886                 } 
    1887         } 
    1888 } 
    1889  
    1890  
    1891 void KdViewCellsManager::ExportColor(Exporter *exporter, 
    1892                                                                          ViewCell *vc) const 
    1893 { 
    1894         // TODO 
    1895 } 
    1896  
    1897 ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const 
    1898 { 
    1899         return new KdViewCell(mesh); 
    1900 } 
    1901  
    1902  
    1903 void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
    1904                                                                                                 ViewCell *vc, 
    1905                                                                                                 const Plane3 *cuttingPlane) const 
    1906 { 
    1907         ViewCellContainer leaves; 
    1908  
    1909         mViewCellsTree->CollectLeaves(vc, leaves); 
    1910         ViewCellContainer::const_iterator it, it_end = leaves.end(); 
    1911  
    1912         for (it = leaves.begin(); it != it_end; ++ it) 
    1913         { 
    1914                 KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it); 
    1915          
    1916                 exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf)); 
    1917         } 
    1918 } 
    1919  
    1920  
    1921 int KdViewCellsManager::GetType() const 
    1922 { 
    1923         return ViewCellsManager::KD; 
    1924 } 
    1925  
    1926  
    1927  
    1928 KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf) 
    1929 { 
    1930         KdNode *node = leaf; 
    1931  
    1932         while (node->mParent && node->mDepth > mKdPvsDepth) 
    1933                 node = node->mParent; 
    1934         return node; 
    1935 } 
    1936  
    1937 int KdViewCellsManager::CastLineSegment(const Vector3 &origin, 
    1938                                                                                 const Vector3 &termination, 
    1939                                                                                 ViewCellContainer &viewcells) 
    1940 { 
    1941         return mKdTree->CastLineSegment(origin, termination, viewcells); 
    1942 } 
    1943  
    1944  
    1945 void KdViewCellsManager::CreateMesh(ViewCell *vc) 
    1946 { 
    1947         // TODO 
    1948 } 
    1949  
    1950  
    1951  
    1952 void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
    1953                                                                                                 vector<MergeCandidate> &candidates) 
    1954 { 
    1955         // TODO 
    1956 } 
    1957  
    1958  
    1959 /**********************************************************************/ 
    1960 /*                   VspKdViewCellsManager implementation             */ 
    1961 /**********************************************************************/ 
    1962  
    1963  
    1964 VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree): 
    1965 ViewCellsManager(), mVspKdTree(vspKdTree) 
    1966 { 
    1967         environment->GetIntValue("VspKdTree.Construction.samples", mInitialSamples); 
    1968         mVspKdTree->SetViewCellsManager(this); 
    1969 } 
    1970  
    1971 float VspKdViewCellsManager::GetProbability(ViewCell *viewCell) 
    1972 { 
    1973         // volume or area substitutes for view point probability 
    1974 #if 0 
    1975         return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 
    1976 #else 
    1977         return GetArea(viewCell) / GetAccVcArea(); 
    1978 #endif 
    1979 } 
    1980  
    1981  
    1982 float VspKdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const 
    1983 { 
    1984         return viewCell->GetPvs().GetSize() * objRendercost; 
    1985 } 
    1986  
    1987  
    1988 void VspKdViewCellsManager::CollectViewCells() 
    1989 { 
    1990         mVspKdTree->CollectViewCells(mViewCells); 
    1991 } 
    1992  
    1993  
    1994 int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 
    1995                                                                                                 const VssRayContainer &rays) 
    1996 { 
    1997         // if view cells already constructed 
    1998         if (ViewCellsConstructed()) 
    1999                 return 0; 
    2000  
    2001         VssRayContainer constructionRays; 
    2002         VssRayContainer savedRays; 
    2003  
    2004         GetRaySets(rays, 
    2005                            mInitialSamples, 
    2006                            constructionRays, 
    2007                            &savedRays); 
    2008  
    2009         Debug << "constructing vsp kd tree using " 
    2010                   << (int)constructionRays.size() << " samples" << endl; 
    2011  
    2012         mVspKdTree->Construct(constructionRays, &mViewSpaceBox); 
    2013         Debug << mVspKdTree->GetStatistics() << endl; 
    2014  
    2015         // export leaf building blocks 
    2016         ExportLeaves(objects, rays); 
    2017  
    2018         // finally merge kd leaf building blocks to view cells 
    2019         const int merged = mVspKdTree->MergeViewCells(rays); 
    2020  
    2021         // collapse siblings belonging to the same view cell 
    2022         mVspKdTree->RefineViewCells(rays); 
    2023  
    2024         // collapse siblings belonging to the same view cell 
    2025         mVspKdTree->CollapseTree(); 
    2026  
    2027         // evaluale view cell stats 
    2028         ResetViewCells(); 
    2029  
    2030         Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 
    2031  
    2032         long startTime = GetTime(); 
    2033         // recast rest of rays 
    2034         ComputeSampleContributions(savedRays, true, false); 
    2035  
    2036         Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 
    2037                   << " secs" << endl; 
    2038  
    2039         return merged; 
    2040 } 
    2041  
    2042 bool VspKdViewCellsManager::ViewCellsConstructed() const 
    2043 { 
    2044         return mVspKdTree->GetRoot() != NULL; 
    2045 } 
    2046  
    2047  
    2048 ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const 
    2049 { 
    2050         return new VspKdViewCell(mesh); 
    2051 } 
    2052  
    2053 int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects, 
    2054                                                                            const VssRayContainer &rays) 
    2055 { 
    2056         if (!ViewCellsConstructed()) 
    2057                 return 0; 
    2058  
    2059         // recalculate stats 
    2060         EvaluateViewCellsStats(); 
    2061  
    2062         return 0; 
    2063 } 
    2064  
    2065  
    2066 void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects, 
    2067                                                                                  const VssRayContainer &sampleRays) 
    2068 { 
    2069         if (!ViewCellsConstructed()) 
    2070                 return; 
    2071  
    2072         //-- export leaf building blocks 
    2073         Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d"); 
    2074         if (!exporter) 
    2075                 return; 
    2076  
    2077         if (mExportGeometry) 
    2078                 exporter->ExportGeometry(objects); 
    2079          
    2080         //exporter->SetWireframe(); 
    2081         //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize); 
    2082         exporter->ExportVspKdTree(*mVspKdTree); 
    2083  
    2084         if (mExportRays) 
    2085         { 
    2086                 const float prob = (float)mVisualizationSamples 
    2087                         / ((float)sampleRays.size() + Limits::Small); 
    2088  
    2089                 exporter->SetWireframe(); 
    2090  
    2091                 //-- collect uniformly distributed rays 
    2092                 VssRayContainer rays; 
    2093  
    2094                 for (int i = 0; i < sampleRays.size(); ++ i) 
    2095                 { 
    2096                         if (RandomValue(0,1) < prob) 
    2097                                 rays.push_back(sampleRays[i]); 
    2098                 } 
    2099                 exporter->ExportRays(rays, RgbColor(1, 0, 0)); 
    2100         } 
    2101  
    2102         delete exporter; 
    2103 } 
    2104  
    2105 void VspKdViewCellsManager::Visualize(const ObjectContainer &objects, 
    2106                                                                           const VssRayContainer &sampleRays) 
    2107 { 
    2108         if (!ViewCellsConstructed()) 
    2109                 return; 
    2110  
    2111         //-- export single view cells 
    2112         for (int i = 0; i < 10; ++ i) 
    2113         { 
    2114                 char s[64]; 
    2115                 sprintf(s, "vsp_viewcell%04d.x3d", i); 
    2116                 Exporter *exporter = Exporter::GetExporter(s); 
    2117                 const int idx = 
    2118                         (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1)); 
    2119  
    2120                 VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]); 
    2121  
    2122                 cout << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl; 
    2123                 Debug << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl; 
    2124                 //-- export geometry 
    2125                 Material m; 
    2126                 m.mDiffuseColor = RgbColor(0, 1, 1); 
    2127  
    2128                 exporter->SetForcedMaterial(m); 
    2129                 exporter->SetWireframe(); 
    2130  
    2131                 ExportViewCellGeometry(exporter, vc); 
    2132  
    2133                 //-- export stored rays 
    2134                  
    2135                 if (mExportRays) 
    2136                 { 
    2137                         ViewCellContainer leaves; 
    2138                         mViewCellsTree->CollectLeaves(vc, leaves); 
    2139  
    2140                         ViewCellContainer::const_iterator it, 
    2141                                 it_end = leaves.end(); 
    2142  
    2143                         for (it = leaves.begin(); it != it_end; ++ it) 
    2144                         { 
    2145                                 VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it); 
    2146                                 VspKdLeaf *leaf = vspKdVc->mLeaf; 
    2147                                 AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf); 
    2148  
    2149                                 VssRayContainer vssRays; 
    2150  
    2151                                 VssRayContainer castRays; 
    2152                                 VssRayContainer initRays; 
    2153  
    2154                                 leaf->GetRays(vssRays); 
    2155  
    2156                                 VssRayContainer::const_iterator it, it_end = vssRays.end(); 
    2157                                 const float prop = 200.0f / (float)vssRays.size(); 
    2158  
    2159                                 for (it = vssRays.begin(); it != it_end; ++ it) 
    2160                                 { 
    2161                                         if (Random(1) < prop) 
    2162                                                 if ((*it)->mTerminationObject == NULL) 
    2163                                                         castRays.push_back(*it); 
    2164                                                 else 
    2165                                                         initRays.push_back(*it); 
    2166                                 } 
    2167  
    2168                                 exporter->ExportRays(castRays, RgbColor(1, 0, 0)); 
    2169                                 exporter->ExportRays(initRays, RgbColor(0, 1, 0)); 
    2170                         } 
    2171                 } 
    2172          
    2173                 //-- output PVS of view cell 
    2174                 m.mDiffuseColor = RgbColor(1, 0, 0); 
    2175                 exporter->SetForcedMaterial(m); 
    2176  
    2177                 Intersectable::NewMail(); 
    2178  
    2179                 ObjectPvsMap::const_iterator it, 
    2180                         it_end = vc->GetPvs().mEntries.end(); 
    2181  
    2182                 exporter->SetFilled(); 
    2183  
    2184                 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
    2185                 { 
    2186                         Intersectable *intersect = (*it).first; 
    2187  
    2188                         if (!intersect->Mailed()) 
    2189                         { 
    2190                                 Material m = RandomMaterial(); 
    2191                                 exporter->SetForcedMaterial(m); 
    2192  
    2193                                 exporter->ExportIntersectable(intersect); 
    2194                                 intersect->Mail(); 
    2195                         } 
    2196                 } 
    2197  
    2198                 delete exporter; 
    2199         } 
    2200  
    2201         //-- export final view cells 
    2202         Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d"); 
    2203  
    2204         //if (exportGeometry) exporter->SetWireframe(); 
    2205         //else exporter->SetFilled(); 
    2206  
    2207         ExportViewCellsForViz(exporter); 
    2208  
    2209         if (mExportGeometry) 
    2210         { 
    2211                 exporter->SetFilled(); 
    2212                 exporter->ExportGeometry(objects); 
    2213         } 
    2214  
    2215         if (mExportRays) 
    2216         { 
    2217                 const float prob = (float)mVisualizationSamples 
    2218                         / ((float)sampleRays.size() + Limits::Small); 
    2219  
    2220                 exporter->SetWireframe(); 
    2221  
    2222                 VssRayContainer rays; 
    2223  
    2224                 for (int i = 0; i < sampleRays.size(); ++ i) 
    2225                 { 
    2226                   if (RandomValue(0,1) < prob) 
    2227                         rays.push_back(sampleRays[i]); 
    2228                 } 
    2229                 exporter->ExportRays(rays, RgbColor(1, 0, 0)); 
    2230         } 
    2231  
    2232         delete exporter; 
    2233 } 
    2234  
    2235 int VspKdViewCellsManager::GetType() const 
    2236 { 
    2237         return VSP_KD; 
    2238 } 
    2239  
    2240  
    2241 int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin, 
    2242                                                                                    const Vector3 &termination, 
    2243                                                                                    ViewCellContainer &viewcells) 
    2244 { 
    2245         return mVspKdTree->CastLineSegment(origin, termination, viewcells); 
    2246 } 
    2247  
    2248  
    2249 void VspKdViewCellsManager::ExportColor(Exporter *exporter, 
    2250                                                                                 ViewCell *vc) const 
    2251 { 
    2252         if (mColorCode == 0) // Random color 
    2253                 return; 
    2254  
    2255         float importance = 0; 
    2256  
    2257         switch (mColorCode) 
    2258         { 
    2259         case 1: // pvs 
    2260                 { 
    2261                         importance = (float)vc->GetPvs().GetSize() / 
    2262                                 (float)mViewCellsStats.maxPvs; 
    2263                 } 
    2264                 break; 
    2265         case 2: // merged leaves 
    2266                 { 
    2267                 int lSize = mViewCellsTree->GetSize(vc); 
    2268                         importance = (float)lSize / 
    2269                                 (float)mViewCellsStats.maxLeaves; 
    2270                 } 
    2271                 break; 
    2272         case 3: // merged tree depth difference 
    2273                 { 
    2274                         //importance = (float)GetMaxTreeDiff(vc) / 
    2275                         //      (float)(mVspBspTree->GetStatistics().maxDepth * 2); 
    2276                 } 
    2277                 break; 
    2278         default: 
    2279                 break; 
    2280         } 
    2281  
    2282         Material m; 
    2283         m.mDiffuseColor.b = 1.0f; 
    2284         m.mDiffuseColor.r = importance; 
    2285         m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 
    2286         //Debug << "importance: " << importance << endl; 
    2287         exporter->SetForcedMaterial(m); 
    2288 } 
    2289  
    2290  
    2291 void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
    2292                                                                                                    ViewCell *vc, 
    2293                                                                                                    const Plane3 *cuttingPlane) const 
    2294 { 
    2295         VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc); 
    2296  
    2297         Mesh m; 
    2298  
    2299         ViewCellContainer leaves; 
    2300         mViewCellsTree->CollectLeaves(vc, leaves); 
    2301  
    2302         ViewCellContainer::const_iterator it, it_end = leaves.end(); 
    2303  
    2304         for (it = leaves.begin(); it != it_end; ++ it) 
    2305         { 
    2306                 VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf; 
    2307                 mVspKdTree->GetBBox(l).AddBoxToMesh(&m); 
    2308         } 
    2309  
    2310         exporter->ExportMesh(&m); 
    2311 } 
    2312  
    2313  
    2314 void VspKdViewCellsManager::CreateMesh(ViewCell *vc) 
    2315 { 
    2316         //TODO 
    2317 } 
    2318  
    2319  
    2320 void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
    2321                                                                                                    vector<MergeCandidate> &candidates) 
    2322 { 
    2323         // TODO 
    2324 } 
    2325  
    2326  
    2327 /**************************************************************************/ 
    2328 /*                   VspBspViewCellsManager implementation                */ 
    2329 /**************************************************************************/ 
    2330  
    2331  
    2332 VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree): 
    2333 ViewCellsManager(), mVspBspTree(vspBspTree) 
    2334 { 
    2335         environment->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 
    2336         mVspBspTree->SetViewCellsManager(this); 
    2337         mVspBspTree->mViewCellsTree = mViewCellsTree; 
    2338 } 
    2339  
    2340  
    2341 VspBspViewCellsManager::~VspBspViewCellsManager() 
    2342 { 
    2343 } 
    2344  
    2345  
    2346 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell) 
    2347 { 
    2348         if (0 && mVspBspTree->mUseAreaForPvs) 
    2349                 return GetArea(viewCell) / GetAccVcArea(); 
    2350         else 
    2351                 return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 
    2352 } 
    2353  
    2354  
    2355 void VspBspViewCellsManager::CollectViewCells() 
    2356 { 
    2357         // view cells tree constructed 
    2358         if (!ViewCellsTreeConstructed()) 
    2359         { 
    2360                 mVspBspTree->CollectViewCells(mViewCells, false); 
    2361         } 
    2362         else  
    2363         { 
    2364                 // we can use the view cells tree hierarchy to get the right set 
    2365                 mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumMergedViewCells); 
    2366         } 
    2367  
    2368 } 
    2369  
    2370  
    2371 float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell, 
    2372                                                                                         float objRendercost) const 
    2373 { 
    2374         return viewCell->GetPvs().GetSize() * objRendercost; 
    2375 } 
    2376  
    2377  
    2378 bool VspBspViewCellsManager::ViewCellsConstructed() const 
    2379 { 
    2380         return mVspBspTree->GetRoot() != NULL; 
    2381 } 
    2382  
    2383  
    2384 ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const 
    2385 { 
    2386         return new BspViewCell(mesh); 
    2387 } 
    2388  
    2389  
    2390 int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 
    2391                                                                           const VssRayContainer &rays) 
    2392 { 
    2393         // if view cells were already constructed 
    2394         if (ViewCellsConstructed()) 
    2395                 return 0; 
    2396  
    2397         Debug << "Constructing bsp view cells" << endl; 
    2398  
    2399         int sampleContributions = 0; 
    2400  
    2401         VssRayContainer sampleRays; 
    2402  
    2403         int limit = min (mInitialSamples, (int)rays.size()); 
    2404  
    2405         VssRayContainer constructionRays; 
    2406         VssRayContainer savedRays; 
    2407  
    2408         Debug << "samples used for subdivision: " << mInitialSamples  
    2409                   << " rays: " << (int)rays.size() << endl; 
    2410  
    2411         GetRaySets(rays, mInitialSamples, constructionRays, &savedRays); 
    2412  
    2413         Debug << "initial rays: " << (int)constructionRays.size() << endl; 
    2414         Debug << "saved rays: " << (int)savedRays.size() << endl; 
    2415  
    2416         mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size()); 
    2417  
    2418         mVspBspTree->Construct(constructionRays, &mViewSpaceBox); 
    2419  
    2420         Debug << mVspBspTree->GetStatistics() << endl; 
    2421  
    2422         // collapse invalid regions 
    2423         cout << "collapsing invalid tree regions ... "; 
    2424         long startTime = GetTime(); 
    2425         int collapsedLeaves = mVspBspTree->CollapseTree(); 
    2426         Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3  
    2427                   << " seconds" << endl; 
    2428  
    2429     cout << "finished" << endl; 
    2430  
    2431         cout << "reseting view cell stats ... "; 
    2432         ResetViewCells(); 
    2433         cout << "finished" << endl; 
    2434  
    2435         Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 
    2436  
    2437         if (1) // export initial view cells 
    2438         { 
    2439                 cout << "exporting initial view cells (=leaves) ... "; 
    2440                 Exporter *exporter = Exporter::GetExporter("view_cells.x3d"); 
    2441  
    2442                 if (exporter) 
    2443                 { 
    2444                         if (0 && mExportRays) 
    2445                                 exporter->ExportRays(rays, RgbColor(1, 1, 1)); 
    2446  
    2447                         if (mExportGeometry) 
    2448                                 exporter->ExportGeometry(objects); 
    2449  
    2450                         //exporter->SetWireframe(); 
    2451                         exporter->SetFilled(); 
    2452                         ExportViewCellsForViz(exporter); 
    2453  
    2454                         delete exporter; 
    2455                 } 
    2456                 cout << "finished" << endl; 
    2457         } 
    2458  
    2459         startTime = GetTime(); 
    2460  
    2461         // reset view cells and stats 
    2462         ResetViewCells(); 
    2463  
    2464         cout << "Computing remaining ray contributions ... "; 
    2465         // recast rest of rays 
    2466         ComputeSampleContributions(savedRays, true, false); 
    2467         cout << "finished" << endl; 
    2468  
    2469         Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 
    2470                   << " secs" << endl; 
    2471  
    2472         cout << "construction finished" << endl; 
    2473  
    2474         return sampleContributions; 
    2475 } 
    2476  
    2477  
    2478 void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays, 
    2479                                                                                         const ObjectContainer &objects) 
    2480 { 
    2481         //-- post processing of bsp view cells 
    2482     int vcSize = 0; 
    2483         int pvsSize = 0; 
    2484  
    2485         mRenderer->RenderScene(); 
    2486         SimulationStatistics ss; 
    2487         dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 
    2488     Debug << ss << endl; 
    2489  
    2490         //-- merge or subdivide view cells 
    2491         int merged = 0; 
    2492         if (mMergeViewCells) 
    2493         { 
    2494                 cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl; 
    2495                 long startTime = GetTime(); 
    2496  
    2497          
    2498                 // TODO: should be done BEFORE the ray casting 
    2499                 merged = mViewCellsTree->ConstructMergeTree(rays, objects); 
    2500  
    2501                 //-- stats and visualizations 
    2502                 cout << "finished merging" << endl; 
    2503                 cout << "merged " << merged << " view cells in " 
    2504                          << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 
    2505  
    2506                 Debug << "Postprocessing: Merged " << merged << " view cells in " 
    2507                           << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 
    2508         } 
    2509  
    2510         //BspLeaf::NewMail(); 
    2511         if (1) // export merged view cells 
    2512         { 
    2513                 cout << "reseting view cells ... "; 
    2514                 ResetViewCells(); 
    2515  
    2516                 cout << "finished" << endl; 
    2517  
    2518                 Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 
    2519                 Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 
    2520  
    2521                 cout << "exporting view cells after merge ... "; 
    2522  
    2523                 if (exporter) 
    2524                 { 
    2525                         if (mExportGeometry) 
    2526                         { 
    2527                                 Material m; 
    2528                                 m.mDiffuseColor = RgbColor(0, 1, 0); 
    2529                                 exporter->SetForcedMaterial(m); 
    2530                                 exporter->SetFilled(); 
    2531  
    2532                                 exporter->ExportGeometry(objects); 
    2533                         } 
    2534  
    2535                         if (0) 
    2536                                 exporter->SetWireframe(); 
    2537                         else 
    2538                                 exporter->SetFilled(); 
    2539  
    2540                         ExportViewCellsForViz(exporter); 
    2541  
    2542                         delete exporter; 
    2543                 } 
    2544                 cout << "finished" << endl; 
    2545         } 
    2546 } 
    2547  
    2548  
    2549 void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays, 
    2550                                                                                          const ObjectContainer &objects) 
    2551 { 
    2552         Debug << "render time before refine:" << endl; 
    2553         mRenderer->RenderScene(); 
    2554         SimulationStatistics ss; 
    2555         dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 
    2556     Debug << ss << endl; 
    2557  
    2558         cout << "Refining the merged view cells ... "; 
    2559         long startTime = GetTime(); 
    2560  
    2561         // refining the merged view cells 
    2562         const int refined = mViewCellsTree->RefineViewCells(rays, objects); 
    2563  
    2564         //-- stats and visualizations 
    2565         cout << "finished" << endl; 
    2566         cout << "refined " << refined << " view cells in " 
    2567                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 
    2568  
    2569         Debug << "Postprocessing: refined " << refined << " view cells in " 
    2570                   << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 
    2571 } 
    2572  
    2573  
    2574 int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects, 
    2575                                                                                 const VssRayContainer &rays) 
    2576 { 
    2577         if (!ViewCellsConstructed()) 
    2578         { 
    2579                 Debug << "postprocess error: no view cells constructed" << endl; 
    2580                 return 0; 
    2581         } 
    2582  
    2583  
    2584         // view cells already finished before post processing step (i.e. because they were loaded) 
    2585         if (mViewCellsFinished) 
    2586         { 
    2587                 FinalizeViewCells(true); 
    2588                 EvaluateViewCellsStats(); 
    2589  
    2590                 return 0; 
    2591         } 
    2592  
    2593  
    2594         // check if new view cells turned invalid 
    2595         SetValidity(mMinPvsSize, mMaxPvsSize);  
    2596         // update valid view space according to valid view cells 
    2597         mVspBspTree->ValidateTree(); 
    2598  
    2599         // recompute view cell statistics 
    2600         mViewCellsStats.Reset(); 
    2601         EvaluateViewCellsStats(); 
    2602  
    2603         // has to be recomputed 
    2604         mTotalAreaValid = false; 
    2605  
    2606  
    2607         VssRayContainer postProcessRays; 
    2608         GetRaySets(rays, mPostProcessSamples, postProcessRays); 
    2609  
    2610         Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl; 
    2611  
    2612         Debug << "\nview cell partition after sampling:\n" << mViewCellsStats << endl << endl; 
    2613  
    2614         // should maybe be done here to allow merge working with area or volume 
    2615         // and to correct the rendering statistics 
    2616         if (0) 
    2617         { 
    2618                 FinalizeViewCells(false); 
    2619         } 
    2620  
    2621         //-- merge the individual view cells 
    2622         MergeViewCells(postProcessRays, objects); 
    2623          
    2624  
    2625         //-- refines the merged view cells 
    2626         if (0) 
    2627                 RefineViewCells(postProcessRays, objects); 
    2628  
    2629         //-- compression 
    2630  
    2631         if (ViewCellsTreeConstructed() && mCompressViewCells) 
    2632         { 
    2633                 int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 
    2634                 Debug << "number of entries before compress: " << pvsEntries << endl; 
    2635  
    2636                 mViewCellsTree->CompressViewCellsPvs(); 
    2637  
    2638                 pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 
    2639                 Debug << "number of entries after compress: " << pvsEntries << endl; 
    2640         } 
    2641  
    2642         if (1) 
    2643         {                
    2644                 float totalCost, erc, var, dev, avg; 
    2645                 int totalpvs; 
    2646  
    2647                 mViewCellsStats.Reset(); 
    2648  
    2649         EvaluateRenderStatistics(totalCost, erc, dev, var, totalpvs, avg); 
    2650                  
    2651                 Debug << "statistics after merge "   
    2652                           << " erc: " << erc  
    2653                           << " dev: " << dev 
    2654                           << " totalpvs: " << totalpvs  
    2655                           << " avg: " << avg << endl; 
    2656         } 
    2657  
    2658  
    2659         //-- export refined (shuffled) view cells 
    2660         if (0) 
    2661         { 
    2662                 cout << "exporting shuffled view cells ... "; 
    2663  
    2664                 Exporter *exporter = Exporter::GetExporter("shuffled_view_cells.x3d"); 
    2665                 if (exporter) 
    2666                 { 
    2667                         if (1) 
    2668                         { 
    2669                                 exporter->SetWireframe(); 
    2670                                 exporter->ExportBox(mViewSpaceBox); 
    2671                                 exporter->SetFilled(); 
    2672                         } 
    2673  
    2674                         if (mExportGeometry) 
    2675                         { 
    2676                                 exporter->ExportGeometry(objects); 
    2677                         } 
    2678  
    2679                         ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 
    2680  
    2681                         Material vm, lm; 
    2682  
    2683                         for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 
    2684                         { 
    2685                                 ViewCell *vc = *vit; 
    2686  
    2687                                 vm = RandomMaterial(); 
    2688  
    2689                                 lm = vm; 
    2690  
    2691                                 vm.mDiffuseColor.r -= 0.45f; 
    2692                                 vm.mDiffuseColor.g -= 0.45f; 
    2693                                 vm.mDiffuseColor.b -= 0.45f; 
    2694  
    2695  
    2696                                 ViewCellContainer leaves; 
    2697                                 mViewCellsTree->CollectLeaves(vc, leaves); 
    2698  
    2699                                 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
    2700  
    2701                                 for (lit = leaves.begin(); lit != lit_end; ++ lit) 
    2702                                 { 
    2703                                         BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 
    2704  
    2705                                         if (leaf->Mailed()) 
    2706                                                 exporter->SetForcedMaterial(lm); 
    2707                                         else 
    2708                                                 exporter->SetForcedMaterial(vm); 
    2709  
    2710                                         BspNodeGeometry geom; 
    2711                                         mVspBspTree->ConstructGeometry(leaf, geom); 
    2712                                         exporter->ExportPolygons(geom.mPolys); 
    2713                                 } 
    2714                         } 
    2715  
    2716                         delete exporter; 
    2717                 } 
    2718  
    2719  
    2720                 cout << "finished" << endl; 
    2721         } 
    2722  
    2723         // collapse sibling leaves that share the same view cell 
    2724         if (0) 
    2725                 mVspBspTree->CollapseTree(); 
    2726  
    2727         // recompute view cell list and statistics 
    2728         ResetViewCells(); 
    2729  
    2730         // real meshes are only contructed only at this stage 
    2731         FinalizeViewCells(true); 
    2732  
    2733         // write view cells to disc 
    2734         if (mExportViewCells) 
    2735         { 
    2736                 char buff[100]; 
    2737                 environment->GetStringValue("ViewCells.filename", buff); 
    2738                 string vcFilename(buff); 
    2739  
    2740                 ExportViewCells(buff); 
    2741         } 
    2742  
    2743         return 0; 
    2744 } 
    2745  
    2746  
    2747 int VspBspViewCellsManager::GetType() const 
    2748 { 
    2749         return VSP_BSP; 
    2750 } 
    2751  
    2752  
    2753 bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const 
    2754 { 
    2755         if (!ViewCellsConstructed()) 
    2756                 return ViewCellsManager::GetViewPoint(viewPoint); 
    2757  
    2758         // TODO: set reasonable limit 
    2759         const int limit = 20; 
    2760  
    2761         for (int i = 0; i < limit; ++ i) 
    2762         { 
    2763                 viewPoint = mViewSpaceBox.GetRandomPoint(); 
    2764                 if (mVspBspTree->ViewPointValid(viewPoint)) 
    2765                 { 
    2766                         return true; 
    2767                 } 
    2768         } 
    2769         Debug << "failed to find valid view point, taking " << viewPoint << endl; 
    2770         return false; 
    2771 } 
    2772  
    2773  
    2774 bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const 
    2775 { 
    2776   // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic 
    2777   // validy update in preprocessor for all managers) 
    2778   return ViewCellsManager::ViewPointValid(viewPoint); 
    2779  
    2780   //    return mViewSpaceBox.IsInside(viewPoint) && 
    2781   //               mVspBspTree->ViewPointValid(viewPoint); 
    2782 } 
    2783  
    2784  
    2785 void VspBspViewCellsManager::Visualize(const ObjectContainer &objects, 
    2786                                                                            const VssRayContainer &sampleRays) 
    2787 { 
    2788         if (!ViewCellsConstructed()) 
    2789                 return; 
    2790  
    2791         VssRayContainer visRays; 
    2792         GetRaySets(sampleRays, mVisualizationSamples, visRays); 
    2793  
    2794         if (1) // export view cells 
    2795         { 
    2796                 Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 
    2797  
    2798                 if (exporter) 
    2799                 { 
    2800                         cout << "exporting view cells after post process ... "; 
    2801  
    2802                         if (1) 
    2803                         { 
    2804                                 exporter->SetWireframe(); 
    2805                                 exporter->ExportBox(mViewSpaceBox); 
    2806                                 exporter->SetFilled(); 
    2807                         } 
    2808  
    2809                         if (mExportGeometry) 
    2810                         { 
    2811                                 exporter->ExportGeometry(objects); 
    2812                         } 
    2813  
    2814                         // export rays 
    2815                         if (mExportRays) 
    2816                         { 
    2817                                 exporter->ExportRays(visRays, RgbColor(0, 1, 0)); 
    2818                         } 
    2819  
    2820                         ExportViewCellsForViz(exporter); 
    2821                         delete exporter; 
    2822                         cout << "finished" << endl; 
    2823                 } 
    2824         } 
    2825  
    2826         if (1) 
    2827         { 
    2828                 cout << "exporting depth map ... "; 
    2829  
    2830                 Exporter *exporter = Exporter::GetExporter("depth_map.x3d"); 
    2831                 if (exporter) 
    2832                 { 
    2833                         if (1) 
    2834                         { 
    2835                                 exporter->SetWireframe(); 
    2836                                 exporter->ExportBox(mViewSpaceBox); 
    2837                                 exporter->SetFilled(); 
    2838                         } 
    2839  
    2840                         if (mExportGeometry) 
    2841                         { 
    2842                                 exporter->ExportGeometry(objects); 
    2843                         } 
    2844  
    2845                         const int maxDepth = mVspBspTree->mBspStats.maxDepth; 
    2846  
    2847                         ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 
    2848  
    2849                         for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 
    2850                         { 
    2851                                 ViewCell *vc = *vit; 
    2852  
    2853                                 ViewCellContainer leaves; 
    2854                                 mViewCellsTree->CollectLeaves(vc, leaves); 
    2855  
    2856                                 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
    2857  
    2858                                 for (lit = leaves.begin(); lit != lit_end; ++ lit) 
    2859                                 { 
    2860                                         BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 
    2861  
    2862                                         Material m;  
    2863  
    2864                                         float relDepth = (float)leaf->GetDepth() / (float)maxDepth; 
    2865                                         m.mDiffuseColor.r = relDepth; 
    2866                                         m.mDiffuseColor.g = 0.0f; 
    2867                                         m.mDiffuseColor.b = 1.0f - relDepth; 
    2868  
    2869                     exporter->SetForcedMaterial(m); 
    2870                                  
    2871  
    2872                                         BspNodeGeometry geom; 
    2873                                         mVspBspTree->ConstructGeometry(leaf, geom); 
    2874                                         exporter->ExportPolygons(geom.mPolys); 
    2875                                 } 
    2876                         } 
    2877  
    2878                         delete exporter; 
    2879                 } 
    2880  
    2881  
    2882                 cout << "finished" << endl; 
    2883         } 
    2884  
    2885         //-- visualization of the BSP splits 
    2886         bool exportSplits = false; 
    2887         environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits); 
    2888  
    2889         if (exportSplits) 
    2890         { 
    2891                 cout << "exporting splits ... "; 
    2892                 ExportSplits(objects, visRays); 
    2893                 cout << "finished" << endl; 
    2894         } 
    2895  
    2896         //-- export single view cells 
    2897         ExportBspPvs(objects, visRays); 
    2898 } 
    2899  
    2900  
    2901 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects, 
    2902                                                                                   const VssRayContainer &rays) 
    2903 { 
    2904         Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 
    2905  
    2906         if (exporter) 
    2907         { 
    2908                 Material m; 
    2909                 m.mDiffuseColor = RgbColor(1, 0, 0); 
    2910                 exporter->SetForcedMaterial(m); 
    2911                 exporter->SetWireframe(); 
    2912  
    2913                 exporter->ExportBspSplits(*mVspBspTree, true); 
    2914  
    2915                 // take forced material, else big scenes cannot be viewed 
    2916                 m.mDiffuseColor = RgbColor(0, 1, 0); 
    2917                 exporter->SetForcedMaterial(m); 
    2918                 exporter->SetFilled(); 
    2919  
    2920                 exporter->ResetForcedMaterial(); 
    2921  
    2922                 // export rays 
    2923                 if (mExportRays) 
    2924                         exporter->ExportRays(rays, RgbColor(1, 1, 0)); 
    2925  
    2926                 if (mExportGeometry) 
    2927                         exporter->ExportGeometry(objects); 
    2928  
    2929                 delete exporter; 
    2930         } 
    2931 } 
    2932  
    2933  
    2934 void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects, 
    2935                                                                                   const VssRayContainer &rays) 
    2936 { 
    2937         const int leafOut = 10; 
    2938  
    2939         ViewCell::NewMail(); 
    2940  
    2941         cout << "visualization using " << mVisualizationSamples << " samples" << endl; 
    2942         Debug << "\nOutput view cells: " << endl; 
    2943  
    2944         // sort view cells to visualize the largest view cells 
    2945         if (0) 
    2946                 stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt); 
    2947  
    2948         int limit = min(leafOut, (int)mViewCells.size()); 
    2949  
    2950         int raysOut; 
    2951  
    2952         //-- some rays for output 
    2953         if (1) 
    2954                 raysOut = min((int)rays.size(), mVisualizationSamples); 
    2955  
    2956         for (int i = 0; i < limit; ++ i) 
    2957         { 
    2958                 cout << "creating output for view cell " << i << " ... "; 
    2959  
    2960                 VssRayContainer vcRays; 
    2961                 Intersectable::NewMail(); 
    2962                 ViewCell *vc; 
    2963          
    2964                 if (0) // largest view cell pvs first 
    2965                         vc = mViewCells[i]; 
    2966                 else 
    2967                         vc = mViewCells[Random((int)mViewCells.size())]; 
    2968  
    2969                 vector<ViewCell *> leaves; 
    2970                 mViewCellsTree->CollectLeaves(vc, leaves); 
    2971  
    2972         if (1) 
    2973                 { 
    2974                         // check whether we can add the current ray to the output rays 
    2975                         for (int k = 0; k < raysOut; ++ k) 
    2976                         { 
    2977                                 VssRay *ray = rays[k]; 
    2978                                 for     (int j = 0; j < (int)ray->mViewCells.size(); ++ j) 
    2979                                 { 
    2980                                         ViewCell *rayvc = ray->mViewCells[j]; 
    2981  
    2982                                         if (leaves[0] == rayvc) 
    2983                                                 vcRays.push_back(ray); 
    2984                                 } 
    2985                         } 
    2986                 } 
    2987  
    2988                 //bspLeaves[j]->Mail(); 
    2989                 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 
    2990                 Exporter *exporter = Exporter::GetExporter(s); 
    2991                 exporter->SetWireframe(); 
    2992  
    2993                 Material m;//= RandomMaterial(); 
    2994                 m.mDiffuseColor = RgbColor(0, 1, 0); 
    2995                 exporter->SetForcedMaterial(m); 
    2996  
    2997                 ExportViewCellGeometry(exporter, vc); 
    2998  
    2999  
    3000                 Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) 
    3001                           << ", piercing rays=" << (int)vcRays.size() << endl; 
    3002                         //  << ", leaves=" << (int)vc->mLeaves.size() << endl; 
    3003  
    3004                  
    3005                 //-- export rays piercing this view cell 
    3006                 if (1) 
    3007                 { 
    3008                         exporter->ExportRays(vcRays, RgbColor(1, 1, 1)); 
    3009                 } 
    3010                 else 
    3011                 { 
    3012  
    3013                         ViewCellContainer leaves; 
    3014                         mViewCellsTree->CollectLeaves(vc, leaves); 
    3015  
    3016                         ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 
    3017  
    3018                         for (lit = leaves.begin(); lit != lit_end; ++ lit) 
    3019                         { 
    3020                                 BspLeaf *l = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 
    3021                                 exporter->ExportRays(l->mVssRays); 
    3022                         } 
    3023                 } 
    3024  
    3025          
    3026                 m.mDiffuseColor = RgbColor(1, 0, 0); 
    3027                 exporter->SetForcedMaterial(m); 
    3028  
    3029                 ObjectPvsMap::const_iterator it, 
    3030                         it_end = vc->GetPvs().mEntries.end(); 
    3031  
    3032                 exporter->SetFilled(); 
    3033  
    3034          
    3035                 // output PVS of view cell 
    3036                 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
    3037                 { 
    3038                  
    3039                         Intersectable *intersect = (*it).first; 
    3040  
    3041                         if (!intersect->Mailed()) 
    3042                         { 
    3043                                 Material m = RandomMaterial(); 
    3044                                 exporter->SetForcedMaterial(m); 
    3045  
    3046                                 exporter->ExportIntersectable(intersect); 
    3047                                 intersect->Mail(); 
    3048                         } 
    3049                 } 
    3050  
    3051                  
    3052                 DEL_PTR(exporter); 
    3053                 cout << "finished" << endl; 
    3054         } 
    3055  
    3056         Debug << endl; 
    3057 } 
    3058  
    3059  
    3060 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin, 
    3061                                                                                         const Vector3 &termination, 
    3062                                                                                         ViewCellContainer &viewcells) 
    3063 { 
    3064         return mVspBspTree->CastLineSegment(origin, termination, viewcells); 
    3065 } 
    3066  
    3067  
    3068 void VspBspViewCellsManager::ExportColor(Exporter *exporter, 
    3069                                                                                  ViewCell *vc) const 
    3070 { 
    3071         const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 
    3072  
    3073         float importance = 0; 
    3074         static Material m; 
    3075  
    3076         switch (mColorCode) 
    3077         { 
    3078         case 0: // Random 
    3079                 { 
    3080                         if (vcValid) 
    3081                         { 
    3082                                 m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f); 
    3083                                 m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f); 
    3084                                 m.mDiffuseColor.b = 0.5f + RandomValue(0.f, 0.5f); 
    3085                         } 
    3086                         else 
    3087                         { 
    3088                                 m.mDiffuseColor.r = 0.0f; 
    3089                                 m.mDiffuseColor.g = 1.0f; 
    3090                                 m.mDiffuseColor.b = 0.0f; 
    3091                         } 
    3092  
    3093                         exporter->SetForcedMaterial(m); 
    3094                         return; 
    3095                 } 
    3096                  
    3097         case 1: // pvs 
    3098                 { 
    3099                         importance = (float)vc->GetPvs().GetSize() / 
    3100                                 (float)mViewCellsStats.maxPvs; 
    3101  
    3102                 } 
    3103                 break; 
    3104         case 2: // merges 
    3105                 { 
    3106             int lSize = mViewCellsTree->GetSize(vc); 
    3107          
    31083215                        importance = (float)lSize / (float)mViewCellsStats.maxLeaves; 
    31093216                } 
     
    31643271                                                           *cuttingPlane, 
    31653272                                                           mViewSpaceBox,  
    3166                                                            0.0001); 
    3167  
    3168                         exporter->ExportPolygons(back.mPolys); 
     3273                                                           0.0001f); 
     3274 
     3275                        if ((int)back.mPolys.size() >= 3) 
     3276                                exporter->ExportPolygons(back.mPolys); 
    31693277                } 
    31703278        } 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h

    r599 r600  
    355355   
    356356  void CollectViewCells(const int n) { 
    357         mNumMergedViewCells = n; 
     357        mNumActiveViewCells = n; 
    358358        mViewCells.clear(); 
    359359        CollectViewCells(); 
     
    454454        float mMaxPvsRatio; 
    455455 
    456         int mNumMergedViewCells; 
    457  
     456        int mNumActiveViewCells; 
    458457        bool mCompressViewCells; 
    459458 
  • trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp

    r590 r600  
    8686        //-- max cost ratio for early tree termination 
    8787        environment->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio); 
    88  
     88mTermMinPolygons = 25; 
    8989        //-- factors for bsp tree split plane heuristics 
    9090        environment->GetFloatValue("VspBspTree.Factor.balancedRays", mBalancedRaysFactor); 
     
    116116 
    117117 
     118        mSubdivisionStats.open("subdivisionStats.log"); 
    118119 
    119120 
     
    387388 
    388389// return memory usage in MB 
    389 float VspBspTree::GetMemUsage(/*const VspBspTraversalStack &tstack*/) const 
     390float VspBspTree::GetMemUsage(/*const VspBspTraversalQueue &tstack*/) const 
    390391{ 
    391392        return 
     
    402403void VspBspTree::Construct(const PolygonContainer &polys, RayInfoContainer *rays) 
    403404{ 
    404         VspBspTraversalStack tStack; 
     405        VspBspTraversalQueue tQueue; 
    405406 
    406407        mRoot = new BspLeaf(); 
     
    426427                tData.mIsKdNode = false; 
    427428 
    428         tStack.push(tData); 
    429  
     429        tQueue.push(tData); 
     430 
     431        mTotalCost = tData.GetCost() / mBox.GetVolume(); 
     432 
     433        Debug << "total cost: " << mTotalCost << endl; 
     434        mSplits = 0; 
     435         
    430436        mBspStats.Start(); 
    431437        cout << "Contructing vsp bsp tree ... \n"; 
     
    440446        int nleaves = 500; 
    441447 
    442         while (!tStack.empty()) 
    443         { 
    444                 tData = tStack.top(); 
    445             tStack.pop();                
     448        while (!tQueue.empty()) 
     449        { 
     450                tData = tQueue.top(); 
     451            tQueue.pop();                
    446452 
    447453                if (0 && !mOutOfMemory) 
     
    457463 
    458464                // subdivide leaf node 
    459                 BspNode *r = Subdivide(tStack, tData); 
     465                BspNode *r = Subdivide(tQueue, tData); 
    460466 
    461467                if (r == mRoot) 
     
    489495                 (data.mProbability <= mTermMinProbability) || 
    490496                 (mBspStats.Leaves() >= mMaxViewCells) || 
     497#if 0 
     498                 (((int)data.mPolygons->size() <= mTermMinPolygons) && !data.mPolygons->empty())|| 
     499#endif 
    491500                 (data.GetAvgRayContribution() > mTermMaxRayContribution) || 
    492501                 (data.mDepth >= mTermMaxDepth)); 
     
    494503 
    495504 
    496 BspNode *VspBspTree::Subdivide(VspBspTraversalStack &tStack, 
     505BspNode *VspBspTree::Subdivide(VspBspTraversalQueue &tQueue, 
    497506                                                           VspBspTraversalData &tData) 
    498507{ 
     
    512521                if (!newNode->IsLeaf()) //-- continue subdivision 
    513522                { 
     523                        if (1) 
     524                        { 
     525                                float costDecr =  
     526                                        (tFrontData.GetCost() + tBackData.GetCost() - tData.GetCost()) / mBox.GetVolume(); 
     527                                mTotalCost += costDecr; 
     528 
     529                                mSubdivisionStats  
     530                                                << "#Nodes\n" << ++ mSplits << endl 
     531                                                << "#RenderCostDecrease\n" << -costDecr << endl  
     532                                                << "#TotalRenderCost\n" << mTotalCost << endl; 
     533                        } 
     534 
    514535                        // push the children on the stack 
    515                         tStack.push(tFrontData); 
    516                         tStack.push(tBackData); 
     536                        tQueue.push(tFrontData); 
     537                        tQueue.push(tBackData); 
    517538 
    518539                        // delete old leaf node 
     
    13411362                        float oldCost, newCost; 
    13421363 
     1364                        // only render cost 
    13431365                        if (1) 
    13441366                        { 
     
    13461368                                newCost = newRenderCost; 
    13471369                        } 
    1348                         else 
     1370                        else // also considering standard deviation 
    13491371                        { 
    13501372                                // standard deviation is difference of back and front pvs 
     
    13611383 
    13621384                        cost += mPvsFactor * newCost / oldCost; 
    1363                 } 
    1364                 else 
    1365                 { 
    1366                         //-- compute weighted sum of expected render cost and standard deviation 
    1367                          
    1368                         //-- first compute expected render cost          
    1369                         const float penaltyOld = EvalPvsPenalty(totalPvs, lowerPvsLimit, upperPvsLimit); 
    1370                 const float penaltyFront = EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit); 
    1371                         const float penaltyBack = EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit); 
    1372                          
    1373                         const float renderCostFront = penaltyFront * pFront; 
    1374                         const float renderCostBack = penaltyBack * pBack; 
    1375  
    1376                         const float oldRenderCost = pOverall * (float)penaltyOld + Limits::Small; 
    1377                         const float newRenderCost = renderCostFront + renderCostBack; 
    1378  
    1379  
    1380                         //-- compute standard deviation 
    1381                         const float expectedCost = 0.5f * (renderCostBack + renderCostFront); 
    1382  
    1383                         const float devFront = fabs(renderCostFront - expectedCost); 
    1384                          
    1385                         const float devBack = fabs(renderCostBack - expectedCost); 
    1386  
    1387                         const float newDev = 0.5f * (devFront + devBack); 
    1388                         const float oldDev = oldRenderCost * oldRenderCost; 
    1389  
    1390                         const float newCost = newRenderCost * mRenderCostWeight + newDev * (1.0f - mRenderCostWeight); 
    1391                         const float oldCost = oldRenderCost * mRenderCostWeight + oldDev * (1.0f - mRenderCostWeight); 
    1392  
    1393                         cost += mPvsFactor * newCost / oldCost; 
    1394  
    1395                         // also try to equalize render differences between front and back pvs 
    1396                         //const float oldCost = pOverall + Limits::Small; 
    1397                         //float newCost = (float)abs(pvsFront - pvsBack); 
    1398                          
    13991385                } 
    14001386        } 
     
    14041390                  << " frontpvs: " << pvsFront << " pFront: " << pFront 
    14051391                  << " backpvs: " << pvsBack << " pBack: " << pBack << endl << endl; 
     1392        Debug << "cost: " << cost << endl; 
    14061393#endif 
    14071394 
     1395         
    14081396        // normalize cost by sum of linear factors 
    14091397        if(0) 
     
    16381626        int hits = 0; 
    16391627 
    1640         stack<BspRayTraversalData> tStack; 
     1628        stack<BspRayTraversalData> tQueue; 
    16411629 
    16421630        float maxt, mint; 
     
    16461634 
    16471635        Intersectable::NewMail(); 
    1648  
     1636        ViewCell::NewMail(); 
    16491637        Vector3 entp = ray.Extrap(mint); 
    16501638        Vector3 extp = ray.Extrap(maxt); 
     
    16901678 
    16911679                        // push data for far child 
    1692                         tStack.push(BspRayTraversalData(farChild, extp, maxt)); 
     1680                        tQueue.push(BspRayTraversalData(farChild, extp, maxt)); 
    16931681 
    16941682                        // find intersection of ray segment with plane 
     
    17091697 
    17101698                        //-- fetch the next far child from the stack 
    1711                         if (tStack.empty()) 
     1699                        if (tQueue.empty()) 
    17121700                                break; 
    17131701 
     
    17181706                                break; 
    17191707 
    1720                         BspRayTraversalData &s = tStack.top(); 
     1708                        BspRayTraversalData &s = tQueue.top(); 
    17211709 
    17221710                        node = s.mNode; 
     
    17241712                        maxt = s.mMaxT; 
    17251713 
    1726                         tStack.pop(); 
     1714                        tQueue.pop(); 
    17271715                } 
    17281716        } 
     
    22042192        return (int)neighbors.size(); 
    22052193} 
     2194 
     2195 
     2196 
     2197int VspBspTree::FindApproximateNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 
     2198                                                                                 const bool onlyUnmailed) const 
     2199{ 
     2200        stack<bspNodePair> nodeStack; 
     2201         
     2202        BspNodeGeometry nodeGeom; 
     2203        ConstructGeometry(n, nodeGeom); 
     2204         
     2205        // split planes from the root to this node 
     2206        // needed to verify that we found neighbor leaf 
     2207        // TODO: really needed? 
     2208        vector<Plane3> halfSpaces; 
     2209        ExtractHalfSpaces(n, halfSpaces); 
     2210 
     2211 
     2212        BspNodeGeometry *rgeom = new BspNodeGeometry(); 
     2213        ConstructGeometry(mRoot, *rgeom); 
     2214 
     2215        nodeStack.push(bspNodePair(mRoot, rgeom)); 
     2216 
     2217        while (!nodeStack.empty()) 
     2218        { 
     2219                BspNode *node = nodeStack.top().first; 
     2220                BspNodeGeometry *geom = nodeStack.top().second; 
     2221         
     2222                nodeStack.pop(); 
     2223 
     2224                if (node->IsLeaf()) 
     2225                { 
     2226                        // test if this leaf is in valid view space 
     2227                        if (node->TreeValid() && 
     2228                                (node != n) &&  
     2229                                (!onlyUnmailed || !node->Mailed())) 
     2230                        { 
     2231                                bool isAdjacent = true; 
     2232 
     2233                                // neighbor was found 
     2234                                if (isAdjacent) 
     2235                                {        
     2236                                        neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 
     2237                                } 
     2238                        } 
     2239                } 
     2240                else 
     2241                { 
     2242                        BspInterior *interior = dynamic_cast<BspInterior *>(node); 
     2243 
     2244                        const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys, 
     2245                                                                                                   interior->GetPlane(), 
     2246                                                                                                   mEpsilon); 
     2247                         
     2248                        BspNode *front = interior->GetFront(); 
     2249                        BspNode *back = interior->GetBack(); 
     2250             
     2251                        BspNodeGeometry *fGeom = new BspNodeGeometry(); 
     2252                        BspNodeGeometry *bGeom = new BspNodeGeometry(); 
     2253 
     2254                        geom->SplitGeometry(*fGeom, 
     2255                                                                *bGeom, 
     2256                                                                interior->GetPlane(), 
     2257                                                                mBox, 
     2258                                                                mEpsilon); 
     2259                 
     2260                        if (cf == Polygon3::FRONT_SIDE) 
     2261                        { 
     2262                                nodeStack.push(bspNodePair(interior->GetFront(), fGeom)); 
     2263                                DEL_PTR(bGeom); 
     2264                        } 
     2265                        else 
     2266                        { 
     2267                                if (cf == Polygon3::BACK_SIDE) 
     2268                                { 
     2269                                        nodeStack.push(bspNodePair(interior->GetBack(), bGeom)); 
     2270                                        DEL_PTR(fGeom); 
     2271                                } 
     2272                                else 
     2273                                {       // random decision 
     2274                                        nodeStack.push(bspNodePair(front, fGeom)); 
     2275                                        nodeStack.push(bspNodePair(back, bGeom)); 
     2276                                } 
     2277                        } 
     2278                } 
     2279         
     2280                DEL_PTR(geom); 
     2281        } 
     2282 
     2283        return (int)neighbors.size(); 
     2284} 
     2285 
    22062286 
    22072287 
     
    23782458{ 
    23792459        int hits = 0; 
    2380         stack<BspRayTraversalData> tStack; 
     2460        stack<BspRayTraversalData> tQueue; 
    23812461 
    23822462        float mint = 0.0f, maxt = 1.0f; 
    23832463 
    23842464        Intersectable::NewMail(); 
     2465        ViewCell::NewMail(); 
    23852466 
    23862467        Vector3 entp = origin; 
     
    24312512 
    24322513                        // push data for far child 
    2433                         tStack.push(BspRayTraversalData(farChild, extp)); 
     2514                        tQueue.push(BspRayTraversalData(farChild, extp)); 
    24342515 
    24352516                        // find intersection of ray segment with plane 
     
    24502531 
    24512532                        //-- fetch the next far child from the stack 
    2452                         if (tStack.empty()) 
     2533                        if (tQueue.empty()) 
    24532534                                break; 
    24542535 
    24552536                        entp = extp; 
    24562537                         
    2457                         BspRayTraversalData &s = tStack.top(); 
     2538                        BspRayTraversalData &s = tQueue.top(); 
    24582539 
    24592540                        node = s.mNode; 
    24602541                        extp = s.mExitPoint; 
    24612542 
    2462                         tStack.pop(); 
     2543                        tQueue.pop(); 
    24632544                } 
    24642545        } 
     
    27112792                vector<BspLeaf *> neighbors; 
    27122793                FindNeighbors(leaf, neighbors, true); 
    2713  
     2794                //FindApproximateNeighbors(leaf, neighbors, true); 
    27142795                vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end(); 
    27152796 
  • trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h

    r591 r600  
    2424class Beam; 
    2525class ViewCellsTree; 
     26 
    2627 
    2728struct BspRay; 
     
    123124                float GetCost() const 
    124125                { 
    125 #if 0 
     126#if 1 
    126127                        return mPvs * mProbability; 
    127128#endif 
    128 #if 1 
    129                         return - mDepth; 
     129#if 0 
     130                        return (float) (-mDepth); // for regular grid 
    130131#endif 
    131132#if 0 
     
    154155    }; 
    155156         
    156         typedef std::priority_queue<VspBspTraversalData> VspBspTraversalStack; 
    157         //typedef std::stack<VspBspTraversalData> VspBspTraversalStack; 
     157        typedef std::priority_queue<VspBspTraversalData> VspBspTraversalQueue; 
     158        //typedef std::stack<VspBspTraversalData> VspBspTraversalQueue; 
    158159 
    159160        /** Default constructor creating an empty tree. 
     
    292293 
    293294         
     295        int FindApproximateNeighbors(BspNode *n,  
     296                                                             vector<BspLeaf *> &neighbors, 
     297                                                                 const bool onlyUnmailed) const; 
     298 
    294299        /** Checks if tree validity-flags are right  
    295300                with respect to view cell valitiy. 
     
    368373                @returns new root of the subtree 
    369374        */ 
    370         BspNode *Subdivide(VspBspTraversalStack &tStack,  
     375        BspNode *Subdivide(VspBspTraversalQueue &tStack,  
    371376                                           VspBspTraversalData &tData); 
    372377 
     
    598603        /** Returns estimated memory usage of tree. 
    599604        */ 
    600         //float GetMemUsage(const VspBspTraversalStack &tstack) const; 
     605        //float GetMemUsage(const VspBspTraversalQueue &tstack) const; 
    601606        float GetMemUsage() const; 
    602607 
     
    633638        float mTermMinAccRayLength; 
    634639 
    635          
     640        //HACK 
     641        int mTermMinPolygons; 
    636642 
    637643        //-- termination criteria for axis aligned split 
     
    677683        int mMaxViewCells; 
    678684         
     685        ofstream  mSubdivisionStats; 
    679686 
    680687        // if rays should be stored in leaves 
     
    698705        bool mOutOfMemory; 
    699706         
    700          
     707        float mTotalCost; 
     708        int mSplits; 
     709 
     710        ofstream mSubdivsionStats; 
     711 
    701712private: 
    702713 
  • trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp

    r598 r600  
    7777    int hits = 0; 
    7878  static Ray ray; 
    79   AxisAlignedBox3 box = mKdTree->GetBox(); 
     79  AxisAlignedBox3 box =  mViewSpaceBox ? *mViewSpaceBox : mKdTree->GetBox(); 
    8080 
    8181  AxisAlignedBox3 sbox = box; 
     
    203203{ 
    204204  Vector3 point; 
    205   if (!use2dSampling) { 
    206         if (0) { 
    207           Vector3 normal; 
    208           int i = Random((int)mObjects.size()); 
    209           Intersectable *object = mObjects[i]; 
    210           object->GetRandomSurfacePoint(point, normal); 
    211         } else 
    212           point = mKdTree->GetBox().GetRandomPoint(); 
     205  if (!use2dSampling)  
     206  { 
     207          if (0)  
     208          { 
     209                  Vector3 normal; 
     210                  int i = Random((int)mObjects.size()); 
     211                  Intersectable *object = mObjects[i]; 
     212                  object->GetRandomSurfacePoint(point, normal); 
     213          }  
     214          else 
     215                  point = mKdTree->GetBox().GetRandomPoint(); 
    213216        //        point = viewpoint + UniformRandomVector(); 
    214  
    215   } else { 
    216         AxisAlignedBox3 box; 
    217  
    218         if (viewSpaceBox) 
    219           box =*viewSpaceBox; 
    220         else 
    221           box = mKdTree->GetBox(); 
    222  
    223         point = box.GetRandomPoint(); 
    224         point.y = viewpoint.y; 
     217  }  
     218  else  
     219  { 
     220          AxisAlignedBox3 box; 
     221 
     222          if (viewSpaceBox) 
     223                  box =*viewSpaceBox; 
     224          else 
     225                  box = mKdTree->GetBox(); 
     226 
     227          point = box.GetRandomPoint(); 
     228          point.y = viewpoint.y; 
    225229  } 
    226230 
     
    528532  { 
    529533          if (0) 
    530                 mViewSpaceBox = box; 
     534                  mViewSpaceBox = box; 
    531535          else 
    532536          { 
     
    536540                Vector3 size = mViewSpaceBox->Size(); 
    537541                //size[1] *= 1.25; 
    538                 Vector3 enlarge(size[0] * 0.1f, size[1] * 0.0f, size[2] * 0.1); 
     542                Vector3 enlarge(size[0] * 0.25f, size[1] * 0.0f, size[2] * 0.25f); 
    539543 
    540544                mViewSpaceBox->Enlarge(enlarge); 
Note: See TracChangeset for help on using the changeset viewer.