Ignore:
Timestamp:
10/26/05 19:18:30 (19 years ago)
Author:
mattausch
Message:

updated ray based subdivision

File:
1 edited

Legend:

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

    r342 r349  
    4343        contribution for a minimum number splits in the tree. 
    4444*/ 
    45 float BspTree::sLeastSplitsTable[] = {0, 0, 1, 0}; 
     45float BspTree::sLeastPolySplitsTable[] = {0, 0, 1, 0}; 
    4646/** Evaluates split plane classification with respect to the plane's  
    4747        contribution for a balanced tree. 
    4848*/ 
    49 float BspTree::sBalancedTreeTable[] = {-1, 1, 0, 0}; 
     49float BspTree::sBalancedPolysTable[] = {1, -1, 0, 0}; 
     50 
     51/** Evaluates split plane classification with respect to the plane's  
     52        contribution for a minimum number of ray splits. 
     53*/ 
     54float BspTree::sLeastRaySplitsTable[] = {0, 0, 1, 1, 0}; 
     55/** Evaluates split plane classification with respect to the plane's  
     56        contribution for balanced rays. 
     57*/ 
     58float BspTree::sBalancedRaysTable[] = {1, -1, 0, 0, 0}; 
    5059 
    5160/****************************************************************/ 
     
    158167} 
    159168 
    160 void BspInterior::SplitRays(RayContainer &rays,  
    161                                                         RayContainer &frontRays,  
    162                                                         RayContainer &backRays) 
    163 { 
     169int BspInterior::SplitRays(RayContainer &rays,  
     170                                                   RayContainer &frontRays,  
     171                                                   RayContainer &backRays, 
     172                                                   const AxisAlignedBox3 &box) 
     173{ 
     174        int splits = 0; 
     175 
    164176        while (!rays.empty()) 
    165177        { 
     
    172184         
    173185                // test with tree bounding box 
    174 /*              if (!mBox.GetMinMaxT(*ray, &minT, &maxT)) 
     186                if (!box.GetMinMaxT(*ray, &minT, &maxT)) 
    175187                        continue; 
     188 
    176189                if (minT < 0) // start ray from origin 
    177190                        minT = 0; 
    178 */ 
     191 
    179192                // bound ray 
    180193                if ((ray->GetType() == Ray::LOCAL_RAY) &&  
     
    185198                } 
    186199                 
    187                 int classification = ray->ClassifyPlane(mPlane, minT, maxT); 
    188                  
     200                const int classification = ray->ClassifyPlane(mPlane, minT, maxT); 
     201                 
     202                ray->SetId(classification); 
     203 
    189204                switch (classification) 
    190205                { 
    191                 case Plane3::COINCIDENT: 
     206                case Ray::COINCIDENT: 
    192207                        break; 
    193                 case Plane3::BACK_SIDE: 
    194                         ray->SetId(BACK_RAY); 
     208                case Ray::BACK: 
    195209                        backRays.push_back(ray); 
    196210                        break; 
    197                 case Plane3::FRONT_SIDE: 
    198                         ray->SetId(FRONT_RAY); 
     211                case Ray::FRONT: 
    199212                        frontRays.push_back(ray); 
    200213                        break; 
    201                 case Plane3::SPLIT: 
    202                         ray->SetId(SPLIT_RAY); 
     214                case Ray::FRONT_BACK: 
     215                        ray->SetId(Ray::FRONT_BACK); 
     216                        backRays.push_back(ray); 
     217                        ++ splits;                       
     218                        break; 
     219                case Ray::BACK_FRONT: 
    203220                        frontRays.push_back(ray); 
    204                         backRays.push_back(ray); 
    205                         //extp = splitPlane->FindIntersection(ray.GetLoc(), extp, &maxt); 
     221                        ++ splits; 
    206222                        break; 
    207223                default: 
     224                        Debug << "Should not come here" << endl; 
    208225                        break; 
    209226                } 
    210227        } 
     228 
     229        return splits; 
    211230} 
    212231 
     
    215234                                                           PolygonContainer &backPolys,  
    216235                                                           PolygonContainer &coincident, 
    217                                                            bool storePolys) 
     236                                                           const bool storePolys) 
    218237{ 
    219238        Polygon3 *splitPoly = NULL; 
     
    232251 
    233252                // classify polygon 
    234                 int classification = poly->ClassifyPlane(mPlane); 
     253                const int classification = poly->ClassifyPlane(mPlane); 
    235254 
    236255                Polygon3 *front_piece = NULL; 
     
    241260                switch (classification) 
    242261                { 
    243                         case Plane3::COINCIDENT: 
     262                        case Polygon3::COINCIDENT: 
    244263                                coincident.push_back(poly); 
    245264                                break;                   
    246                         case Plane3::FRONT_SIDE:         
     265                        case Polygon3::FRONT_SIDE:       
    247266                                frontPolys.push_back(poly); 
    248267                                break; 
    249                         case Plane3::BACK_SIDE: 
     268                        case Polygon3::BACK_SIDE: 
    250269                                backPolys.push_back(poly); 
    251270                                break; 
    252                         case Plane3::SPLIT: 
     271                        case Polygon3::SPLIT: 
    253272                                front_piece = new Polygon3(poly->mParent); 
    254273                                back_piece = new Polygon3(poly->mParent); 
     
    262281                                ++ splits; // increase number of splits 
    263282 
    264                                 //-- inherit rays 
    265                                 if (poly->mPiercingRays) 
    266                                         InheritRays(*poly, *front_piece, *back_piece); 
    267  
     283                                //-- inherit rays from parent polygon 
     284                                poly->InheritRays(*front_piece, *back_piece); 
     285                                Debug << "p: " << poly->mPiercingRays.size() << " f: " << front_piece->mPiercingRays.size() << " b: " << back_piece->mPiercingRays.size() << endl; 
     286                                 
    268287                                // check if polygons still valid  
    269288                                if (front_piece->Valid()) 
     
    280299                                Debug << "split " << *poly << endl << *front_piece << endl << *back_piece << endl; 
    281300#endif 
    282                                 ProcessPolygon(&poly, storePolys); 
    283                                  
     301                                ProcessPolygon(&poly, storePolys);                       
    284302                                break; 
    285303                        default: 
     
    290308 
    291309        return splits; 
    292 } 
    293  
    294 void BspInterior::InheritRays(const Polygon3 &poly,  
    295                                                       Polygon3 &front_piece,  
    296                                                       Polygon3 &back_piece) 
    297 { 
    298         RayContainer *rays = poly.mPiercingRays; 
    299  
    300         RayContainer::const_iterator it, it_end = rays->end(); 
    301  
    302         for (it = rays->begin(); it != it_end; ++ it) 
    303         { 
    304                 switch((*it)->GetId()) 
    305                 { 
    306                 case BACK_RAY: 
    307                         back_piece.GetPiercingRays()->push_back(*it); 
    308                         break; 
    309                 case FRONT_RAY: 
    310                         front_piece.GetPiercingRays()->push_back(*it); 
    311                         break; 
    312                 } 
    313         } 
    314310} 
    315311 
     
    664660                        if (it != facePolyMap.end())  
    665661                        { 
    666                                 (*it).second->AddPiercingRay(ray); 
     662                                (*it).second->mPiercingRays.push_back(ray); 
    667663                        }  
    668664                        else 
     
    670666                                Polygon3 *poly = new Polygon3(face, obj->GetMesh()); 
    671667                                polys->push_back(poly); 
    672                                 poly->AddPiercingRay(ray); 
     668                                poly->mPiercingRays.push_back(ray); 
    673669 
    674670                                facePolyMap[face] = poly; 
     
    842838                                                                        PolygonContainer &coincident, 
    843839                                                                        RayContainer &rays, 
    844                                                                         RayContainer &backRays, 
    845                                                                         RayContainer &frontRays) 
     840                                                                        RayContainer &frontRays, 
     841                                                                        RayContainer &backRays) 
    846842{ 
    847843        mStat.nodes += 2; 
     
    855851#endif 
    856852         
    857         // partition rays 
    858         interior->SplitRays(rays, frontRays, backRays); 
     853        // subdivide rays into front and back rays 
     854        interior->SplitRays(rays, frontRays, backRays, mBox); 
    859855         
    860856        // split polygons with split plane 
     
    987983} 
    988984 
     985bool BspTree::SelectAxisAlignedPlane(Plane3 &plane,  
     986                                                                         const PolygonContainer &polys) const 
     987{ 
     988        AxisAlignedBox3 box; 
     989        box.Initialize(); 
     990         
     991        // create bounding box of region 
     992        Polygon3::IncludeInBox(polys, box); 
     993         
     994        int objectsBack = 0, objectsFront = 0; 
     995        int axis = 0; 
     996        float costRatio = MAX_FLOAT; 
     997        Vector3 position; 
     998 
     999        //-- area subdivision 
     1000        for (int i = 0; i < 3; ++ i)  
     1001        { 
     1002                float p = 0; 
     1003                float r = BestCostRatio(polys, box, i, p, objectsBack, objectsFront); 
     1004                 
     1005                if (r < costRatio) 
     1006                { 
     1007                        costRatio = r; 
     1008                        axis = i; 
     1009                        position = p; 
     1010                } 
     1011        } 
     1012         
     1013        if (costRatio >= sMaxCostRatio) 
     1014                return false; 
     1015 
     1016        Vector3 norm(0,0,0); norm[axis] = 1.0f; 
     1017        plane = Plane3(norm, position); 
     1018 
     1019        return true; 
     1020} 
     1021 
    9891022Plane3 BspTree::SelectPlane(BspLeaf *leaf,  
    9901023                                                        PolygonContainer &polys,  
    9911024                                                        const RayContainer &rays) 
    9921025{ 
    993         if (polys.size() == 0) 
    994         { 
    995                 Debug << "Warning: No split candidate available\n"; 
    996                 return Plane3(); 
     1026        if (polys.empty()) 
     1027        { 
     1028                Debug << "Warning: No autopartition polygon candidate available\n"; 
     1029         
     1030                // return axis aligned split 
     1031                AxisAlignedBox3 box; 
     1032                box.Initialize(); 
     1033         
     1034                // create bounding box of region 
     1035                Polygon3::IncludeInBox(polys, box); 
     1036 
     1037                const int axis = box.Size().DrivingAxis(); 
     1038                const Vector3 position = (box.Min()[axis] + box.Max()[axis])*0.5f; 
     1039 
     1040                Vector3 norm(0,0,0); norm[axis] = 1.0f; 
     1041                return Plane3(norm, position); 
    9971042        } 
    9981043 
     
    10001045                ((int)polys.size() > sTermMaxPolysForAxisAligned)) 
    10011046        { 
    1002                 AxisAlignedBox3 box; 
    1003                 box.Initialize(); 
    1004          
    1005                 // todo: area subdivision 
    1006                 Polygon3::IncludeInBox(polys, box); 
    1007          
    1008                 int objectsBack = 0, objectsFront = 0; 
    1009                 int axis = 0; 
    1010                 float costRatio = MAX_FLOAT; 
    1011                 Vector3 position; 
    1012  
    1013                 for (int i = 0; i < 3; ++ i)  
    1014                 { 
    1015                         float p = 0; 
    1016                         float r = BestCostRatio(polys, box, i, p, objectsBack, objectsFront); 
    1017                          
    1018                         if (r < costRatio) 
    1019                         { 
    1020                                 costRatio = r; 
    1021                                 axis = i; 
    1022                                 position = p; 
    1023                         } 
    1024                 } 
    1025                  
    1026                 if (costRatio < sMaxCostRatio) 
    1027                 { 
    1028                         Vector3 norm(0,0,0); norm[axis] = 1.0f; 
    1029                         return Plane3(norm, position); 
    1030                 } 
     1047                Plane3 plane; 
     1048                if (SelectAxisAlignedPlane(plane, polys)) 
     1049                        return plane; 
    10311050        } 
    10321051 
     
    10741093int BspTree::GetNextCandidateIdx(int currentIdx, PolygonContainer &polys) 
    10751094{ 
    1076         int candidateIdx = Random(currentIdx --); 
     1095        const int candidateIdx = Random(currentIdx --); 
    10771096 
    10781097        // swap candidates to avoid testing same plane 2 times 
     
    11011120        // needed for balanced view cells criterium 
    11021121        ViewCell::NewMail(); 
    1103         int backId = ViewCell::sMailId; 
     1122        const int backId = ViewCell::sMailId; 
    11041123        ViewCell::NewMail(); 
    1105         int frontId = ViewCell::sMailId; 
     1124        const int frontId = ViewCell::sMailId; 
    11061125        ViewCell::NewMail(); 
    1107         int frontAndBackId = ViewCell::sMailId; 
     1126        const int frontAndBackId = ViewCell::sMailId; 
    11081127 
    11091128        PolygonContainer::const_iterator it, it_end = polys.end(); 
     
    11111130        for (it = polys.begin(); it != it_end; ++ it) 
    11121131        { 
    1113                 int classification = (*it)->ClassifyPlane(candidatePlane); 
     1132                const int classification = (*it)->ClassifyPlane(candidatePlane); 
    11141133 
    11151134                if (sSplitPlaneStrategy & BALANCED_POLYS) 
    1116                         sumBalancedPolys += sBalancedTreeTable[classification]; 
     1135                        sumBalancedPolys += sBalancedPolysTable[classification]; 
    11171136                 
    11181137                if (sSplitPlaneStrategy & LEAST_SPLITS) 
    1119                         sumSplits += sLeastSplitsTable[classification]; 
     1138                        sumSplits += sLeastPolySplitsTable[classification]; 
    11201139 
    11211140                if (sSplitPlaneStrategy & LARGEST_POLY_AREA) 
    11221141                { 
    1123                         if (classification == Plane3::COINCIDENT) 
     1142                        if (classification == Polygon3::COINCIDENT) 
    11241143                                sumPolyArea += (*it)->GetArea(); 
    11251144                        //totalArea += area; 
     
    11281147                if (sSplitPlaneStrategy & BLOCKED_RAYS) 
    11291148                { 
    1130                         float blockedRays = (float)(*it)->GetPiercingRays()->size(); 
    1131                  
    1132                         if (classification == Plane3::COINCIDENT) 
     1149                        const float blockedRays = (float)(*it)->mPiercingRays.size(); 
     1150                 
     1151                        if (classification == Polygon3::COINCIDENT) 
    11331152                                sumBlockedRays += blockedRays; 
    11341153                         
     
    11431162                        // assure that we only count a view cell  
    11441163                        // once for the front and once for the back side of the plane 
    1145                         if (classification == Plane3::FRONT_SIDE) 
     1164                        if (classification == Polygon3::FRONT_SIDE) 
    11461165                        { 
    11471166                                if ((viewCell->mMailbox != frontId) &&  
     
    11581177                                } 
    11591178                        } 
    1160                         else if (classification == Plane3::BACK_SIDE) 
     1179                        else if (classification == Polygon3::BACK_SIDE) 
    11611180                        { 
    11621181                                if ((viewCell->mMailbox != backId) && 
     
    11901209        if (sSplitPlaneStrategy & BLOCKED_RAYS) 
    11911210                if (totalBlockedRays != 0) 
    1192                         val += sBlockedRaysFactor * sumBlockedRays / totalBlockedRays; 
     1211                        val += sBlockedRaysFactor * (totalBlockedRays - sumBlockedRays) / totalBlockedRays; 
    11931212 
    11941213        if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) 
     
    12181237         
    12191238                // test with tree bounding box 
    1220                 /*if (!mBox.GetMinMaxT(*ray, &minT, &maxT)) 
     1239                if (!mBox.GetMinMaxT(*ray, &minT, &maxT)) 
    12211240                        continue; 
    12221241                if (minT < 0) // start ray from origin 
    1223                         minT = 0;*/ 
     1242                        minT = 0; 
    12241243 
    12251244                // bound ray 
     
    12311250                } 
    12321251 
    1233                 int classification = ray->ClassifyPlane(candidatePlane, minT, maxT); 
     1252                const int classification =  
     1253                        ray->ClassifyPlane(candidatePlane, minT, maxT); 
    12341254 
    12351255                if (sSplitPlaneStrategy & LEAST_RAY_SPLITS) 
    12361256                { 
    1237                         sumBalancedRays += sBalancedTreeTable[classification]; 
     1257                        sumBalancedRays += sBalancedRaysTable[classification]; 
    12381258                } 
    12391259                 
    12401260                if (sSplitPlaneStrategy & BALANCED_RAYS) 
    12411261                { 
    1242                         sumRaySplits += sLeastSplitsTable[classification]; 
     1262                        sumRaySplits += sLeastRaySplitsTable[classification]; 
    12431263                } 
    12441264        } 
     
    13321352        environment->GetBoolValue("BspTree.storeSplitPolys", sStoreSplitPolys); 
    13331353 
    1334         environment->GetFloatValue("BspTree.Construction.sideTolerance", Polygon3::sSideTolerance); 
    1335         Polygon3::sSideToleranceSqrt = Polygon3::sSideTolerance * Polygon3::sSideTolerance; 
     1354        environment->GetFloatValue("BspTree.Construction.sideTolerance", Vector3::sDistTolerance); 
     1355        Vector3::sDistToleranceSqrt = Vector3::sDistTolerance * Vector3::sDistTolerance; 
    13361356 
    13371357    Debug << "BSP max depth: " << sTermMaxDepth << endl; 
     
    13791399                { 
    13801400                        BspInterior *interior = dynamic_cast<BspInterior *>(node); 
     1401 
    13811402                        nodeStack.push(interior->GetBack()); 
    13821403                        nodeStack.push(interior->GetFront()); 
     
    14171438        } 
    14181439         
    1419 #ifdef _DEBUG 
     1440//#ifdef _DEBUG 
    14201441        Debug << "BSP stats: " 
    14211442                  << "Depth: " << data.mDepth << " (max: " << sTermMaxDepth << "), " 
    14221443                  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << sTermMaxPolygons << "), " 
    14231444                  << "#rays: " << (int)data.mRays->size() << " (max: " << sTermMaxRays << ")" << endl; 
    1424 #endif 
     1445//#endif 
    14251446} 
    14261447 
     
    15201541                        entp = extp; 
    15211542                        mint = maxt; // NOTE: need this? 
     1543 
     1544                         if (ray.GetType() == Ray::LINE_SEGMENT && mint > 1.0f) 
     1545                                break; 
     1546 
    15221547                        BspRayTraversalData &s = tStack.top(); 
    15231548 
Note: See TracChangeset for help on using the changeset viewer.