Changeset 297 for trunk


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

added bsp split plane criteria

Location:
trunk/VUT/GtpVisibilityPreprocessor
Files:
8 edited

Legend:

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

    r294 r297  
    6565 
    6666BspTree { 
    67         splitPlaneStrategy 14 
     67        # next polygon         = 1 
     68        # axis aligned         = 2 
     69        # least splits         = 4 
     70        # balanced polygons    = 8 
     71        # balanced view cells  = 16 
     72        # largest polygon area = 32 
     73        # vertical axis        = 64 
     74         
     75        # least splits + balanced polygons 
     76        #splitPlaneStrategy 12 
     77        # axis aligned + vertical axis 
     78        #splitPlaneStrategy 66 
     79        # axis aligned + balanced view cells 
     80        #splitPlaneStrategy 18 
     81        # largest polygon area 
     82        #splitPlaneStrategy 32 
     83        splitPlaneStrategy 72 
    6884#       constructionMethod rays 
    6985        constructionMethod viewCells 
     
    7288        maxViewCells 999999 
    7389        Termination { 
     90                maxPolysForAxisAligned 50 
    7491                maxPolygons 0 
    7592                maxDepth 100 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp

    r268 r297  
    11611161                 "5"); 
    11621162   
     1163  RegisterOption("BspTree.Termination.maxPolysForAxisAligned", 
     1164                 optInt, 
     1165                 "-bsp_term_max_polygons=", 
     1166                 "50"); 
     1167 
    11631168  RegisterOption("BspTree.Termination.maxDepth", 
    11641169                 optInt, 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp

    r295 r297  
    124124        bool onFrontSide = false; 
    125125        bool onBackSide = false; 
    126         // threshold for coincident classification 
    127         const float dot_thres = 0.99f; 
    128  
     126         
    129127        int count = 0; 
    130128        // find possible line-plane intersections 
     
    145143                // 3 vertices enough to decide coincident 
    146144                else if (((++ count) >= 3) && !onFrontSide && !onBackSide)  
    147                 { 
    148                         // Decide if plane and surface normal are same 
    149                         if (DotProd(plane.mNormal, GetSupportingPlane().mNormal) > dot_thres) 
    150                                 return COINCIDENT; // plane and polygon are coincident 
    151                         else  
    152                                 return FRONT_SIDE; 
    153                 } 
     145                        return COINCIDENT;  
    154146        } 
    155147 
     
    163155        } 
    164156 
    165         // Decide if plane and surface normal are same 
    166         if (DotProd(plane.mNormal, GetSupportingPlane().mNormal) > dot_thres) 
    167                 return COINCIDENT; // plane and polygon are coincident 
    168         else  
    169                 return FRONT_SIDE; 
     157        return COINCIDENT; // plane and polygon are coincident 
    170158} 
    171159 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp

    r265 r297  
    99Preprocessor::Preprocessor(): 
    1010mKdTree(NULL), 
    11 mBspTree(NULL) 
     11mBspTree(NULL), 
     12mRootViewCell(NULL) 
    1213{ 
    1314} 
     
    1819  DEL_PTR(mBspTree); 
    1920  DEL_PTR(mKdTree); 
     21  DEL_PTR(mRootViewCell); 
    2022} 
    2123 
     
    8789{ 
    8890        DEL_PTR(mBspTree); 
    89         mBspTree = new BspTree(); 
     91        DEL_PTR(mRootViewCell); 
     92        mRootViewCell = new ViewCell(); 
     93        mBspTree = new BspTree(mRootViewCell); 
    9094 
    9195        ObjectContainer objects; 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h

    r263 r297  
    105105  /// BSP tree representing the viewcells 
    106106  BspTree *mBspTree; 
     107 
     108  /// the root view cell of the bsp tree 
     109  ViewCell *mRootViewCell; 
    107110}; 
    108111 
  • 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 
  • trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h

    r296 r297  
    162162class BspInterior : public BspNode  
    163163{ 
     164        friend BspTree; 
    164165public: 
    165166        /** Standard contructor taking split plane as argument. 
     
    275276 
    276277        /** Default constructor creating an empty tree. 
     278                @param viewCell view cell corresponding to unbounded space 
    277279        */  
    278         BspTree(); 
     280        BspTree(ViewCell *viewCell); 
    279281 
    280282        ~BspTree(); 
     
    427429        inline int GetNextCandidateIdx(const int max) const; 
    428430 
     431        /** Helper function which extracts a view cell on the front and the back 
     432                of the split plane. 
     433                @param backViewCell returns view cell on the back of the split plane 
     434                @param frontViewCell returns a view cell on the front of the split plane 
     435                @param coincident container of polygons coincident to the split plane 
     436                @param splitPlane the split plane which decides about back and front 
     437                @param extractFront if a front view cell is extracted 
     438                @param extractBack if a back view cell is extracted 
     439        */ 
     440        void ExtractViewCells(ViewCell **backViewCell,  
     441                                                  ViewCell **frontViewCell, 
     442                                                  const PolygonContainer &coincident, 
     443                                                  const Plane3 splitPlane,  
     444                                                  const bool extractFront,  
     445                                                  const bool extractBack) const; 
     446         
    429447        /// Pointer to the root of the tree 
    430448        BspNode *mRoot; 
     
    436454 
    437455        /// Strategies for choosing next split plane. 
    438         enum {NEXT_POLYGON = 0,  
    439                   LEAST_SPLITS = 2,  
    440                   BALANCED_TREE = 4,  
    441                   VERTICAL_AXIS = 8,  
    442                   AXIS_ALIGNED = 16}; 
     456        enum {NO_STRATEGY = 0, 
     457                  NEXT_POLYGON = 1,  
     458                  AXIS_ALIGNED = 2, 
     459                  LEAST_SPLITS = 4,  
     460                  BALANCED_POLYS = 8, 
     461                  BALANCED_VIEW_CELLS = 16, 
     462                  LARGEST_POLY_AREA = 32, 
     463                  VERTICAL_AXIS = 64 
     464                }; 
    443465 
    444466        /// box around the whole view domain 
     
    448470        bool mStorePolys; 
    449471 
    450         /// vertical axis of scene 
    451         Vector3 mVerticalAxis; 
     472        /// view cell corresponding to unbounded space 
     473        ViewCell *mViewCell; 
    452474 
    453475public: 
     
    465487        /// BSP tree construction method 
    466488        static int sConstructionMethod; 
    467  
     489        /// maximal number of polygons where we do axis aligned splits 
     490        static int sTermMaxPolysForAxisAligned; 
     491 
     492        // factors to guid the split plane heuristics 
    468493        static float sLeastSplitsFactor; 
    469         static float sBalancedTreeFactor; 
    470         static float sVerticalFactor; 
    471  
     494        static float sBalancedPolysFactor; 
     495        static float sBalancedViewCellsFactor; 
     496        static float sVerticalSplitsFactor; 
     497         
    472498private: 
    473499        /** Evaluates split plane classification with respect to the plane's  
     
    478504                contribution for a minimum number splits in the tree. 
    479505        */ 
    480         static float sBalancedTreeTable[4]; 
     506        static float sBalancedPolysTable[4]; 
    481507}; 
    482508 
  • trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp

    r294 r297  
    4747                  p->GenerateViewCells(); 
    4848 
    49          Debug << "Viewcells loaded / generated. Number of view cells: " << p->mViewCells.size() << endl; 
     49         Debug << "Viewcells loaded / generated. Number of view cells: " << (int)p->mViewCells.size() << endl; 
    5050  } 
    5151 
Note: See TracChangeset for help on using the changeset viewer.