Ignore:
Timestamp:
12/30/05 12:08:15 (19 years ago)
Author:
mattausch
Message:

changed castlinesegment of vspbpstree
changed rayinfo ray classification for bsp tree
implemented shuffling

File:
1 edited

Legend:

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

    r484 r485  
    3333int VspBspTree::sFrontAndBackId = 0; 
    3434 
    35 float BspMergeCandidate::sOverallCost = Limits::Small; 
     35float BspMergeCandidate::sOverallCost = 0; 
    3636 
    3737/****************************************************************/ 
     
    4444mCostNormalizer(Limits::Small), 
    4545mViewCellsManager(NULL), 
    46 mStoreRays(true), 
     46mStoreRays(false), 
    4747mOnlyDrivingAxis(false) 
    4848{ 
    49         mRootCell = new BspViewCell(); 
    50  
    5149        Randomize(); // initialise random generator for heuristics 
    5250 
     
    8280        environment->GetFloatValue("VspBspTree.PostProcess.maxCostRatio", mMergeMaxCostRatio); 
    8381 
     82        environment->GetBoolValue("VspBspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis); 
     83        environment->GetBoolValue("VspBspTree.PostProcess.useRaysForMerge", mUseRaysForMerge); 
    8484 
    8585        //-- debug output 
     
    137137{ 
    138138        DEL_PTR(mRoot); 
    139         DEL_PTR(mRootCell); 
    140139        DEL_PTR(mSplitCandidates); 
    141140} 
     
    216215                { 
    217216                        mBox.Include(object->GetBox()); // add to BSP tree aabb 
    218                         AddMeshToPolygons(mesh, polys, mRootCell); 
     217                        AddMeshToPolygons(mesh, polys, NULL); 
    219218                } 
    220219        } 
     
    360359                 (data.mPvs <= mTermMinPvs)   || 
    361360                 (data.mArea <= mTermMinArea) || 
    362                  (mStat.nodes / 2 + 1 >= mMaxViewCells) || 
     361                 (mStat.Leaves() >= mMaxViewCells) || 
    363362                // (data.GetAvgRayContribution() >= mTermMaxRayContribution) || 
    364363                 (data.mDepth >= mTermMaxDepth)); 
     
    400399                BspViewCell *viewCell = new BspViewCell(); 
    401400                leaf->SetViewCell(viewCell); 
    402  
     401                 
    403402                if (mStoreRays) 
    404403                { 
     
    410409                viewCell->mLeaves.push_back(leaf); 
    411410                viewCell->SetArea(tData.mArea); 
     411                leaf->mArea = tData.mArea; 
    412412 
    413413                //-- update pvs 
    414414                int conSamp = 0, sampCon = 0; 
    415415                AddToPvs(leaf, *tData.mRays, conSamp, sampCon); 
    416  
     416         
    417417                mStat.contributingSamples += conSamp; 
    418418                mStat.sampleContributions += sampCon; 
     
    10651065                        // add the termination object 
    10661066                        AddObjToPvs(ray->mTerminationObject, cf, frontPvs, backPvs); 
    1067  
    10681067                        // add the source object 
    10691068                        AddObjToPvs(ray->mOriginObject, cf, frontPvs, backPvs); 
     
    10811080                                if (cf == 1) 
    10821081                                        pFront += len; 
    1083                                 if (cf == -1) 
     1082                                else if (cf == -1) 
    10841083                                        pBack += len; 
    1085                                 if (cf == 0) 
     1084                                else if (cf == 0) 
    10861085                                { 
    10871086                                        // use length of rays to approximate volume 
     
    12311230                mStat.maxDepth = data.mDepth; 
    12321231 
     1232        if (data.mPvs > mStat.maxPvs) 
     1233                mStat.maxPvs = data.mPvs; 
    12331234        if (data.mDepth < mStat.minDepth) 
    12341235                mStat.minDepth = data.mDepth; 
    1235  
    12361236        if (data.mDepth >= mTermMaxDepth) 
    12371237                ++ mStat.maxDepthNodes; 
     
    14361436                float t; 
    14371437 
    1438                         // get classification and receive new t 
     1438                // get classification and receive new t 
    14391439                const int cf = bRay.ComputeRayIntersection(plane, t); 
    14401440 
     
    14481448                        break; 
    14491449                case 0: 
    1450                         //-- split ray 
    1451                         //--  look if start point behind or in front of plane 
    1452                         if (plane.Side(bRay.ExtrapOrigin()) <= 0) 
    14531450                        { 
    1454                                 backRays.push_back(RayInfo(ray, bRay.GetMinT(), t)); 
    1455                                 frontRays.push_back(RayInfo(ray, t, bRay.GetMaxT())); 
    1456                         } 
    1457                         else 
    1458                         { 
    1459                                 frontRays.push_back(RayInfo(ray, bRay.GetMinT(), t)); 
    1460                                 backRays.push_back(RayInfo(ray, t, bRay.GetMaxT())); 
     1451                                //-- split ray 
     1452                                //-- test if start point behind or in front of plane 
     1453                                const int side = plane.Side(bRay.ExtrapOrigin()); 
     1454 
     1455                                if (side <= 0) 
     1456                                { 
     1457                                        backRays.push_back(RayInfo(ray, bRay.GetMinT(), t)); 
     1458                                        frontRays.push_back(RayInfo(ray, t, bRay.GetMaxT())); 
     1459                                } 
     1460                                else 
     1461                                { 
     1462                                        frontRays.push_back(RayInfo(ray, bRay.GetMinT(), t)); 
     1463                                        backRays.push_back(RayInfo(ray, t, bRay.GetMaxT())); 
     1464                                } 
    14611465                        } 
    14621466                        break; 
    14631467                default: 
    1464                         Debug << "Should not come here 4" << endl; 
     1468                        Debug << "Should not come here" << endl; 
    14651469                        break; 
    14661470                } 
     
    14971501} 
    14981502 
     1503 
    14991504void VspBspTree::ConstructGeometry(BspNode *n, 
    15001505                                                                   BspNodeGeometry &cell) const 
    15011506{ 
    1502         PolygonContainer polys; 
    1503         ConstructGeometry(n, polys); 
    1504         cell.mPolys = polys; 
    1505 } 
     1507        ConstructGeometry(n, cell.mPolys); 
     1508} 
     1509 
    15061510 
    15071511void VspBspTree::ConstructGeometry(BspNode *n, 
     
    15881592} 
    15891593 
    1590 void VspBspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &vcGeom) const 
     1594 
     1595void VspBspTree::ConstructGeometry(BspViewCell *vc,  
     1596                                                                   PolygonContainer &vcGeom) const 
    15911597{ 
    15921598        vector<BspLeaf *> leaves = vc->mLeaves; 
    1593  
    15941599        vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
    15951600 
     
    15981603} 
    15991604 
     1605 
    16001606int VspBspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 
    16011607                                                   const bool onlyUnmailed) const 
    16021608{ 
    16031609        PolygonContainer cell; 
    1604  
    16051610        ConstructGeometry(n, cell); 
    16061611 
     
    17941799} 
    17951800 
    1796 BspViewCell *VspBspTree::GetRootCell() const 
    1797 { 
    1798         return mRootCell; 
    1799 } 
    18001801 
    18011802int VspBspTree::SplitPolygons(const Plane3 &plane, 
     
    18581859        BspNode *farChild = NULL; 
    18591860 
     1861        float t; 
    18601862        while (1) 
    18611863        { 
     
    18651867 
    18661868                        Plane3 splitPlane = in->GetPlane(); 
     1869                         
    18671870                        const int entSide = splitPlane.Side(entp); 
    18681871                        const int extSide = splitPlane.Side(extp); 
    18691872 
    1870                         if (entSide < 0) 
     1873                        if (entSide < 0)  
    18711874                        { 
    18721875                                node = in->GetBack(); 
    1873  
    1874                                 if (extSide <= 0) // plane does not split ray => no far child 
     1876                                // plane does not split ray => no far child 
     1877                                if (extSide <= 0)  
    18751878                                        continue; 
    18761879 
    18771880                                farChild = in->GetFront(); // plane splits ray 
    1878                         } else if (entSide > 0) 
     1881                        }  
     1882                        else if (entSide > 0) 
    18791883                        { 
    18801884                                node = in->GetFront(); 
     
    18851889                                farChild = in->GetBack(); // plane splits ray 
    18861890                        } 
    1887                         else // ray and plane are coincident 
    1888                         { 
    1889                                 // WHAT TO DO IN THIS CASE ? 
    1890                                 //break; 
    1891                                 node = in->GetFront(); 
    1892                                 continue; 
     1891                        else // ray end point on plane 
     1892                        {       // NOTE: what to do if ray is coincident with plane? 
     1893                                if (extSide < 0) 
     1894                                        node = in->GetBack(); 
     1895                                else if (extSide > 0) 
     1896                                        node = in->GetFront(); 
     1897 
     1898                                continue; // no far child 
    18931899                        } 
    18941900 
    18951901                        // push data for far child 
    1896                         tStack.push(BspRayTraversalData(farChild, extp, maxt)); 
     1902                        tStack.push(BspRayTraversalData(farChild, extp)); 
    18971903 
    18981904                        // find intersection of ray segment with plane 
    1899                         float t; 
    19001905                        extp = splitPlane.FindIntersection(origin, extp, &t); 
    1901                         maxt *= t; 
    1902  
    1903                 } else 
     1906                }  
     1907                else 
    19041908                { 
    19051909                        // reached leaf => intersection with view cell 
     
    19181922 
    19191923                        entp = extp; 
    1920                         mint = maxt; // NOTE: need this? 
    1921  
    1922  
     1924                         
    19231925                        BspRayTraversalData &s = tStack.top(); 
    19241926 
    19251927                        node = s.mNode; 
    19261928                        extp = s.mExitPoint; 
    1927                         maxt = s.mMaxT; 
    19281929 
    19291930                        tStack.pop(); 
    19301931                } 
    19311932        } 
     1933 
    19321934        return hits; 
    19331935} 
    19341936 
    1935 int VspBspTree::TreeDistance(BspNode *n1, BspNode *n2) 
     1937int VspBspTree::TreeDistance(BspNode *n1, BspNode *n2) const 
    19361938{ 
    19371939        std::deque<BspNode *> path1; 
     
    19971999                } 
    19982000        } 
     2001 
     2002        // revalidate leaves 
     2003        RepairVcLeafLists(); 
    19992004 
    20002005        return node; 
     
    20402045 
    20412046 
    2042 int VspBspTree::MergeLeaves() 
    2043 { 
    2044         vector<BspLeaf *> leaves; 
    2045         priority_queue<BspMergeCandidate> mergeQueue; 
    2046  
    2047         // collect the leaves, e.g., the "voxels" that will build the view cells 
    2048         CollectLeaves(leaves); 
    2049  
    2050         int vcSize = (int)leaves.size(); 
    2051         int savedVcSize = vcSize; 
    2052  
    2053         BspLeaf::NewMail(); 
    2054  
    2055         vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
    2056  
    2057         // find merge candidates and push them into queue 
    2058         for (it = leaves.begin(); it != it_end; ++ it) 
    2059         { 
    2060                 BspLeaf *leaf = *it; 
    2061  
    2062                 // no leaf is part of two merge candidates 
    2063                 if (!leaf->Mailed()) 
    2064                 { 
    2065                         leaf->Mail(); 
    2066  
    2067                         vector<BspLeaf *> neighbors; 
    2068                         FindNeighbors(leaf, neighbors, true); 
    2069  
    2070                         vector<BspLeaf *>::const_iterator nit, 
    2071                                 nit_end = neighbors.end(); 
    2072  
    2073                         for (nit = neighbors.begin(); nit != nit_end; ++ nit) 
    2074                         { 
    2075                                 BspMergeCandidate mc = BspMergeCandidate(leaf, *nit); 
    2076                                 mergeQueue.push(mc); 
    2077  
    2078                                 BspMergeCandidate::sOverallCost += mc.GetLeaf1Cost(); 
    2079                                 BspMergeCandidate::sOverallCost += mc.GetLeaf2Cost(); 
    2080                         } 
    2081                 } 
    2082         } 
    2083  
    2084         int merged = 0; 
    2085         int mergedSiblings = 0; 
    2086         int accTreeDist = 0; 
    2087         int maxTreeDist = 0; 
    2088         const bool mergeStats = true; 
    2089  
    2090  
    2091         //-- use priority queue to merge leaf pairs 
    2092         while (!mergeQueue.empty() && (vcSize > mMergeMinViewCells) && 
    2093                    (mergeQueue.top().GetMergeCost() < 
    2094                     mMergeMaxCostRatio * BspMergeCandidate::sOverallCost)) 
    2095         { 
    2096                 //Debug << "mergecost: " << mergeQueue.top().GetMergeCost() / BspMergeCandidate::sOverallCost << " " << mMergeMaxCostRatio << endl; 
    2097                 BspMergeCandidate mc = mergeQueue.top(); 
    2098                 mergeQueue.pop(); 
    2099  
    2100                 // both view cells equal! 
    2101                 if (mc.GetLeaf1()->GetViewCell() == mc.GetLeaf2()->GetViewCell()) 
    2102                         continue; 
    2103  
    2104                 if (mc.Valid()) 
    2105                 { 
    2106                         ViewCell::NewMail(); 
    2107                         MergeViewCells(mc.GetLeaf1(), mc.GetLeaf2()); 
    2108                         -- vcSize; 
    2109                         // increase absolute merge cost 
    2110                         BspMergeCandidate::sOverallCost += mc.GetMergeCost(); 
    2111  
    2112                         //-- stats 
    2113                         ++ merged; 
    2114  
    2115                         if (mc.GetLeaf1()->IsSibling(mc.GetLeaf2())) 
    2116                                 ++ mergedSiblings; 
    2117  
    2118                         if (mergeStats) 
    2119                         { 
    2120                                 const int dist = TreeDistance(mc.GetLeaf1(), mc.GetLeaf2()); 
    2121  
    2122                                 if (dist > maxTreeDist) 
    2123                                         maxTreeDist = dist; 
    2124  
    2125                                 accTreeDist += dist; 
    2126                         } 
    2127                 } 
    2128                 // merge candidate not valid, because one of the leaves was already 
    2129                 // merged with another one 
    2130                 else 
    2131                 { 
    2132                         // validate and reinsert into queue 
    2133                         mc.SetValid(); 
    2134                         mergeQueue.push(mc); 
    2135                         //Debug << "validate " << mc.GetMergeCost() << endl; 
    2136                 } 
    2137         } 
    2138  
    2139         // collapse tree according to view cell partition 
    2140         CollapseTree(mRoot); 
    2141         // revalidate leaves 
    2142         RepairVcLeafLists(); 
    2143  
    2144         Debug << "Merged " << merged << " nodes of " << savedVcSize 
    2145                   << " (merged " << mergedSiblings << " siblings)" << endl; 
    2146  
    2147         if (mergeStats) 
    2148         { 
    2149                 Debug << "maximal tree distance: " << maxTreeDist << endl; 
    2150                 Debug << "Avg tree distance: " << (float)accTreeDist / (float)merged << endl; 
    2151         } 
    2152  
    2153         //TODO: should return sample contributions 
    2154         return merged; 
    2155 } 
    2156  
    2157  
    2158 bool VspBspTree::MergeViewCells(BspLeaf *l1, BspLeaf *l2) 
     2047bool VspBspTree::MergeViewCells(BspLeaf *l1, BspLeaf *l2) const 
    21592048{ 
    21602049        //-- change pointer to view cells of all leaves associated 
     
    22042093        mViewCellsManager = vcm; 
    22052094} 
     2095 
     2096 
     2097int VspBspTree::CollectMergeCandidates() 
     2098{ 
     2099        vector<BspLeaf *> leaves; 
     2100 
     2101        // collect the leaves, e.g., the "voxels" that will build the view cells 
     2102        CollectLeaves(leaves); 
     2103        BspLeaf::NewMail(); 
     2104 
     2105        vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 
     2106 
     2107        // find merge candidates and push them into queue 
     2108        for (it = leaves.begin(); it != it_end; ++ it) 
     2109        { 
     2110                BspLeaf *leaf = *it; 
     2111                 
     2112                /// create leaf pvs (needed for post processing 
     2113                leaf->mPvs = new ObjectPvs(leaf->GetViewCell()->GetPvs()); 
     2114 
     2115                BspMergeCandidate::sOverallCost +=  
     2116                        leaf->mArea * leaf->mPvs->GetSize(); 
     2117 
     2118                // the same leaves must not be part of two merge candidates 
     2119                leaf->Mail(); 
     2120                vector<BspLeaf *> neighbors; 
     2121                FindNeighbors(leaf, neighbors, true); 
     2122 
     2123                vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end(); 
     2124 
     2125                // TODO: test if at least one ray goes from one leaf to the other 
     2126                for (nit = neighbors.begin(); nit != nit_end; ++ nit) 
     2127                {                        
     2128                        mMergeQueue.push(BspMergeCandidate(leaf, *nit)); 
     2129                } 
     2130        } 
     2131 
     2132        return (int)leaves.size(); 
     2133} 
     2134 
     2135 
     2136int VspBspTree::CollectMergeCandidates(const VssRayContainer &rays) 
     2137{ 
     2138        vector<BspRay *> bspRays; 
     2139 
     2140        ConstructBspRays(bspRays, rays); 
     2141        map<BspLeaf *, vector<BspLeaf*> > neighborMap; 
     2142 
     2143        vector<BspIntersection>::const_iterator iit; 
     2144 
     2145        int leaves = 0; 
     2146         
     2147        BspLeaf::NewMail(); 
     2148 
     2149        for (int i = 0; i < (int)bspRays.size(); ++ i) 
     2150        {   
     2151                BspRay *ray = bspRays[i]; 
     2152           
     2153                // traverse leaves stored in the rays and compare and  
     2154                // merge consecutive leaves (i.e., the neighbors in the tree) 
     2155                if (ray->intersections.size() < 2) 
     2156                        continue; 
     2157           
     2158                iit = ray->intersections.begin(); 
     2159                BspLeaf *prevLeaf = (*(iit ++)).mLeaf; 
     2160                 
     2161                // create leaf pvs (needed for post processing) 
     2162                if (!prevLeaf->mPvs) 
     2163                { 
     2164                        prevLeaf->mPvs =  
     2165                                new ObjectPvs(prevLeaf->GetViewCell()->GetPvs()); 
     2166 
     2167                        BspMergeCandidate::sOverallCost +=  
     2168                                prevLeaf->mArea * prevLeaf->mPvs->GetSize(); 
     2169                         
     2170                        ++ leaves; 
     2171                } 
     2172                 
     2173                // traverse intersections  
     2174                // consecutive leaves are neighbors =>  
     2175                // add them to queue 
     2176                for (; iit != ray->intersections.end(); ++ iit) 
     2177                { 
     2178            BspLeaf *leaf = (*iit).mLeaf; 
     2179             
     2180                        if (!leaf->mPvs) 
     2181                        { 
     2182                                leaf->mPvs =  
     2183                                        new ObjectPvs(leaf->GetViewCell()->GetPvs()); 
     2184                                 
     2185                                BspMergeCandidate::sOverallCost +=  
     2186                                        leaf->mArea * leaf->mPvs->GetSize(); 
     2187 
     2188                                ++ leaves; 
     2189                        } 
     2190                 
     2191                        vector<BspLeaf *> &neighbors = neighborMap[leaf]; 
     2192                         
     2193                        bool found = false; 
     2194 
     2195                        // both leaves inserted in queue already => 
     2196                        // look if double pair already exists 
     2197                        if (leaf->Mailed() && prevLeaf->Mailed()) 
     2198                        { 
     2199                                vector<BspLeaf *>::const_iterator it, it_end = neighbors.end(); 
     2200                                 
     2201                for (it = neighbors.begin(); !found && (it != it_end); ++ it) 
     2202                                        if (*it == prevLeaf) 
     2203                                                found = true; // already in queue 
     2204                        } 
     2205                         
     2206                        if (!found) 
     2207                        { 
     2208                                // this pair is not in map already 
     2209                                // => insert into the neighbor map and the queue 
     2210                                neighbors.push_back(prevLeaf); 
     2211                                neighborMap[prevLeaf].push_back(leaf); 
     2212 
     2213                                leaf->Mail(); 
     2214                                prevLeaf->Mail(); 
     2215 
     2216                                mMergeQueue.push(BspMergeCandidate(leaf, prevLeaf)); 
     2217                        } 
     2218 
     2219                        prevLeaf = leaf; 
     2220        } 
     2221        } 
     2222        Debug << "neighbormap size: " << (int)neighborMap.size() << endl; 
     2223        Debug << "mergequeue: " << (int)mMergeQueue.size() << endl; 
     2224        Debug << "leaves in queue: " << leaves << endl; 
     2225        Debug << "overall cost: " << BspMergeCandidate::sOverallCost << endl; 
     2226 
     2227        CLEAR_CONTAINER(bspRays); 
     2228 
     2229        return leaves; 
     2230} 
     2231 
     2232 
     2233void VspBspTree::ConstructBspRays(vector<BspRay *> &bspRays, 
     2234                                                                  const VssRayContainer &rays) 
     2235{ 
     2236        VssRayContainer::const_iterator it, it_end = rays.end(); 
     2237 
     2238        for (it = rays.begin(); it != rays.end(); ++ it) 
     2239        { 
     2240                VssRay *vssRay = *it; 
     2241                BspRay *ray = new BspRay(vssRay); 
     2242 
     2243                ViewCellContainer viewCells; 
     2244 
     2245                Ray hray(*vssRay); 
     2246                float tmin = 0, tmax = 1.0; 
     2247                // matt TODO: remove this!! 
     2248                //hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT); 
     2249                if (!mBox.GetRaySegment(hray, tmin, tmax) || (tmin > tmax)) 
     2250                        continue; 
     2251 
     2252                Vector3 origin = hray.Extrap(tmin); 
     2253                Vector3 termination = hray.Extrap(tmax); 
     2254         
     2255                // cast line segment to get intersections with bsp leaves 
     2256                CastLineSegment(origin, termination, viewCells); 
     2257 
     2258                ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 
     2259                for (vit = viewCells.begin(); vit != vit_end; ++ vit) 
     2260                { 
     2261                        BspViewCell *vc = dynamic_cast<BspViewCell *>(*vit); 
     2262                        vector<BspLeaf *>::const_iterator it, it_end = vc->mLeaves.end(); 
     2263                        //NOTE: not sorted! 
     2264                        for (it = vc->mLeaves.begin(); it != it_end; ++ it) 
     2265                                ray->intersections.push_back(BspIntersection(0, *it)); 
     2266                } 
     2267 
     2268                bspRays.push_back(ray); 
     2269        } 
     2270} 
     2271 
     2272 
     2273int VspBspTree::MergeViewCells(const VssRayContainer &rays) 
     2274{ 
     2275        MergeStatistics mergeStats; 
     2276        mergeStats.Start(); 
     2277        // TODO: REMOVE LATER for performance! 
     2278        const bool showMergeStats = true; 
     2279        //BspMergeCandidate::sOverallCost = mBox.SurfaceArea() * mStat.maxPvs; 
     2280        long startTime = GetTime(); 
     2281 
     2282        if (mUseRaysForMerge) 
     2283                mergeStats.nodes = CollectMergeCandidates(rays); 
     2284        else 
     2285                mergeStats.nodes = CollectMergeCandidates(); 
     2286 
     2287        mergeStats.collectTime = TimeDiff(startTime, GetTime()); 
     2288        mergeStats.candidates = (int)mMergeQueue.size(); 
     2289        startTime = GetTime(); 
     2290 
     2291        int nViewCells = /*mergeStats.nodes*/ mStat.Leaves(); 
     2292 
     2293         
     2294        //-- use priority queue to merge leaf pairs 
     2295        while (!mMergeQueue.empty() && (nViewCells > mMergeMinViewCells) && 
     2296                   (mMergeQueue.top().GetMergeCost() < 
     2297                    mMergeMaxCostRatio * BspMergeCandidate::sOverallCost)) 
     2298        { 
     2299                //Debug << "abs mergecost: " << mMergeQueue.top().GetMergeCost() << " rel mergecost: " 
     2300                //        << mMergeQueue.top().GetMergeCost() / BspMergeCandidate::sOverallCost  
     2301                //        << " max ratio: " << mMergeMaxCostRatio << endl; 
     2302                BspMergeCandidate mc = mMergeQueue.top(); 
     2303                mMergeQueue.pop(); 
     2304 
     2305                // both view cells equal! 
     2306                if (mc.GetLeaf1()->GetViewCell() == mc.GetLeaf2()->GetViewCell()) 
     2307                        continue; 
     2308 
     2309                if (mc.Valid()) 
     2310                { 
     2311                        ViewCell::NewMail(); 
     2312                        MergeViewCells(mc.GetLeaf1(), mc.GetLeaf2()); 
     2313                        -- nViewCells; 
     2314                         
     2315                        ++ mergeStats.merged; 
     2316                         
     2317                        // increase absolute merge cost 
     2318                        BspMergeCandidate::sOverallCost += mc.GetMergeCost(); 
     2319 
     2320                        if (showMergeStats) 
     2321                        { 
     2322                                if (mc.GetLeaf1()->IsSibling(mc.GetLeaf2())) 
     2323                                        ++ mergeStats.siblings; 
     2324 
     2325                                const int dist =  
     2326                                        TreeDistance(mc.GetLeaf1(), mc.GetLeaf2()); 
     2327                                if (dist > mergeStats.maxTreeDist) 
     2328                                        mergeStats.maxTreeDist = dist; 
     2329                                mergeStats.accTreeDist += dist; 
     2330                        } 
     2331                } 
     2332                // merge candidate not valid, because one of the leaves was already 
     2333                // merged with another one => validate and reinsert into queue 
     2334                else 
     2335                {  
     2336                        mc.SetValid(); 
     2337                        mMergeQueue.push(mc); 
     2338                } 
     2339        } 
     2340 
     2341        mergeStats.mergeTime = TimeDiff(startTime, GetTime()); 
     2342        mergeStats.Stop(); 
     2343 
     2344        if (showMergeStats) 
     2345                Debug << mergeStats << endl << endl; 
     2346         
     2347        //TODO: should return sample contributions? 
     2348        return mergeStats.merged; 
     2349} 
     2350 
     2351 
     2352int VspBspTree::RefineViewCells(const VssRayContainer &rays) 
     2353{ 
     2354        int shuffled = 0; 
     2355 
     2356        Debug << "refining " << (int)mMergeQueue.size() << " candidates " << endl; 
     2357        BspLeaf::NewMail(); 
     2358 
     2359        // Use priority queue of remaining leaf pairs  
     2360        // These candidates either share the same view cells or 
     2361        // are border leaves which share a boundary. 
     2362        // We test if they can be shuffled, i.e., 
     2363        // either one leaf is made part of one view cell or the other 
     2364        // leaf is made part of the other view cell. It is tested if the 
     2365        // remaining view cells are "better" than the old ones. 
     2366        while (!mMergeQueue.empty()) 
     2367        { 
     2368                BspMergeCandidate mc = mMergeQueue.top(); 
     2369                mMergeQueue.pop(); 
     2370 
     2371                // both view cells equal or already shuffled 
     2372                if ((mc.GetLeaf1()->GetViewCell() == mc.GetLeaf2()->GetViewCell()) || 
     2373                        (mc.GetLeaf1()->Mailed()) || (mc.GetLeaf2()->Mailed())) 
     2374                        continue; 
     2375                 
     2376                // candidate for shuffling 
     2377                const bool wasShuffled =  
     2378                        ShuffleLeaves(mc.GetLeaf1(), mc.GetLeaf2()); 
     2379                 
     2380                //-- stats 
     2381                if (wasShuffled) 
     2382                        ++ shuffled; 
     2383        } 
     2384 
     2385        return shuffled; 
     2386} 
     2387 
     2388 
     2389inline int AddedPvsSize(ObjectPvs pvs1, const ObjectPvs &pvs2) 
     2390{ 
     2391        return pvs1.AddPvs(pvs2); 
     2392} 
     2393 
     2394/*inline int SubtractedPvsSize(BspViewCell *vc, BspLeaf *l, const ObjectPvs &pvs2) 
     2395{ 
     2396        ObjectPvs pvs; 
     2397        vector<BspLeaf *>::const_iterator it, it_end = vc->mLeaves.end(); 
     2398        for (it = vc->mLeaves.begin(); it != vc->mLeaves.end(); ++ it) 
     2399                if (*it != l) 
     2400                        pvs.AddPvs(*(*it)->mPvs); 
     2401        return pvs.GetSize(); 
     2402}*/ 
     2403 
     2404inline int SubtractedPvsSize(ObjectPvs pvs1, const ObjectPvs &pvs2) 
     2405{ 
     2406        return pvs1.SubtractPvs(pvs2); 
     2407} 
     2408 
     2409 
     2410float GetShuffledVcCost(BspLeaf *leaf, BspViewCell *vc1, BspViewCell *vc2) 
     2411{ 
     2412        //const int pvs1 = SubtractedPvsSize(vc1, leaf, *leaf->mPvs); 
     2413        const int pvs1 = SubtractedPvsSize(vc1->GetPvs(), *leaf->mPvs); 
     2414        const int pvs2 = AddedPvsSize(vc2->GetPvs(), *leaf->mPvs); 
     2415 
     2416        const float area1 = vc1->GetArea() - leaf->mArea; 
     2417        const float area2 = vc2->GetArea() + leaf->mArea; 
     2418 
     2419        const float cost1 = pvs1 * area1; 
     2420        const float cost2 = pvs2 * area2; 
     2421 
     2422        return cost1 + cost2; 
     2423} 
     2424 
     2425 
     2426void VspBspTree::ShuffleLeaf(BspLeaf *leaf,  
     2427                                                         BspViewCell *vc1,  
     2428                                                         BspViewCell *vc2) const 
     2429{ 
     2430        //Debug << "old pvs: " << vc1->GetPvs().GetSize() + vc2->GetPvs().GetSize()  
     2431        //        << " (" << vc1->GetPvs().GetSize() << ", " << vc2->GetPvs().GetSize() << ")" << endl; 
     2432        // compute new pvs and area 
     2433        vc1->GetPvs().SubtractPvs(*leaf->mPvs); 
     2434        vc2->GetPvs().AddPvs(*leaf->mPvs); 
     2435         
     2436        vc1->SetArea(vc1->GetArea() - leaf->mArea); 
     2437        vc2->SetArea(vc2->GetArea() + leaf->mArea); 
     2438 
     2439        /// add to second view cell 
     2440        vc2->mLeaves.push_back(leaf); 
     2441 
     2442        // erase leaf from old view cell 
     2443        vector<BspLeaf *>::iterator it = vc1->mLeaves.begin(); 
     2444 
     2445        for (; *it != leaf; ++ it); 
     2446        vc1->mLeaves.erase(it); 
     2447 
     2448        /*vc1->GetPvs().mEntries.clear(); 
     2449        for (; it != vc1->mLeaves.end(); ++ it) 
     2450        { 
     2451                if (*it == leaf) 
     2452                        vc1->mLeaves.erase(it); 
     2453                else 
     2454                        vc1->GetPvs().AddPvs(*(*it)->mPvs); 
     2455        }*/ 
     2456 
     2457        leaf->SetViewCell(vc2);         // finally change view cell 
     2458         
     2459        //Debug << "new pvs: " << vc1->GetPvs().GetSize() + vc2->GetPvs().GetSize()  
     2460        //        << " (" << vc1->GetPvs().GetSize() << ", " << vc2->GetPvs().GetSize() << ")" << endl; 
     2461 
     2462} 
     2463 
     2464 
     2465bool VspBspTree::ShuffleLeaves(BspLeaf *leaf1, BspLeaf *leaf2) const 
     2466{ 
     2467        BspViewCell *vc1 = leaf1->GetViewCell(); 
     2468        BspViewCell *vc2 = leaf2->GetViewCell(); 
     2469 
     2470        const float cost1 = vc1->GetPvs().GetSize() * vc1->GetArea(); 
     2471        const float cost2 = vc2->GetPvs().GetSize() * vc2->GetArea(); 
     2472 
     2473        const float oldCost = cost1 + cost2; 
     2474         
     2475        float shuffledCost1 = Limits::Infinity; 
     2476        float shuffledCost2 = Limits::Infinity; 
     2477 
     2478        // the view cell should not be empty after the shuffle 
     2479        if (vc1->mLeaves.size() > 1) 
     2480                shuffledCost1 = GetShuffledVcCost(leaf1, vc1, vc2); 
     2481        if (vc2->mLeaves.size() > 1) 
     2482                shuffledCost2 = GetShuffledVcCost(leaf2, vc2, vc1); 
     2483 
     2484        // shuffling unsuccessful 
     2485        if ((oldCost <= shuffledCost1) && (oldCost <= shuffledCost2)) 
     2486                return false; 
     2487         
     2488        if (shuffledCost1 < shuffledCost2) 
     2489        { 
     2490                //Debug << "old cost: " << oldCost << ", new cost: " << shuffledCost1 << endl; 
     2491                ShuffleLeaf(leaf1, vc1, vc2); 
     2492                leaf1->Mail(); 
     2493        } 
     2494        else 
     2495        { 
     2496                //Debug << "old cost: " << oldCost << ", new cost: " << shuffledCost2 << endl; 
     2497                ShuffleLeaf(leaf2, vc2, vc1); 
     2498                leaf2->Mail(); 
     2499        } 
     2500 
     2501        return true; 
     2502} 
     2503 
    22062504 
    22072505/************************************************************************/ 
     
    22202518} 
    22212519 
     2520float BspMergeCandidate::GetCost(ViewCell *vc) const 
     2521{ 
     2522        return vc->GetPvs().GetSize() * vc->GetArea(); 
     2523} 
     2524 
    22222525float BspMergeCandidate::GetLeaf1Cost() const 
    22232526{ 
    22242527        BspViewCell *vc = mLeaf1->GetViewCell(); 
    2225         return vc->GetPvs().GetSize() * vc->GetArea(); 
     2528        return GetCost(vc); 
    22262529} 
    22272530 
     
    22292532{ 
    22302533        BspViewCell *vc = mLeaf2->GetViewCell(); 
    2231         return vc->GetPvs().GetSize() * vc->GetVolume(); 
     2534        return GetCost(vc); 
    22322535} 
    22332536 
     
    22392542 
    22402543        const int diff1 = vc1->GetPvs().Diff(vc2->GetPvs()); 
    2241         const int vcPvs = diff1 + vc1->GetPvs().GetSize(); 
     2544        const int newPvs = diff1 + vc1->GetPvs().GetSize(); 
    22422545 
    22432546        //-- compute ratio of old cost 
     
    22472550 
    22482551        const float newCost = 
    2249                 (float)vcPvs * (vc1->GetArea() + vc2->GetArea()); 
     2552                (float)newPvs * (vc1->GetArea() + vc2->GetArea()); 
    22502553 
    22512554        mMergeCost = newCost - oldCost; 
    2252  
    22532555//      if (vcPvs > sMaxPvsSize) // strong penalty if pvs size too large 
    22542556//              mMergeCost += 1.0; 
     
    22942596        EvalMergeCost(); 
    22952597} 
     2598 
     2599 
     2600/************************************************************************/ 
     2601/*                  MergeStatistics implementation                      */ 
     2602/************************************************************************/ 
     2603 
     2604 
     2605void MergeStatistics::Print(ostream &app) const 
     2606{ 
     2607        app << "===== Merge statistics ===============\n"; 
     2608 
     2609        app << setprecision(4); 
     2610 
     2611        app << "#N_CTIME ( Overall time [s] )\n" << Time() << " \n"; 
     2612 
     2613        app << "#N_CCTIME ( Collect candidates time [s] )\n" << collectTime * 1e-3f << " \n"; 
     2614 
     2615        app << "#N_MTIME ( Merge time [s] )\n" << mergeTime * 1e-3f << " \n"; 
     2616 
     2617        app << "#N_NODES ( Number of nodes before merge )\n" << nodes << "\n"; 
     2618 
     2619        app << "#N_CANDIDATES ( Number of merge candidates )\n" << candidates << "\n"; 
     2620 
     2621        app << "#N_MERGEDSIBLINGS ( Number of merged siblings )\n" << siblings << "\n"; 
     2622        app << "#N_MERGEDNODES ( Number of merged nodes )\n" << merged << "\n"; 
     2623 
     2624        app << "#MAX_TREEDIST ( Maximal distance in tree of merged leaves )\n" << maxTreeDist << "\n"; 
     2625 
     2626        app << "#AVG_TREEDIST ( Average distance in tree of merged leaves )\n" << AvgTreeDist() << "\n"; 
     2627 
     2628        app << "===== END OF BspTree statistics ==========\n"; 
     2629} 
Note: See TracChangeset for help on using the changeset viewer.