Changeset 485 for trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
- Timestamp:
- 12/30/05 12:08:15 (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
r484 r485 33 33 int VspBspTree::sFrontAndBackId = 0; 34 34 35 float BspMergeCandidate::sOverallCost = Limits::Small;35 float BspMergeCandidate::sOverallCost = 0; 36 36 37 37 /****************************************************************/ … … 44 44 mCostNormalizer(Limits::Small), 45 45 mViewCellsManager(NULL), 46 mStoreRays( true),46 mStoreRays(false), 47 47 mOnlyDrivingAxis(false) 48 48 { 49 mRootCell = new BspViewCell();50 51 49 Randomize(); // initialise random generator for heuristics 52 50 … … 82 80 environment->GetFloatValue("VspBspTree.PostProcess.maxCostRatio", mMergeMaxCostRatio); 83 81 82 environment->GetBoolValue("VspBspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis); 83 environment->GetBoolValue("VspBspTree.PostProcess.useRaysForMerge", mUseRaysForMerge); 84 84 85 85 //-- debug output … … 137 137 { 138 138 DEL_PTR(mRoot); 139 DEL_PTR(mRootCell);140 139 DEL_PTR(mSplitCandidates); 141 140 } … … 216 215 { 217 216 mBox.Include(object->GetBox()); // add to BSP tree aabb 218 AddMeshToPolygons(mesh, polys, mRootCell);217 AddMeshToPolygons(mesh, polys, NULL); 219 218 } 220 219 } … … 360 359 (data.mPvs <= mTermMinPvs) || 361 360 (data.mArea <= mTermMinArea) || 362 (mStat. nodes / 2 + 1>= mMaxViewCells) ||361 (mStat.Leaves() >= mMaxViewCells) || 363 362 // (data.GetAvgRayContribution() >= mTermMaxRayContribution) || 364 363 (data.mDepth >= mTermMaxDepth)); … … 400 399 BspViewCell *viewCell = new BspViewCell(); 401 400 leaf->SetViewCell(viewCell); 402 401 403 402 if (mStoreRays) 404 403 { … … 410 409 viewCell->mLeaves.push_back(leaf); 411 410 viewCell->SetArea(tData.mArea); 411 leaf->mArea = tData.mArea; 412 412 413 413 //-- update pvs 414 414 int conSamp = 0, sampCon = 0; 415 415 AddToPvs(leaf, *tData.mRays, conSamp, sampCon); 416 416 417 417 mStat.contributingSamples += conSamp; 418 418 mStat.sampleContributions += sampCon; … … 1065 1065 // add the termination object 1066 1066 AddObjToPvs(ray->mTerminationObject, cf, frontPvs, backPvs); 1067 1068 1067 // add the source object 1069 1068 AddObjToPvs(ray->mOriginObject, cf, frontPvs, backPvs); … … 1081 1080 if (cf == 1) 1082 1081 pFront += len; 1083 if (cf == -1)1082 else if (cf == -1) 1084 1083 pBack += len; 1085 if (cf == 0)1084 else if (cf == 0) 1086 1085 { 1087 1086 // use length of rays to approximate volume … … 1231 1230 mStat.maxDepth = data.mDepth; 1232 1231 1232 if (data.mPvs > mStat.maxPvs) 1233 mStat.maxPvs = data.mPvs; 1233 1234 if (data.mDepth < mStat.minDepth) 1234 1235 mStat.minDepth = data.mDepth; 1235 1236 1236 if (data.mDepth >= mTermMaxDepth) 1237 1237 ++ mStat.maxDepthNodes; … … 1436 1436 float t; 1437 1437 1438 1438 // get classification and receive new t 1439 1439 const int cf = bRay.ComputeRayIntersection(plane, t); 1440 1440 … … 1448 1448 break; 1449 1449 case 0: 1450 //-- split ray1451 //-- look if start point behind or in front of plane1452 if (plane.Side(bRay.ExtrapOrigin()) <= 0)1453 1450 { 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 } 1461 1465 } 1462 1466 break; 1463 1467 default: 1464 Debug << "Should not come here 4" << endl;1468 Debug << "Should not come here" << endl; 1465 1469 break; 1466 1470 } … … 1497 1501 } 1498 1502 1503 1499 1504 void VspBspTree::ConstructGeometry(BspNode *n, 1500 1505 BspNodeGeometry &cell) const 1501 1506 { 1502 PolygonContainer polys; 1503 ConstructGeometry(n, polys); 1504 cell.mPolys = polys; 1505 } 1507 ConstructGeometry(n, cell.mPolys); 1508 } 1509 1506 1510 1507 1511 void VspBspTree::ConstructGeometry(BspNode *n, … … 1588 1592 } 1589 1593 1590 void VspBspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &vcGeom) const 1594 1595 void VspBspTree::ConstructGeometry(BspViewCell *vc, 1596 PolygonContainer &vcGeom) const 1591 1597 { 1592 1598 vector<BspLeaf *> leaves = vc->mLeaves; 1593 1594 1599 vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 1595 1600 … … 1598 1603 } 1599 1604 1605 1600 1606 int VspBspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 1601 1607 const bool onlyUnmailed) const 1602 1608 { 1603 1609 PolygonContainer cell; 1604 1605 1610 ConstructGeometry(n, cell); 1606 1611 … … 1794 1799 } 1795 1800 1796 BspViewCell *VspBspTree::GetRootCell() const1797 {1798 return mRootCell;1799 }1800 1801 1801 1802 int VspBspTree::SplitPolygons(const Plane3 &plane, … … 1858 1859 BspNode *farChild = NULL; 1859 1860 1861 float t; 1860 1862 while (1) 1861 1863 { … … 1865 1867 1866 1868 Plane3 splitPlane = in->GetPlane(); 1869 1867 1870 const int entSide = splitPlane.Side(entp); 1868 1871 const int extSide = splitPlane.Side(extp); 1869 1872 1870 if (entSide < 0) 1873 if (entSide < 0) 1871 1874 { 1872 1875 node = in->GetBack(); 1873 1874 if (extSide <= 0) // plane does not split ray => no far child1876 // plane does not split ray => no far child 1877 if (extSide <= 0) 1875 1878 continue; 1876 1879 1877 1880 farChild = in->GetFront(); // plane splits ray 1878 } else if (entSide > 0) 1881 } 1882 else if (entSide > 0) 1879 1883 { 1880 1884 node = in->GetFront(); … … 1885 1889 farChild = in->GetBack(); // plane splits ray 1886 1890 } 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 1893 1899 } 1894 1900 1895 1901 // push data for far child 1896 tStack.push(BspRayTraversalData(farChild, extp , maxt));1902 tStack.push(BspRayTraversalData(farChild, extp)); 1897 1903 1898 1904 // find intersection of ray segment with plane 1899 float t;1900 1905 extp = splitPlane.FindIntersection(origin, extp, &t); 1901 maxt *= t; 1902 1903 } else 1906 } 1907 else 1904 1908 { 1905 1909 // reached leaf => intersection with view cell … … 1918 1922 1919 1923 entp = extp; 1920 mint = maxt; // NOTE: need this? 1921 1922 1924 1923 1925 BspRayTraversalData &s = tStack.top(); 1924 1926 1925 1927 node = s.mNode; 1926 1928 extp = s.mExitPoint; 1927 maxt = s.mMaxT;1928 1929 1929 1930 tStack.pop(); 1930 1931 } 1931 1932 } 1933 1932 1934 return hits; 1933 1935 } 1934 1936 1935 int VspBspTree::TreeDistance(BspNode *n1, BspNode *n2) 1937 int VspBspTree::TreeDistance(BspNode *n1, BspNode *n2) const 1936 1938 { 1937 1939 std::deque<BspNode *> path1; … … 1997 1999 } 1998 2000 } 2001 2002 // revalidate leaves 2003 RepairVcLeafLists(); 1999 2004 2000 2005 return node; … … 2040 2045 2041 2046 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) 2047 bool VspBspTree::MergeViewCells(BspLeaf *l1, BspLeaf *l2) const 2159 2048 { 2160 2049 //-- change pointer to view cells of all leaves associated … … 2204 2093 mViewCellsManager = vcm; 2205 2094 } 2095 2096 2097 int 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 2136 int 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 2233 void 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 2273 int 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 2352 int 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 2389 inline 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 2404 inline int SubtractedPvsSize(ObjectPvs pvs1, const ObjectPvs &pvs2) 2405 { 2406 return pvs1.SubtractPvs(pvs2); 2407 } 2408 2409 2410 float 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 2426 void 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 2465 bool 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 2206 2504 2207 2505 /************************************************************************/ … … 2220 2518 } 2221 2519 2520 float BspMergeCandidate::GetCost(ViewCell *vc) const 2521 { 2522 return vc->GetPvs().GetSize() * vc->GetArea(); 2523 } 2524 2222 2525 float BspMergeCandidate::GetLeaf1Cost() const 2223 2526 { 2224 2527 BspViewCell *vc = mLeaf1->GetViewCell(); 2225 return vc->GetPvs().GetSize() * vc->GetArea();2528 return GetCost(vc); 2226 2529 } 2227 2530 … … 2229 2532 { 2230 2533 BspViewCell *vc = mLeaf2->GetViewCell(); 2231 return vc->GetPvs().GetSize() * vc->GetVolume();2534 return GetCost(vc); 2232 2535 } 2233 2536 … … 2239 2542 2240 2543 const int diff1 = vc1->GetPvs().Diff(vc2->GetPvs()); 2241 const int vcPvs = diff1 + vc1->GetPvs().GetSize();2544 const int newPvs = diff1 + vc1->GetPvs().GetSize(); 2242 2545 2243 2546 //-- compute ratio of old cost … … 2247 2550 2248 2551 const float newCost = 2249 (float) vcPvs * (vc1->GetArea() + vc2->GetArea());2552 (float)newPvs * (vc1->GetArea() + vc2->GetArea()); 2250 2553 2251 2554 mMergeCost = newCost - oldCost; 2252 2253 2555 // if (vcPvs > sMaxPvsSize) // strong penalty if pvs size too large 2254 2556 // mMergeCost += 1.0; … … 2294 2596 EvalMergeCost(); 2295 2597 } 2598 2599 2600 /************************************************************************/ 2601 /* MergeStatistics implementation */ 2602 /************************************************************************/ 2603 2604 2605 void 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.