Changeset 1020 for GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
- Timestamp:
- 06/18/06 03:47:06 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
r1016 r1020 21 21 22 22 #define USE_FIXEDPOINT_T 0 23 24 23 #define COUNT_ORIGIN_OBJECTS 1 24 25 25 26 //-- static members 26 27 27 28 28 int VspBspTree::sFrontId = 0; 29 29 int VspBspTree::sBackId = 0; 30 30 int VspBspTree::sFrontAndBackId = 0; 31 32 31 33 32 34 typedef pair<BspNode *, BspNodeGeometry *> bspNodePair; … … 113 115 114 116 Environment::GetSingleton()->GetFloatValue("VspBspTree.Construction.renderCostWeight", mRenderCostWeight); 117 Environment::GetSingleton()->GetFloatValue("VspBspTree.Construction.renderCostDecreaseWeight", mRenderCostDecreaseWeight); 115 118 Environment::GetSingleton()->GetBoolValue("VspBspTree.usePolygonSplitIfAvailable", mUsePolygonSplitIfAvailable); 116 119 … … 161 164 Debug << "maxband: " << mMaxBand << endl; 162 165 Debug << "use driving axis for max cost: " << mUseDrivingAxisIfMaxCostViolated << endl; 166 Debug << "render cost decrease weight: " << mRenderCostDecreaseWeight << endl; 163 167 164 168 Debug << "Split plane strategy: "; … … 189 193 190 194 191 m SplitCandidates = new vector<SortableEntry>;195 mLocalSplitCandidates = new vector<SortableEntry>; 192 196 193 197 Debug << endl; … … 236 240 { 237 241 DEL_PTR(mRoot); 238 DEL_PTR(m SplitCandidates);242 DEL_PTR(mLocalSplitCandidates); 239 243 } 240 244 … … 497 501 const float prop = mUseAreaForPvs ? geom->GetArea() : geom->GetVolume(); 498 502 503 /// first traversal data 499 504 VspBspTraversalData tData(mRoot, 500 505 new PolygonContainer(polys), … … 520 525 mTotalPvsSize = tData.mPvs; 521 526 522 // first stats 523 mSubdivisionStats 524 << "#ViewCells\n1" << endl 525 << "#RenderCostDecrease\n0" << endl 526 << "#TotalRenderCost\n" << mTotalCost << endl 527 << "#AvgRenderCost\n" << mTotalPvsSize << endl; 528 529 Debug << "total cost: " << mTotalCost << endl; 530 531 527 // first subdivison statistics 528 AddSubdivisionStats(1, 0, 0, mTotalCost, (float)mTotalPvsSize); 529 532 530 mBspStats.Start(); 533 531 cout << "Constructing vsp bsp tree ... \n"; … … 586 584 587 585 Debug << "Used Memory: " << GetMemUsage() << " MB" << endl << endl; 588 cout << "finished \n";586 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << "secs" << endl; 589 587 590 588 mBspStats.Stop(); … … 624 622 mTotalPvsSize = tData.mPvs; 625 623 626 mSubdivisionStats 627 << "#ViewCells\n1\n" << endl 628 << "#RenderCostDecrease\n0\n" << endl 629 << "#SplitCandidateCost\n0\n" << endl 630 << "#TotalRenderCost\n" << mTotalCost << endl 631 << "#AvgRenderCost\n" << mTotalPvsSize << endl; 632 633 Debug << "total cost: " << mTotalCost << endl; 634 635 636 mBspStats.Start(); 624 // first subdivison statistics 625 AddSubdivisionStats(1, 0, 0, mTotalCost, (float)mTotalPvsSize); 626 627 mBspStats.Start(); 637 628 cout << "Constructing vsp bsp tree ... \n"; 638 629 … … 654 645 655 646 // cost ratio of cost decrease / totalCost 656 float costRatio = splitCandidate.Get Cost() / mTotalCost;647 float costRatio = splitCandidate.GetPriority() / mTotalCost; 657 648 658 649 //Debug << "cost ratio: " << costRatio << endl; … … 716 707 717 708 709 void VspBspTree::AddSubdivisionStats(const int viewCells, 710 const float renderCostDecr, 711 const float splitCandidateCost, 712 const float totalRenderCost, 713 const float avgRenderCost) 714 { 715 mSubdivisionStats 716 << "#ViewCells\n" << viewCells << endl 717 << "#RenderCostDecrease\n" << renderCostDecr << endl 718 << "#SplitCandidateCost\n" << splitCandidateCost << endl 719 << "#TotalRenderCost\n" << totalRenderCost << endl 720 << "#AvgRenderCost\n" << avgRenderCost << endl; 721 } 722 723 718 724 bool VspBspTree::GlobalTerminationCriteriaMet(const VspBspTraversalData &data) const 719 725 { … … 726 732 727 733 728 729 734 BspNode *VspBspTree::Subdivide(VspBspTraversalQueue &tQueue, 730 735 VspBspTraversalData &tData) … … 785 790 if (1) 786 791 { 787 float cFront = (float)tFrontData.mPvs * tFrontData.mProbability;788 float cBack = (float)tBackData.mPvs * tBackData.mProbability;789 float cData = (float)tData.mPvs * tData.mProbability;;790 791 float costDecr = (cFront + cBack - cData) / mBox.GetVolume();792 const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 793 const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 794 const float cData = (float)tData.mPvs * tData.mProbability;; 795 796 const float costDecr = (cFront + cBack - cData) / mBox.GetVolume(); 792 797 793 798 mTotalCost += costDecr; 794 799 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 795 800 796 mSubdivisionStats797 << "#ViewCells\n" << mBspStats.Leaves() << endl798 << "#RenderCostDecrease\n" << -costDecr << endl799 << "#TotalRenderCost\n" << mTotalCost << endl800 << "#AvgRenderCost\n" << (float)mTotalPvsSize / (float)mBspStats.Leaves() << endl;801 AddSubdivisionStats(mBspStats.Leaves(), 802 -costDecr, 803 0, 804 mTotalCost, 805 (float)mTotalPvsSize / (float)mBspStats.Leaves()); 801 806 } 802 807 … … 814 819 { 815 820 BspLeaf *leaf = dynamic_cast<BspLeaf *>(newNode); 821 816 822 BspViewCell *viewCell = new BspViewCell(); 817 818 823 leaf->SetViewCell(viewCell); 819 824 … … 860 865 leaf->mProbability = tData.mProbability; 861 866 867 // finally evaluate stats until this leaf 862 868 EvaluateLeafStats(tData); 863 869 } … … 906 912 tBackData.mMaxCostMisses = maxCostMisses; 907 913 908 914 // statistics 909 915 if (1) 910 916 { … … 920 926 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 921 927 922 mSubdivisionStats 923 << "#ViewCells\n" << mBspStats.Leaves() << endl 924 << "#RenderCostDecrease\n" << -costDecr << endl 925 << "#SplitCandidateCost\n" << splitCandidate.GetCost() << endl 926 << "#TotalRenderCost\n" << mTotalCost << endl 927 << "#AvgRenderCost\n" << (float)mTotalPvsSize / (float)mBspStats.Leaves() << endl; 928 AddSubdivisionStats(mBspStats.Leaves(), 929 -costDecr, 930 splitCandidate.GetPriority(), 931 mTotalCost, 932 (float)mTotalPvsSize / (float)mBspStats.Leaves()); 928 933 } 929 934 … … 948 953 { 949 954 BspLeaf *leaf = dynamic_cast<BspLeaf *>(newNode); 955 950 956 BspViewCell *viewCell = new BspViewCell(); 951 952 957 leaf->SetViewCell(viewCell); 953 958 … … 974 979 } 975 980 976 // should I check here?981 977 982 viewCell->mLeaf = leaf; 978 983 … … 984 989 leaf->mProbability = tData.mProbability; 985 990 991 // finally evaluate stats until this leaf 986 992 EvaluateLeafStats(tData); 987 993 } … … 1029 1035 1030 1036 // compute global decrease in render cost 1031 splitData.m RenderCost= EvalRenderCostDecrease(splitData.mSplitPlane, tData);1037 splitData.mPriority = EvalRenderCostDecrease(splitData.mSplitPlane, tData); 1032 1038 splitData.mParentData = tData; 1033 1039 splitData.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1; … … 1192 1198 1193 1199 // only count termination objects? 1194 if ( 1&& ray->mOriginObject)1200 if (COUNT_ORIGIN_OBJECTS && ray->mOriginObject) 1195 1201 { 1196 1202 if (vc->AddPvsSample(ray->mOriginObject, ray->mPdf, contribution)) 1197 1203 madeContrib = true; 1204 1198 1205 sc += contribution; 1199 1206 } … … 1214 1221 float maxBand) 1215 1222 { 1216 m SplitCandidates->clear();1223 mLocalSplitCandidates->clear(); 1217 1224 1218 1225 int requestedSize = 2 * (int)(rays.size()); 1219 1226 // creates a sorted split candidates array 1220 if (m SplitCandidates->capacity() > 500000 &&1221 requestedSize < (int)(m SplitCandidates->capacity() / 10) )1222 { 1223 delete m SplitCandidates;1224 m SplitCandidates = new vector<SortableEntry>;1225 } 1226 1227 m SplitCandidates->reserve(requestedSize);1227 if (mLocalSplitCandidates->capacity() > 500000 && 1228 requestedSize < (int)(mLocalSplitCandidates->capacity() / 10) ) 1229 { 1230 delete mLocalSplitCandidates; 1231 mLocalSplitCandidates = new vector<SortableEntry>; 1232 } 1233 1234 mLocalSplitCandidates->reserve(requestedSize); 1228 1235 1229 1236 float pos; … … 1245 1252 if (0) ClipValue(pos, minBand, maxBand); 1246 1253 1247 m SplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMin : SortableEntry::ERayMax,1254 mLocalSplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMin : SortableEntry::ERayMax, 1248 1255 pos, (*ri).mRay)); 1249 1256 … … 1252 1259 if (0) ClipValue(pos, minBand, maxBand); 1253 1260 1254 m SplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMax : SortableEntry::ERayMin,1261 mLocalSplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMax : SortableEntry::ERayMin, 1255 1262 pos, (*ri).mRay)); 1256 1263 } 1257 1264 1258 stable_sort(m SplitCandidates->begin(), mSplitCandidates->end());1265 stable_sort(mLocalSplitCandidates->begin(), mLocalSplitCandidates->end()); 1259 1266 } 1260 1267 … … 1307 1314 Intersectable *tObject = (*ri).mRay->mTerminationObject; 1308 1315 1309 if ( oObject)1316 if (COUNT_ORIGIN_OBJECTS && oObject) 1310 1317 { 1311 1318 if (!oObject->Mailed()) … … 1319 1326 } 1320 1327 } 1328 1321 1329 if (tObject) 1322 1330 { … … 1335 1343 Intersectable::NewMail(); 1336 1344 1337 vector<SortableEntry>::const_iterator ci, ci_end = m SplitCandidates->end();1338 1339 for (ci = m SplitCandidates->begin(); ci != ci_end; ++ ci)1345 vector<SortableEntry>::const_iterator ci, ci_end = mLocalSplitCandidates->end(); 1346 1347 for (ci = mLocalSplitCandidates->begin(); ci != ci_end; ++ ci) 1340 1348 { 1341 1349 VssRay *ray; … … 1350 1358 case SortableEntry::ERayMin: 1351 1359 { 1352 if ( oObject && !oObject->Mailed())1360 if (COUNT_ORIGIN_OBJECTS && oObject && !oObject->Mailed()) 1353 1361 { 1354 1362 oObject->Mail(); 1355 1363 ++ pvsl; 1356 1364 } 1365 1357 1366 if (tObject && !tObject->Mailed()) 1358 1367 { … … 1360 1369 ++ pvsl; 1361 1370 } 1371 1362 1372 break; 1363 1373 } 1364 1374 case SortableEntry::ERayMax: 1365 1375 { 1366 if ( oObject)1376 if (COUNT_ORIGIN_OBJECTS && oObject) 1367 1377 { 1368 1378 if (-- oObject->mCounter == 0) … … 1379 1389 } 1380 1390 } 1381 1382 1383 1384 // Note: sufficient to compare size of bounding boxes of front and back side? 1391 1392 1393 // Note: we compare size of bounding boxes of front and back side because 1394 // of efficiency reasons (otherwise a new geometry would have to be computed 1395 // in each step and incremential evaluation would be difficult. 1396 // but then errors happen if the geometry is not an axis aligned box 1397 // (i.e., if a geometry aligned split was taken before) 1398 // question: is it sufficient to make this approximation? 1385 1399 if (((*ci).value >= minBand) && ((*ci).value <= maxBand)) 1386 1400 { … … 1873 1887 // find front and back pvs for origing and termination object 1874 1888 AddObjToPvs(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs); 1875 AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs); 1889 1890 if (COUNT_ORIGIN_OBJECTS) 1891 AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs); 1876 1892 } 1877 1893 … … 1910 1926 1911 1927 // -- pvs rendering heuristics 1928 1929 // upper and lower bounds 1912 1930 const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize(); 1913 1931 const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize(); 1914 1932 1915 // only render cost heuristics or combined with standard deviation 1916 const float penaltyOld = EvalPvsPenalty(totalPvs, lowerPvsLimit, upperPvsLimit); 1917 const float penaltyFront = EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit); 1918 const float penaltyBack = EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit); 1933 const float penaltyOld = EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit); 1934 const float penaltyFront = EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit); 1935 const float penaltyBack = EvalPvsPenalty((int)pvsBack, lowerPvsLimit, upperPvsLimit); 1919 1936 1920 1937 const float oldRenderCost = pOverall * penaltyOld; … … 1924 1941 const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBox.GetVolume(); 1925 1942 1926 1927 #if 1 1943 const float weight = mRenderCostDecreaseWeight; 1928 1944 // take render cost of node into account to avoid being stuck in a local minimum 1929 1945 const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume(); 1930 1946 1931 //Debug << "rendercostdecr: " << 0.99f * renderCostDecrease << " old render cost: " << 0.01f * normalizedOldRenderCost << endl; 1932 return 0.99f * renderCostDecrease + 0.01f * normalizedOldRenderCost; 1933 #else 1934 return renderCostDecrease; 1935 #endif 1947 //Debug << "rendercostdecr: " << weight * renderCostDecrease << " old render cost: " << (1.0f - weight) * normalizedOldRenderCost << endl; 1948 return weight * renderCostDecrease + (1.0f - weight) * normalizedOldRenderCost; 1936 1949 } 1937 1950 … … 1944 1957 float &pBack) const 1945 1958 { 1946 float cost = 0;1947 1948 1959 float totalPvs = 0; 1949 1960 float pvsFront = 0; … … 1957 1968 pBack = 0; 1958 1969 1959 1960 int limit; 1961 bool useRand; 1962 1970 int numTests; // the number of tests 1971 1972 // if random samples shold be taken instead of testing all the rays 1973 bool useRand; 1974 1975 if ((int)data.mRays->size() > mMaxTests) 1976 { 1977 useRand = true; 1978 numTests = mMaxTests; 1979 } 1980 else 1981 { 1982 useRand = false; 1983 numTests = (int)data.mRays->size(); 1984 } 1985 1963 1986 // create unique ids for pvs heuristics 1964 1987 GenerateUniqueIdsForPvs(); 1965 1988 1966 // choose test rays randomly if too much 1967 if ((int)data.mRays->size() > mMaxTests) 1968 { 1969 useRand = true; 1970 limit = mMaxTests; 1971 } 1972 else 1973 { 1974 useRand = false; 1975 limit = (int)data.mRays->size(); 1976 } 1977 1978 for (int i = 0; i < limit; ++ i) 1989 for (int i = 0; i < numTests; ++ i) 1979 1990 { 1980 1991 const int testIdx = useRand ? … … 1988 1999 // find front and back pvs for origing and termination object 1989 2000 AddObjToPvs(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs); 1990 AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs); 2001 2002 if (COUNT_ORIGIN_OBJECTS) 2003 AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs); 1991 2004 } 1992 2005 … … 2057 2070 } 2058 2071 2059 co st += mPvsFactor * newCost / (oldCost + Limits::Small);2072 const float cost = mPvsFactor * newCost / (oldCost + Limits::Small); 2060 2073 2061 2074 … … 2165 2178 for(rit = data.mRays->begin(); rit != rit_end; ++ rit) 2166 2179 { 2167 //if (!(*rit).mRay->IsActive()) continue;2168 2169 2180 // determine the side of this ray with respect to the plane 2170 2181 float t; … … 2172 2183 2173 2184 AddObjToPvs((*rit).mRay->mTerminationObject, side, pvsFront, pvsBack, pvsTotal); 2174 AddObjToPvs((*rit).mRay->mOriginObject, side, pvsFront, pvsBack, pvsTotal); 2175 } 2185 2186 if (COUNT_ORIGIN_OBJECTS) 2187 AddObjToPvs((*rit).mRay->mOriginObject, side, pvsFront, pvsBack, pvsTotal); 2188 } 2189 2176 2190 2177 2191 //-- pvs heuristics 2178 float pOverall; 2179 2180 //-- compute heurstics 2181 //-- we take simplified computation for mid split 2182 2183 pOverall = data.mProbability; 2184 2192 2193 float pOverall = data.mProbability; 2194 2195 // note: we use a simplified computation assuming that we always do a 2196 // spatial mid split 2197 2185 2198 if (!mUseAreaForPvs) 2186 { // volume 2199 { 2200 // volume 2187 2201 pBack = pFront = pOverall * 0.5f; 2188 2189 2202 #if 0 2190 2203 // box length substitute for probability … … 3220 3233 VssRay *ray = (*rit).mRay; 3221 3234 3222 if ( ray->mOriginObject)3235 if (COUNT_ORIGIN_OBJECTS && ray->mOriginObject) 3223 3236 { 3224 3237 if (!ray->mOriginObject->Mailed()) … … 3228 3241 } 3229 3242 } 3243 3230 3244 if (ray->mTerminationObject) 3231 3245 { … … 3343 3357 } 3344 3358 else // one of the ray end points is on the plane 3345 { // NOTE: what to do if ray is coincident with plane? 3359 { 3360 // NOTE: what to do if ray is coincident with plane? 3346 3361 if (extSide < 0) 3347 3362 node = in->GetBack(); … … 3365 3380 ViewCell *viewCell; 3366 3381 3382 // question: always contribute to leaf or to currently active view cell? 3367 3383 if (0) 3368 3384 viewCell = mViewCellsTree->GetActiveViewCell(leaf->GetViewCell());
Note: See TracChangeset
for help on using the changeset viewer.