Ignore:
Timestamp:
09/26/05 02:00:42 (19 years ago)
Author:
mattausch
Message:

added bsp split plane criteria

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp

    r296 r297  
    1818int BspTree::sSplitPlaneStrategy = NEXT_POLYGON;  
    1919int BspTree::sConstructionMethod = VIEW_CELLS; 
    20 float BspTree::sLeastSplitsFactor = 1.0f 
    21 float BspTree::sBalancedTreeFactor = 2.0f; 
    22 float BspTree::sVerticalFactor = 50.0f // very important criterium for 2.5d scenes 
     20int BspTree::sTermMaxPolysForAxisAligned = 50; 
     21 
     22//-- factors for bsp tree split plane heuristics 
     23float BspTree::sLeastSplitsFactor = 1.0f; 
     24float BspTree::sBalancedPolysFactor = 2.0f; 
     25float BspTree::sBalancedViewCellsFactor = 2.0f; 
     26float BspTree::sVerticalSplitsFactor = 1.0f; // very important criterium for 2.5d scenes 
    2327 
    2428 
     
    3034        contribution for a minimum number splits in the tree. 
    3135*/ 
    32 float BspTree::sBalancedTreeTable[] = {-1, 1, 0, 0}; 
     36float BspTree::sBalancedPolysTable[] = {-1, 1, 0, 0}; 
    3337 
    3438//int counter = 0; 
     
    187191 
    188192                                ++ splits; // increase number of splits 
    189                                 // check if polygon still valid  
     193 
     194                                // check if polygons still valid  
    190195                                if (front_piece->mVertices.size() >= 3) 
    191196                                        frontPolys->push_back(front_piece); 
    192197                                else 
    193198                                        DEL_PTR(front_piece); 
    194                                 // check if polygon still valid 
     199                                 
    195200                                if (back_piece->mVertices.size() >= 3) 
    196201                                        backPolys->push_back(back_piece); 
     
    248253/****************************************************************/ 
    249254 
    250 BspTree::BspTree():  
     255BspTree::BspTree(ViewCell *viewCell):  
    251256mRoot(NULL),  
    252 mVerticalAxis(Vector3(0, 0, 1)), 
     257mViewCell(viewCell), 
    253258//mStorePolys(true) 
    254259mStorePolys(false) 
     
    369374        BspNode *firstNode = mRoot ? mRoot : new BspLeaf(); 
    370375 
    371         tStack.push(BspTraversalData(firstNode, polys, 0, NULL)); 
     376        tStack.push(BspTraversalData(firstNode, polys, 0, mViewCell)); 
    372377 
    373378        while (!tStack.empty()) 
     
    398403                                                                                mStorePolys); 
    399404                                 
    400                                 // get view cell associated with the split polygon 
    401                                 ViewCell *viewCell = (coincident.size() > 0) ?  
    402                                         dynamic_cast<ViewCell *>(coincident.front()->mParent) : NULL; 
     405                                // extract view cells associated with the split polygons 
     406                                ViewCell *frontViewCell = mViewCell; 
     407                                ViewCell *backViewCell = mViewCell; 
     408         
     409                                if (!viewCells) 
     410                                { 
     411                                        ExtractViewCells(&backViewCell, 
     412                                                                         &frontViewCell, 
     413                                                                         coincident,  
     414                                                                         interior->mPlane,  
     415                                                                         frontPolys->empty(),  
     416                                                                         backPolys->empty()); 
     417                                } 
     418 
     419                                // don't need coincident polygons anymore 
    403420                                interior->ProcessPolygons(&coincident, mStorePolys); 
    404421 
     
    407424 
    408425                                // push the children on the stack 
    409                                 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, NULL)); 
    410                                 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, viewCell)); 
     426                                tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, frontViewCell)); 
     427                                tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, backViewCell)); 
    411428                        } 
    412429 
     
    533550        std::stack<BspTraversalData> tStack; 
    534551         
    535         BspTraversalData tData(new BspLeaf(), polys, 0, NULL); 
     552        BspTraversalData tData(new BspLeaf(), polys, 0, mViewCell); 
    536553 
    537554        tStack.push(tData); 
     
    563580        if ((tData.mPolygons->size() <= sTermMaxPolygons) || (tData.mDepth >= sTermMaxDepth)) 
    564581        { 
    565 #ifdef _DEBUG 
     582//#ifdef _DEBUG 
    566583                Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " << (int)tData.mPolygons->size() << endl; 
    567 #endif 
     584//#endif 
    568585 
    569586                EvaluateLeafStats(tData); 
     
    580597                } 
    581598                //-- add viewcell stored in split polygon 
    582                 else if (tData.mViewCell) 
     599                else 
    583600                { 
    584601                        if (leaf->GetViewCell()) 
     
    586603 
    587604                        //leaf->mViewCellIdx = counter; Debug << "insert view cell " << tData.mViewCell << endl; 
    588                         leaf->SetViewCell(dynamic_cast<ViewCell *>(tData.mViewCell)); 
     605                        leaf->SetViewCell(tData.mViewCell); 
    589606                } 
    590607         
     
    608625                                                                                  &coincident); 
    609626 
    610         // view cell associated with the first split polygon 
    611         ViewCell *viewCell = (coincident.size() > 0) ?  
    612                                         dynamic_cast<ViewCell *>(coincident.front()->mParent) : NULL; 
     627        //-- extract view cells from coincident polygons according to plane normal 
     628        ViewCell *frontViewCell = mViewCell; 
     629        ViewCell *backViewCell = mViewCell; 
     630         
     631    if (!viewCells) 
     632        { 
     633                ExtractViewCells(&backViewCell, 
     634                                                 &frontViewCell, 
     635                                                 coincident,  
     636                                                 interior->mPlane,  
     637                                                 frontPolys->empty(),  
     638                                                 backPolys->empty()); 
     639        } 
     640     
     641        // don't need coincident polygons anymore 
    613642        interior->ProcessPolygons(&coincident, mStorePolys); 
    614643 
    615644        // push the children on the stack 
    616645        // split polygon is only needed in the back leaf 
    617         tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, NULL)); 
    618         tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, viewCell)); 
     646        tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, frontViewCell)); 
     647        tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, backViewCell)); 
    619648 
    620649        // cleanup 
     
    625654} 
    626655 
     656void BspTree::ExtractViewCells(ViewCell **backViewCell,  
     657                                                           ViewCell **frontViewCell, 
     658                                                           const PolygonContainer &coincident, 
     659                                                           const Plane3 splitPlane,  
     660                                                           const bool extractFront,  
     661                                                           const bool extractBack) const 
     662{ 
     663        bool foundFront = !extractFront, foundBack = !extractBack; 
     664 
     665        PolygonContainer::const_iterator it, it_end = coincident.end(); 
     666 
     667        for (it = coincident.begin(); !(foundFront && foundBack) &&  
     668                (it < coincident.end()); ++it) 
     669        { 
     670                if (DotProd((*it)->GetSupportingPlane().mNormal, splitPlane.mNormal > 0)) 
     671                { 
     672                        *backViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 
     673                        foundBack = true; 
     674                } 
     675                else 
     676                { 
     677                        *frontViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 
     678                        foundFront = true; 
     679                } 
     680        } 
     681} 
    627682 
    628683BspInterior *BspTree::SubdivideNode(BspLeaf *leaf,  
     
    671726        } 
    672727 
    673         // simple strategy: just take next polygon 
    674         if (sSplitPlaneStrategy & NEXT_POLYGON) 
    675         { 
    676                 return polys.front()->GetSupportingPlane(); 
    677         } 
    678          
    679         if (sSplitPlaneStrategy & AXIS_ALIGNED) 
     728        if ((sSplitPlaneStrategy & AXIS_ALIGNED) && 
     729                ((int)polys.size() > sTermMaxPolysForAxisAligned)) 
    680730        { 
    681731                AxisAlignedBox3 box; 
    682732                box.Initialize(); 
    683733         
     734                // todo: area subdivision 
    684735                Polygon3::IncludeInBox(polys, box); 
    685736         
     
    690741 
    691742                return Plane3(norm, pt); 
     743        } 
     744 
     745        // simplest strategy: just take next polygon 
     746        if (sSplitPlaneStrategy & NEXT_POLYGON) 
     747        { 
     748                return polys.front()->GetSupportingPlane(); 
    692749        } 
    693750 
     
    729786                } 
    730787        } 
    731         //Debug << "Plane lowest cost: " << lowestCost << endl; 
     788        Debug << "Plane lowest cost: " << lowestCost << endl; 
    732789         
    733790        return polys[bestPlaneIdx]->GetSupportingPlane(); 
     
    741798float BspTree::EvalSplitPlane(const PolygonContainer &polys, const Plane3 &candidatePlane) const 
    742799{ 
    743         float sumBalanced = 0, sumLeastSplits = 0, verticalAxis = 0; 
     800        float sumBalancedPolys = 0; 
     801        float sumBalancedViewCells = 0; 
     802        float sumLeastSplits = 0; 
     803        float verticalAxis = 0; 
    744804         
    745805        if (sSplitPlaneStrategy & VERTICAL_AXIS) 
    746806        { 
    747                 Vector3 thinAxis(0,0,0); thinAxis[mBox.size().ThinAxis()] = 1.0f; 
    748                 // want to minimize this dot product 
    749                 verticalAxis = DotProd(candidatePlane.mNormal, thinAxis); 
    750                  
    751         //drivingAxis = (candidatePlane.mNormal.DrivingAxis() == mBox.Size().DrivingAxis()) ? 99.0f : 0.0f; 
    752         } 
    753         if ((sSplitPlaneStrategy & BALANCED_TREE) || (sSplitPlaneStrategy & LEAST_SPLITS)) 
     807                Vector3 tinyAxis(0,0,0); tinyAxis[mBox.Size().TinyAxis()] = 1.0f; 
     808                // want to put a penalty on the dot product between the "tiny" vertical axis 
     809                // and the split plane axis 
     810                verticalAxis = fabs(DotProd(candidatePlane.mNormal, tinyAxis)) * (float)polys.size(); 
     811        } 
     812        //-- strategies where the effect of the split plane on the polygons is tested 
     813        if ((sSplitPlaneStrategy & BALANCED_POLYS)      ||  
     814                (sSplitPlaneStrategy & LEAST_SPLITS)        || 
     815                (sSplitPlaneStrategy & LARGEST_POLY_AREA)) 
    754816        { 
    755817                PolygonContainer::const_iterator it, it_end = polys.end(); 
     
    759821                        int classification = (*it)->ClassifyPlane(candidatePlane); 
    760822 
    761                         if (sSplitPlaneStrategy & BALANCED_TREE) 
    762                                 sumBalanced += sBalancedTreeTable[classification]; 
    763          
     823                        if (sSplitPlaneStrategy & BALANCED_POLYS) 
     824                                sumBalancedPolys += sBalancedPolysTable[classification]; 
     825                                 
    764826                        if (sSplitPlaneStrategy & LEAST_SPLITS) 
    765827                                sumLeastSplits += sLeastSplitsTable[classification]; 
    766828                } 
    767829        } 
     830         
     831        if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) 
     832        { 
     833                // store view cells 
     834                ObjectContainer frontViewCells; 
     835                ObjectContainer backViewCells; 
     836 
     837                PolygonContainer::const_iterator it, it_end = polys.end(); 
     838                 
     839                for (it = polys.begin(); it != it_end; ++ it) 
     840                { 
     841                        int classification = (*it)->ClassifyPlane(candidatePlane); 
     842                        Intersectable *viewCell = (*it)->mParent; 
     843                         
     844                        if (viewCell && (classification == Polygon3::FRONT_SIDE)) 
     845                                frontViewCells.push_back(viewCell); 
     846                        else if (viewCell && (classification == Polygon3::BACK_SIDE)) 
     847                                backViewCells.push_back(viewCell); 
     848                } 
     849 
     850                // count number of unique view cells 
     851                sort(frontViewCells.begin(), frontViewCells.end()); 
     852                sort(backViewCells.begin(), backViewCells.end()); 
     853 
     854                ObjectContainer::const_iterator frontIt, frontIt_end = frontViewCells.end(); 
     855                 
     856                Intersectable *intersect = NULL; 
     857                // increase counter for view cells in front of plane 
     858        for (frontIt = frontViewCells.begin(); frontIt != frontIt_end; ++frontIt) 
     859                { 
     860                        if (*frontIt != intersect) 
     861                        { 
     862                                intersect = *frontIt; 
     863                                sumBalancedViewCells += 1; 
     864                        } 
     865                } 
     866 
     867                ObjectContainer::const_iterator backIt, backIt_end = backViewCells.end(); 
     868                intersect = NULL; 
     869                // decrease counter for view cells on back side of plane 
     870        for (backIt = backViewCells.begin(); backIt != backIt_end; ++backIt) 
     871                { 
     872                        if (*backIt != intersect) 
     873                        { 
     874                                intersect = *backIt; 
     875                                sumBalancedViewCells -= 1; 
     876                        } 
     877                } 
     878        } 
    768879 
    769880        // return linear combination of the sums 
    770         return sBalancedFactor * fabs(sumBalanced) + sLeastSplitsFactor * sumLeastSplits + sVerticalFactor * dotProd; 
     881        return sBalancedPolysFactor * fabs(sumBalancedPolys) +  
     882                   sBalancedViewCellsFactor * fabs(sumBalancedViewCells) + 
     883                   sLeastSplitsFactor * sumLeastSplits +  
     884                   sVerticalSplitsFactor * verticalAxis; 
    771885} 
    772886 
     
    775889        environment->GetIntValue("BspTree.Termination.maxDepth", sTermMaxDepth); 
    776890        environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons); 
     891        environment->GetIntValue("BspTree.Termination.maxPolysForAxisAligned",  
     892                                                         sTermMaxPolysForAxisAligned); 
    777893        environment->GetIntValue("BspTree.maxCandidates", sMaxCandidates); 
    778894        environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy); 
    779895 
    780         Debug << "BSP max depth: " << sTermMaxDepth << endl; 
     896    Debug << "BSP max depth: " << sTermMaxDepth << endl; 
    781897        Debug << "BSP max polys: " << sTermMaxPolygons << endl; 
    782898        Debug << "BSP max candidates: " << sMaxCandidates << endl; 
     899         
     900        Debug << "Split plane strategy: "; 
     901        if (sSplitPlaneStrategy & NEXT_POLYGON) 
     902                Debug << "next polygon "; 
     903        if (sSplitPlaneStrategy & AXIS_ALIGNED) 
     904                Debug << "axis aligned "; 
     905        if (sSplitPlaneStrategy & LEAST_SPLITS)      
     906                Debug << "least splits "; 
     907        if (sSplitPlaneStrategy & BALANCED_POLYS) 
     908                Debug << "balanced polygons "; 
     909        if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) 
     910                Debug << "balanced view cells "; 
     911        if (sSplitPlaneStrategy & LARGEST_POLY_AREA) 
     912                Debug << "largest polygon area "; 
     913        if (sSplitPlaneStrategy & VERTICAL_AXIS) 
     914                Debug << "vertical axis "; 
     915 
     916        Debug << endl; 
    783917 
    784918        //-- parse BSP tree construction method 
Note: See TracChangeset for help on using the changeset viewer.