Ignore:
Timestamp:
02/04/06 12:46:14 (18 years ago)
Author:
mattausch
Message:

updated vspkdtree for regular sudbivision

File:
1 edited

Legend:

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

    r582 r587  
    1010#include "Triangle3.h" 
    1111#include "Tetrahedron3.h" 
    12  
    13 #include <stack> 
    14  
     12#include "ViewCellsManager.h" 
    1513#include "Exporter.h" 
    1614#include "Plane3.h" 
     15#include <stack> 
    1716 
    1817//-- static members 
     
    214213BspTree::BspTree():   
    215214mRoot(NULL),  
    216 mUseAreaForPvs(true), 
     215mUseAreaForPvs(false), 
    217216mGenerateViewCells(true) 
    218217{ 
     
    227226        environment->GetIntValue("BspTree.Termination.minPolygons", mTermMinPolys); 
    228227        environment->GetIntValue("BspTree.Termination.minRays", mTermMinRays); 
    229         environment->GetFloatValue("BspTree.Termination.minArea", mTermMinArea);         
     228        environment->GetFloatValue("BspTree.Termination.minProbability", mTermMinProbability);   
    230229        environment->GetFloatValue("BspTree.Termination.maxRayContribution", mTermMaxRayContribution); 
    231230        environment->GetFloatValue("BspTree.Termination.minAccRayLenght", mTermMinAccRayLength); 
     
    258257        environment->GetFloatValue("BspTree.AxisAligned.splitBorder", mSplitBorder); 
    259258        environment->GetIntValue("BspTree.maxTests", mMaxTests); 
     259        environment->GetIntValue("BspTree.Termination.maxViewCells", mMaxViewCells); 
    260260 
    261261        environment->GetFloatValue("BspTree.Construction.epsilon", mEpsilon); 
     
    263263    Debug << "BSP max depth: " << mTermMaxDepth << endl; 
    264264        Debug << "BSP min PVS: " << mTermMinPvs << endl; 
    265         Debug << "BSP min area: " << mTermMinArea << endl; 
     265        Debug << "BSP min probability: " << mTermMinProbability << endl; 
    266266        Debug << "BSP max polys: " << mTermMinPolys << endl; 
    267267        Debug << "BSP max rays: " << mTermMinRays << endl; 
     
    413413                << maxCostNodes * 100 / (double)Leaves() << endl; 
    414414 
    415         app << "#N_PMINAREALEAVES  ( Percentage of leaves with mininum probability )\n" 
     415        app << "#N_PMINPROBABILITYAREALEAVES  ( Percentage of leaves with mininum probability )\n" 
    416416                << minProbabilityNodes * 100 / (double)Leaves() << endl; 
    417417 
     
    480480                                                                 new BoundedRayContainer(),  
    481481                                                                 0,  
    482                                                                  mBox.SurfaceArea(),  
     482                                                                 mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(),  
    483483                                                                 new BspNodeGeometry())); 
    484484 
     
    519519                                                                                   tData.mRays, 
    520520                                                                                   tData.mPvs, 
    521                                                                                    mBox.SurfaceArea(), 
     521                                                                                   mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(),  
    522522                                                                                   new BspNodeGeometry()); 
    523523 
     
    528528                                                                                  tData.mRays, 
    529529                                                                                  tData.mPvs, 
    530                                                                                   mBox.SurfaceArea(), 
     530                                                                                   mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(),  
    531531                                                                                  new BspNodeGeometry()); 
    532532 
     
    583583} 
    584584 
     585 
    585586int BspTree::AddToPolygonSoup(const ViewCellContainer &viewCells,  
    586587                                                          PolygonContainer &polys,  
     
    604605} 
    605606 
    606 int BspTree::AddToPolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects) 
    607 { 
    608         int limit = (maxObjects > 0) ? Min((int)objects.size(), maxObjects) : (int)objects.size(); 
     607 
     608int BspTree::AddToPolygonSoup(const ObjectContainer &objects, 
     609                                                          PolygonContainer &polys,  
     610                                                          int maxObjects, 
     611                                                          bool addToBbox) 
     612{ 
     613        int limit = (maxObjects > 0) ?  
     614                Min((int)objects.size(), maxObjects) : (int)objects.size(); 
    609615   
    610616        for (int i = 0; i < limit; ++i) 
     
    629635        if (mesh) // copy the mesh data to polygons 
    630636                { 
    631                         mBox.Include(object->GetBox()); // add to BSP tree aabb 
     637                        if (addToBbox) 
     638                        { 
     639                                mBox.Include(object->GetBox()); // add to BSP tree aabb 
     640                        } 
     641                 
    632642                        AddMeshToPolygons(mesh, polys, mRootCell); 
    633643                } 
     
    636646        return (int)polys.size(); 
    637647} 
     648 
    638649 
    639650void BspTree::Construct(const ViewCellContainer &viewCells) 
     
    668679} 
    669680 
    670 void BspTree::Construct(const RayContainer &sampleRays) 
     681 
     682void BspTree::Construct(const RayContainer &sampleRays, 
     683                                                AxisAlignedBox3 *forcedBoundingBox) 
    671684{ 
    672685    mStat.nodes = 1; 
    673686        mBox.Initialize();      // initialise BSP tree bounding box 
    674687         
     688        if (forcedBoundingBox) 
     689                mBox = *forcedBoundingBox; 
     690 
    675691        PolygonContainer *polys = new PolygonContainer(); 
    676692        BoundedRayContainer *rays = new BoundedRayContainer(); 
     
    724740 
    725741        // compute bounding box 
    726         Polygon3::IncludeInBox(*polys, mBox); 
     742        if (!forcedBoundingBox) 
     743                Polygon3::IncludeInBox(*polys, mBox); 
    727744 
    728745        //-- store rays 
     
    746763} 
    747764 
    748 void BspTree::Construct(const ObjectContainer &objects, const RayContainer &sampleRays) 
     765 
     766void BspTree::Construct(const ObjectContainer &objects,  
     767                                                const RayContainer &sampleRays, 
     768                                                AxisAlignedBox3 *forcedBoundingBox) 
    749769{ 
    750770    mStat.nodes = 1; 
    751771        mBox.Initialize();      // initialise BSP tree bounding box 
    752772         
     773        if (forcedBoundingBox) 
     774                mBox = *forcedBoundingBox; 
     775 
    753776        BoundedRayContainer *rays = new BoundedRayContainer(); 
    754777        PolygonContainer *polys = new PolygonContainer(); 
     
    757780 
    758781        // copy mesh instance polygons into one big polygon soup 
    759         mStat.polys = AddToPolygonSoup(objects, *polys); 
     782        mStat.polys = AddToPolygonSoup(objects, *polys, 0, !forcedBoundingBox); 
     783 
    760784 
    761785        RayContainer::const_iterator rit, rit_end = sampleRays.end(); 
     
    776800} 
    777801 
     802 
    778803void BspTree::Construct(PolygonContainer *polys, BoundedRayContainer *rays) 
    779804{ 
     
    786811        ConstructGeometry(mRoot, *geom); 
    787812 
    788         BspTraversalData tData(mRoot, polys, 0, mRootCell, rays,  
    789                                                    ComputePvsSize(*rays), geom->GetArea(), geom); 
     813        BspTraversalData tData(mRoot,  
     814                                                   polys,  
     815                                                   0,  
     816                                                   mRootCell,  
     817                                                   rays,  
     818                                                   ComputePvsSize(*rays),  
     819                                                   mUseAreaForPvs ? geom->GetArea() : geom->GetVolume(),  
     820                                                   geom); 
    790821 
    791822        tStack.push(tData); 
     
    804835 
    805836                if (r == mRoot) 
    806                         Debug << "BSP tree construction time spent at root: " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
     837            Debug << "BSP tree construction time spent at root: "  
     838                                  << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 
    807839        } 
    808840 
     
    818850                 ((int)data.mRays->size() <= mTermMinRays) || 
    819851                 (data.mPvs <= mTermMinPvs) || 
    820                  (data.mArea <= mTermMinArea) || 
     852                 (data.mProbability <= mTermMinProbability) || 
    821853                 (data.mDepth >= mTermMaxDepth) || 
    822                  (data.GetAvgRayContribution() < mTermMaxRayContribution)); 
     854                 (mStat.Leaves() >= mMaxViewCells) || 
     855                 (data.GetAvgRayContribution() > mTermMaxRayContribution)); 
    823856} 
    824857 
     
    842875                viewCell->mLeaf = leaf; 
    843876 
     877                if (mUseAreaForPvs) 
     878                        viewCell->SetArea(tData.mProbability); 
     879                else 
     880                        viewCell->SetVolume(tData.mProbability); 
     881                 
    844882                //-- add pvs 
    845883                if (viewCell != mRootCell) 
     
    880918                SubdivideNode(tData, tFrontData, tBackData, coincident); 
    881919 
    882 #ifdef _DEBUG    
    883 //      if (frontPolys->empty() && backPolys->empty() && (coincident.size() > 2)) 
    884 //      {       for (PolygonContainer::iterator it = coincident.begin(); it != coincident.end(); ++it) 
    885 //                      Debug << (*it) << " " << (*it)->GetArea() << " " << (*it)->mParent << endl ; 
    886 //              Debug << endl;} 
    887 #endif 
    888920 
    889921        // extract view cells from coincident polygons according to plane normal 
     
    951983        BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode); 
    952984 
    953         Debug << "*********************" << endl; 
    954         long startTime = GetTime(); 
     985        long startTime; 
     986        if (0) 
     987        { 
     988                Debug << "*********************" << endl; 
     989                startTime = GetTime(); 
     990        } 
    955991         
    956992        // select subdivision plane 
    957993        BspInterior *interior =  
    958994                new BspInterior(SelectPlane(leaf, tData));  
    959         Debug << "time used for split plane selection: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 
     995         
     996        if (0) 
     997        { 
     998                Debug << "time used for split plane selection: "  
     999                          << TimeDiff(startTime, GetTime()) * 1e-3 << "s" << endl; 
     1000        } 
    9601001#ifdef _DEBUG 
    9611002        Debug << interior << endl; 
     
    9631004         
    9641005 
    965         Debug << "number of rays: " << (int)tData.mRays->size() << endl; 
    966         Debug << "number of polys: " << (int)tData.mPolygons->size() << endl; 
    967  
    968         startTime = GetTime(); 
     1006        if (0) 
     1007        { 
     1008                Debug << "number of rays: " << (int)tData.mRays->size() << endl; 
     1009                Debug << "number of polys: " << (int)tData.mPolygons->size() << endl; 
     1010 
     1011                startTime = GetTime(); 
     1012        }        
    9691013         
    9701014        // subdivide rays into front and back rays 
    9711015        SplitRays(interior->mPlane, *tData.mRays, *frontData.mRays, *backData.mRays); 
    9721016         
    973         Debug << "time used for rays splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 
    974  
    975         startTime = GetTime(); 
     1017        if (0) 
     1018        { 
     1019                Debug << "time used for rays splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 
     1020                startTime = GetTime(); 
     1021        } 
     1022 
    9761023        // subdivide polygons with plane 
    9771024        mStat.polySplits += SplitPolygons(interior->GetPlane(), 
     
    9811028                                                                          coincident); 
    9821029 
    983         Debug << "time used for polygon splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 
     1030        if (0) 
     1031        { 
     1032                Debug << "time used for polygon splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 
     1033        } 
    9841034 
    9851035    // compute pvs 
     
    9971047         
    9981048                 
    999                 frontData.mArea = frontData.mGeometry->GetArea(); 
    1000                 backData.mArea = backData.mGeometry->GetArea(); 
     1049                frontData.mProbability = frontData.mGeometry->GetVolume(); 
     1050                backData.mProbability = backData.mGeometry->GetVolume(); 
    10011051        } 
    10021052 
     
    11861236 
    11871237                const int axis = box.Size().DrivingAxis(); 
    1188                 const Vector3 position = (box.Min()[axis] + box.Max()[axis])*0.5f; 
     1238                const Vector3 position = (box.Min()[axis] + box.Max()[axis]) * 0.5f; 
    11891239 
    11901240                Vector3 norm(0,0,0); norm[axis] = 1.0f; 
     
    11961246                ((int)data.mRays->size() > mTermMinRaysForAxisAligned) && 
    11971247                ((mTermMinObjectsForAxisAligned < 0) ||  
    1198                   (Polygon3::ParentObjectsSize(*data.mPolygons) > mTermMinObjectsForAxisAligned))) 
     1248                 (Polygon3::ParentObjectsSize(*data.mPolygons) > mTermMinObjectsForAxisAligned))) 
    11991249        { 
    12001250                Plane3 plane; 
     
    13291379                // assure that no index is taken twice 
    13301380                const int candidateIdx = (int)RandomValue(0, (Real)(-- maxIdx)); 
    1331                 //Debug << "current Idx: " << maxIdx << " cand idx " << candidateIdx << endl; 
    1332                  
     1381                                 
    13331382                Polygon3 *poly = (*data.mPolygons)[candidateIdx]; 
    13341383 
    13351384                // swap candidate to the end to avoid testing same plane 
    13361385                std::swap((*data.mPolygons)[maxIdx], (*data.mPolygons)[candidateIdx]); 
    1337          
    13381386                //Polygon3 *poly = (*data.mPolygons)[(int)RandomValue(0, (int)polys.size() - 1)]; 
    13391387 
     
    15171565                                                          const BoundedRayContainer &rays, 
    15181566                                                          const int pvs, 
    1519                                                           const float area, 
     1567                                                          const float probability, 
    15201568                                                          const BspNodeGeometry &cell) const 
    15211569{ 
     
    15401588                GenerateUniqueIdsForPvs(); 
    15411589 
    1542                 if (mUseAreaForPvs) // use front and back cell areas to approximate volume 
    1543                 { 
    1544                         // construct child geometry with regard to the candidate split plane 
    1545                         BspNodeGeometry frontCell; 
    1546                         BspNodeGeometry backCell; 
    1547  
    1548                         cell.SplitGeometry(frontCell,  
    1549                                                            backCell,  
    1550                                                            candidatePlane, 
    1551                                                            mBox, 
    1552                                                            mEpsilon); 
    1553                  
     1590                // construct child geometry with regard to the candidate split plane 
     1591                BspNodeGeometry frontCell; 
     1592                BspNodeGeometry backCell; 
     1593 
     1594                cell.SplitGeometry(frontCell,  
     1595                                                   backCell,  
     1596                                                   candidatePlane, 
     1597                                                   mBox, 
     1598                                                   mEpsilon); 
     1599 
     1600                if (mUseAreaForPvs) 
     1601                { 
    15541602                        pFront = frontCell.GetArea(); 
    15551603                        pBack = backCell.GetArea(); 
    1556  
    1557                         pOverall = area; 
    1558                 } 
     1604                } 
     1605                else 
     1606                { 
     1607                        pFront = frontCell.GetVolume(); 
     1608                        pBack = backCell.GetVolume(); 
     1609                } 
     1610                 
     1611 
     1612                pOverall = probability; 
    15591613        } 
    15601614                         
     
    16111665                        // add the source object 
    16121666                        AddObjToPvs(ray->sourceObject.mObject, cf, frontPvs, backPvs); 
    1613                          
    1614                         if (mUseAreaForPvs) 
    1615                         { 
    1616                                 float len = 1; 
    1617                          
    1618                                 if (pvsUseLen) 
    1619                                         len = SqrDistance(entP, extP); 
    1620          
    1621                                 // use length of rays to approximate volume 
    1622                                 if (Ray::BACK && Ray::COINCIDENT) 
    1623                                         pBack += len; 
    1624                                 if (Ray::FRONT && Ray::COINCIDENT) 
    1625                                         pFront += len; 
    1626                                 if (Ray::FRONT_BACK || Ray::BACK_FRONT) 
    1627                                 { 
    1628                                         if (pvsUseLen) 
    1629                                         { 
    1630                                                 const Vector3 extp = ray->Extrap(maxT); 
    1631                                                 const float t = candidatePlane.FindT(ray->GetLoc(), extp); 
    1632                                  
    1633                                                 const float newT = t * maxT; 
    1634                                                 const float newLen = SqrDistance(ray->Extrap(newT), extp); 
    1635  
    1636                                                 if (Ray::FRONT_BACK) 
    1637                                                 { 
    1638                                                         pFront += len - newLen; 
    1639                                                         pBack += newLen; 
    1640                                                 } 
    1641                                                 else 
    1642                                                 { 
    1643                                                         pBack += len - newLen; 
    1644                                                         pFront += newLen; 
    1645                                                 } 
    1646                                         } 
    1647                                         else 
    1648                                         { 
    1649                                                 ++ pFront; 
    1650                                                 ++ pBack; 
    1651                                         } 
    1652                                 } 
    1653                         } 
    16541667                } 
    16551668        } 
     
    17601773        { 
    17611774                val += SplitPlaneCost(candidatePlane, *data.mRays, data.mPvs,  
    1762                                                           data.mArea, *data.mGeometry); 
     1775                                                          data.mProbability, *data.mGeometry); 
    17631776        } 
    17641777 
     
    18341847                ++ mStat.maxRayContribNodes; 
    18351848         
    1836         if (data.mGeometry->GetArea() <= mTermMinArea)  
     1849        if (data.mProbability <= mTermMinProbability)  
    18371850                ++ mStat.minProbabilityNodes; 
    18381851 
     
    18411854                  << "Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), " 
    18421855                  << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), " 
    1843                   << "Area: " << data.mArea << " (min: " << mTermMinArea << "), " 
     1856                  << "Probability: " << data.mProbability << " (min: " << mTermMinProbability << "), " 
    18441857                  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << mTermMinPolys << "), " 
    18451858                  << "#rays: " << (int)data.mRays->size() << " (max: " << mTermMinRays << "), "  
     
    22072220} 
    22082221 
    2209 void BspTree::ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const 
    2210 { 
    2211         // TODO 
    2212 /*      vector<BspLeaf *> leaves = vc->mLeaves; 
    2213  
    2214         vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
     2222 
     2223 
     2224void BspTree::ConstructGeometry(ViewCell *vc,  
     2225                                                                BspNodeGeometry &vcGeom) const 
     2226{ 
     2227        ViewCellContainer leaves; 
     2228        mViewCellsManager->GetViewCellsTree()->CollectLeaves(vc, leaves); 
     2229 
     2230        ViewCellContainer::const_iterator it, it_end = leaves.end(); 
    22152231 
    22162232        for (it = leaves.begin(); it != it_end; ++ it) 
    2217                 ConstructGeometry(*it, geom);*/ 
     2233        { 
     2234                BspLeaf *l = dynamic_cast<BspViewCell *>(*it)->mLeaf; 
     2235                ConstructGeometry(l, vcGeom); 
     2236        } 
     2237} 
     2238 
     2239 
     2240void BspTree::SetViewCellsManager(ViewCellsManager *vcm) 
     2241{ 
     2242        mViewCellsManager = vcm; 
    22182243} 
    22192244 
     
    23012326 
    23022327 
    2303 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,  
     2328typedef pair<BspNode *, BspNodeGeometry *> bspNodePair; 
     2329 
     2330 
     2331int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 
    23042332                                                   const bool onlyUnmailed) const 
    23052333{ 
    2306         BspNodeGeometry geom; 
    2307         ConstructGeometry(n, geom); 
    2308  
    2309         stack<BspNode *> nodeStack; 
    2310         nodeStack.push(mRoot); 
    2311                  
    2312         // planes needed to verify that we found neighbor leaf. 
     2334        stack<bspNodePair> nodeStack; 
     2335         
     2336        BspNodeGeometry nodeGeom; 
     2337        ConstructGeometry(n, nodeGeom); 
     2338         
     2339        // split planes from the root to this node 
     2340        // needed to verify that we found neighbor leaf 
     2341        // TODO: really needed? 
    23132342        vector<Plane3> halfSpaces; 
    23142343        ExtractHalfSpaces(n, halfSpaces); 
    23152344 
    2316         while (!nodeStack.empty())  
    2317         { 
    2318                 BspNode *node = nodeStack.top(); 
     2345 
     2346        BspNodeGeometry *rgeom = new BspNodeGeometry(); 
     2347        ConstructGeometry(mRoot, *rgeom); 
     2348 
     2349        nodeStack.push(bspNodePair(mRoot, rgeom)); 
     2350 
     2351        while (!nodeStack.empty()) 
     2352        { 
     2353                BspNode *node = nodeStack.top().first; 
     2354                BspNodeGeometry *geom = nodeStack.top().second; 
     2355         
    23192356                nodeStack.pop(); 
    23202357 
    23212358                if (node->IsLeaf()) 
    23222359                { 
    2323             if (node != n && (!onlyUnmailed || !node->Mailed())) 
     2360                        // test if this leaf is in valid view space 
     2361                        if (node->TreeValid() && 
     2362                                (node != n) &&  
     2363                                (!onlyUnmailed || !node->Mailed())) 
    23242364                        { 
    2325                                 // test all planes of current node if neighbour  
    2326                                 // candidate really is neighbour 
    2327                                 BspNodeGeometry candidateGeom; 
    2328                                 ConstructGeometry(node, candidateGeom); 
    2329                                  
    23302365                                bool isAdjacent = true; 
    2331                                 for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i) 
     2366 
     2367                                if (1) 
    23322368                                { 
    2333                                         const int cf =  
    2334                                                 Polygon3::ClassifyPlane(candidateGeom.mPolys,  
    2335                                                                                                 halfSpaces[i], 
    2336                                                                                                 mEpsilon); 
    2337  
    2338                                         if (cf == Polygon3::BACK_SIDE) 
    2339                                                 isAdjacent = false; 
     2369                                        // test all planes of current node if still adjacent 
     2370                                        for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i) 
     2371                                        { 
     2372                                                const int cf = 
     2373                                                        Polygon3::ClassifyPlane(geom->mPolys, 
     2374                                                                                                        halfSpaces[i], 
     2375                                                                                                        mEpsilon); 
     2376 
     2377                                                if (cf == Polygon3::BACK_SIDE) 
     2378                                                { 
     2379                                                        isAdjacent = false; 
     2380                                                } 
     2381                                        } 
    23402382                                } 
    2341  
     2383                                else 
     2384                                { 
     2385                                        // TODO: why is this wrong?? 
     2386                                        // test all planes of current node if still adjacent 
     2387                                        for (int i = 0; (i < (int)nodeGeom.mPolys.size()) && isAdjacent; ++ i) 
     2388                                        { 
     2389                                                Polygon3 *poly = nodeGeom.mPolys[i]; 
     2390 
     2391                                                const int cf = 
     2392                                                        Polygon3::ClassifyPlane(geom->mPolys, 
     2393                                                                                                        poly->GetSupportingPlane(), 
     2394                                                                                                        mEpsilon); 
     2395 
     2396                                                if (cf == Polygon3::BACK_SIDE) 
     2397                                                { 
     2398                                                        isAdjacent = false; 
     2399                                                } 
     2400                                        } 
     2401                                } 
     2402                                // neighbor was found 
    23422403                                if (isAdjacent) 
     2404                                {        
    23432405                                        neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 
     2406                                } 
    23442407                        } 
    23452408                } 
    2346                 else  
     2409                else 
    23472410                { 
    23482411                        BspInterior *interior = dynamic_cast<BspInterior *>(node); 
    2349          
    2350                         const int cf = Polygon3::ClassifyPlane(geom.mPolys,  
    2351                                                                                                    interior->mPlane, 
     2412 
     2413                        const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys, 
     2414                                                                                                   interior->GetPlane(), 
    23522415                                                                                                   mEpsilon); 
    2353  
     2416                         
     2417                        BspNode *front = interior->GetFront(); 
     2418                        BspNode *back = interior->GetBack(); 
     2419             
     2420                        BspNodeGeometry *fGeom = new BspNodeGeometry(); 
     2421                        BspNodeGeometry *bGeom = new BspNodeGeometry(); 
     2422 
     2423                        geom->SplitGeometry(*fGeom, 
     2424                                                                *bGeom, 
     2425                                                                interior->GetPlane(), 
     2426                                                                mBox, 
     2427                                                                mEpsilon); 
     2428                 
    23542429                        if (cf == Polygon3::FRONT_SIDE) 
    2355                                 nodeStack.push(interior->GetFront()); 
     2430                        { 
     2431                                nodeStack.push(bspNodePair(interior->GetFront(), fGeom)); 
     2432                                DEL_PTR(bGeom); 
     2433                        } 
    23562434                        else 
     2435                        { 
    23572436                                if (cf == Polygon3::BACK_SIDE) 
    2358                                         nodeStack.push(interior->GetBack()); 
    2359                                 else  
    23602437                                { 
    2361                                         // random decision 
    2362                                         nodeStack.push(interior->GetBack()); 
    2363                                         nodeStack.push(interior->GetFront()); 
     2438                                        nodeStack.push(bspNodePair(interior->GetBack(), bGeom)); 
     2439                                        DEL_PTR(fGeom); 
    23642440                                } 
    2365                 } 
    2366         } 
    2367          
     2441                                else 
     2442                                {       // random decision 
     2443                                        nodeStack.push(bspNodePair(front, fGeom)); 
     2444                                        nodeStack.push(bspNodePair(back, bGeom)); 
     2445                                } 
     2446                        } 
     2447                } 
     2448         
     2449                DEL_PTR(geom); 
     2450        } 
     2451 
    23682452        return (int)neighbors.size(); 
    23692453} 
     
    24212505} 
    24222506 
     2507 
    24232508BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 
    24242509{ 
     
    24552540        return NULL; 
    24562541} 
     2542 
    24572543 
    24582544void BspTree::AddToPvs(BspLeaf *leaf, 
     
    24952581} 
    24962582 
     2583 
    24972584int BspTree::ComputePvsSize(const BoundedRayContainer &rays) const 
    24982585{ 
     
    25282615} 
    25292616 
     2617 
    25302618float BspTree::GetEpsilon() const 
    25312619{ 
     
    25342622 
    25352623 
    2536 /*************************************************************/ 
    2537 /*            BspNodeGeometry Implementation                 */ 
    2538 /*************************************************************/ 
     2624int BspTree::CollectMergeCandidates(const vector<BspLeaf *> leaves, 
     2625                                                                        vector<MergeCandidate> &candidates) 
     2626{ 
     2627        BspLeaf::NewMail(); 
     2628         
     2629        vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
     2630 
     2631        int numCandidates = 0; 
     2632 
     2633        // find merge candidates and push them into queue 
     2634        for (it = leaves.begin(); it != it_end; ++ it) 
     2635        { 
     2636                BspLeaf *leaf = *it; 
     2637                 
     2638                // the same leaves must not be part of two merge candidates 
     2639                leaf->Mail(); 
     2640                vector<BspLeaf *> neighbors; 
     2641                FindNeighbors(leaf, neighbors, true); 
     2642 
     2643                vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end(); 
     2644 
     2645                // TODO: test if at least one ray goes from one leaf to the other 
     2646                for (nit = neighbors.begin(); nit != nit_end; ++ nit) 
     2647                { 
     2648                        if ((*nit)->GetViewCell() != leaf->GetViewCell()) 
     2649                        { 
     2650                                MergeCandidate mc(leaf->GetViewCell(), (*nit)->GetViewCell()); 
     2651                                candidates.push_back(mc); 
     2652 
     2653                                ++ numCandidates; 
     2654                                if ((numCandidates % 1000) == 0) 
     2655                                { 
     2656                                        cout << "collected " << numCandidates << " merge candidates" << endl; 
     2657                                } 
     2658                        } 
     2659                } 
     2660        } 
     2661 
     2662        Debug << "merge queue: " << (int)candidates.size() << endl; 
     2663        Debug << "leaves in queue: " << numCandidates << endl; 
     2664         
     2665 
     2666        return (int)leaves.size(); 
     2667} 
     2668 
     2669 
     2670int BspTree::CollectMergeCandidates(const VssRayContainer &rays,  
     2671                                                                        vector<MergeCandidate> &candidates) 
     2672{ 
     2673        ViewCell::NewMail(); 
     2674        long startTime = GetTime(); 
     2675         
     2676        map<BspLeaf *, vector<BspLeaf*> > neighborMap; 
     2677        ViewCellContainer::const_iterator iit; 
     2678 
     2679        int numLeaves = 0; 
     2680         
     2681        BspLeaf::NewMail(); 
     2682 
     2683        for (int i = 0; i < (int)rays.size(); ++ i) 
     2684        {   
     2685                VssRay *ray = rays[i]; 
     2686         
     2687                // traverse leaves stored in the rays and compare and  
     2688                // merge consecutive leaves (i.e., the neighbors in the tree) 
     2689                if (ray->mViewCells.size() < 2) 
     2690                        continue; 
     2691//TODO viewcellhierarchy 
     2692                iit = ray->mViewCells.begin(); 
     2693                BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*(iit ++)); 
     2694                BspLeaf *leaf = bspVc->mLeaf; 
     2695                 
     2696                // traverse intersections  
     2697                // consecutive leaves are neighbors => add them to queue 
     2698                for (; iit != ray->mViewCells.end(); ++ iit) 
     2699                { 
     2700                        // next pair 
     2701                        BspLeaf *prevLeaf = leaf; 
     2702                        bspVc = dynamic_cast<BspViewCell *>(*iit); 
     2703            leaf = bspVc->mLeaf; 
     2704 
     2705                        // view space not valid or same view cell 
     2706                        if (!leaf->TreeValid() || !prevLeaf->TreeValid() || 
     2707                                (leaf->GetViewCell() == prevLeaf->GetViewCell())) 
     2708                                continue; 
     2709 
     2710                vector<BspLeaf *> &neighbors = neighborMap[leaf]; 
     2711                         
     2712                        bool found = false; 
     2713 
     2714                        // both leaves inserted in queue already => 
     2715                        // look if double pair already exists 
     2716                        if (leaf->Mailed() && prevLeaf->Mailed()) 
     2717                        { 
     2718                                vector<BspLeaf *>::const_iterator it, it_end = neighbors.end(); 
     2719                                 
     2720                for (it = neighbors.begin(); !found && (it != it_end); ++ it) 
     2721                                        if (*it == prevLeaf) 
     2722                                                found = true; // already in queue 
     2723                        } 
     2724                 
     2725                        if (!found) 
     2726                        { 
     2727                                // this pair is not in map yet 
     2728                                // => insert into the neighbor map and the queue 
     2729                                neighbors.push_back(prevLeaf); 
     2730                                neighborMap[prevLeaf].push_back(leaf); 
     2731 
     2732                                leaf->Mail(); 
     2733                                prevLeaf->Mail(); 
     2734                 
     2735                                MergeCandidate mc(leaf->GetViewCell(), prevLeaf->GetViewCell()); 
     2736                                 
     2737                                candidates.push_back(mc); 
     2738 
     2739                                if (((int)candidates.size() % 1000) == 0) 
     2740                                { 
     2741                                        cout << "collected " << (int)candidates.size() << " merge candidates" << endl; 
     2742                                } 
     2743                        } 
     2744        } 
     2745        } 
     2746 
     2747        Debug << "neighbormap size: " << (int)neighborMap.size() << endl; 
     2748        Debug << "merge queue: " << (int)candidates.size() << endl; 
     2749        Debug << "leaves in queue: " << numLeaves << endl; 
     2750 
     2751 
     2752        //-- collect the leaves which haven't been found by ray casting 
     2753#if 0 
     2754        cout << "finding additional merge candidates using geometry" << endl; 
     2755        vector<BspLeaf *> leaves; 
     2756        CollectLeaves(leaves, true); 
     2757        Debug << "found " << (int)leaves.size() << " new leaves" << endl << endl; 
     2758        CollectMergeCandidates(leaves, candidates); 
     2759#endif 
     2760 
     2761        return numLeaves; 
     2762} 
     2763 
     2764 
     2765 
     2766 
     2767/***************************************************************/ 
     2768/*              BspNodeGeometry Implementation                 */ 
     2769/***************************************************************/ 
    25392770 
    25402771 
     
    25742805 
    25752806        // note: can take arbitrary point, e.g., the origin. However, 
    2576         // center of mass prevents precision errors 
     2807        // we rather take the center of mass to prevents precision errors 
    25772808        const Vector3 center = CenterOfMass(); 
    25782809 
     
    27012932                front.mPolys.push_back(planePoly->CreateReversePolygon()); 
    27022933        } 
    2703  
    2704         //Debug << "returning new geometry " << mPolys.size() << " f: " << front.mPolys.size() << " b: " << back.mPolys.size() << endl; 
    2705         //Debug << "old area " << GetArea() << " f: " << front.GetArea() << " b: " << back.GetArea() << endl; 
    27062934} 
    27072935 
Note: See TracChangeset for help on using the changeset viewer.