- Timestamp:
- 09/14/06 18:55:38 (18 years ago)
- Location:
- GTP/trunk/Lib/Vis/Preprocessing/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
r1359 r1370 17 17 #include "Beam.h" 18 18 #include "VspTree.h" 19 #include "HierarchyManager.h" 19 20 20 21 … … 22 23 23 24 25 #define PROBABILIY_IS_BV_VOLUME 1 24 26 #define USE_FIXEDPOINT_T 0 25 27 … … 197 199 Randomize(); // initialise random generator for heuristics 198 200 201 202 ///////////////////////////////////////////////////////////// 199 203 //-- termination criteria for autopartition 200 204 Environment::GetSingleton()->GetIntValue("BvHierarchy.Termination.maxDepth", mTermMaxDepth); 201 205 Environment::GetSingleton()->GetIntValue("BvHierarchy.Termination.maxLeaves", mTermMaxLeaves); 202 206 Environment::GetSingleton()->GetIntValue("BvHierarchy.Termination.minObjects", mTermMinObjects); 207 Environment::GetSingleton()->GetIntValue("BvHierarchy.Termination.minRays", mTermMinRays); 203 208 Environment::GetSingleton()->GetFloatValue("BvHierarchy.Termination.minProbability", mTermMinProbability); 204 209 205 210 Environment::GetSingleton()->GetIntValue("BvHierarchy.Termination.missTolerance", mTermMissTolerance); 206 211 212 213 //////////////////////////////////////////////// 207 214 //-- max cost ratio for early tree termination 215 208 216 Environment::GetSingleton()->GetFloatValue("BvHierarchy.Termination.maxCostRatio", mTermMaxCostRatio); 209 210 217 Environment::GetSingleton()->GetFloatValue("BvHierarchy.Termination.minGlobalCostRatio", 211 218 mTermMinGlobalCostRatio); … … 213 220 mTermGlobalCostMissTolerance); 214 221 215 //-- factors for bsp tree split plane heuristics 216 217 // if only the driving axis is used for axis aligned split 222 223 ///////////////////////////////////////// 224 //-- factors for subdivision heuristics 225 226 // if only the driving axis is used for splits 218 227 Environment::GetSingleton()->GetBoolValue("BvHierarchy.splitUseOnlyDrivingAxis", mOnlyDrivingAxis); 219 228 Environment::GetSingleton()->GetFloatValue("BvHierarchy.maxStaticMemory", mMaxMemory); … … 263 272 } 264 273 274 static int CountRays(const ObjectContainer &objects) 275 { 276 int nRays = 0; 277 278 ObjectContainer::const_iterator oit, oit_end = objects.end(); 279 280 for (oit = objects.begin(); oit != oit_end; ++ oit) 281 { 282 nRays += (int)(*oit)->mVssRays.size(); 283 } 284 285 return nRays; 286 } 265 287 266 288 BvhInterior *BvHierarchy::SubdivideNode(const BvhSubdivisionCandidate &sc, … … 268 290 BvhTraversalData &backData) 269 291 { 292 mBvhStats.nodes += 2; // we have two new leaves 293 270 294 const BvhTraversalData &tData = sc.mParentData; 271 295 BvhLeaf *leaf = tData.mNode; 272 mBvhStats.nodes += 2; // we have two new leaves 296 AxisAlignedBox3 parentBox = leaf->GetBoundingBox(); 273 297 274 298 // add the new nodes to the tree 275 BvhInterior *node = new BvhInterior(tData.mBoundingBox, leaf->GetParent()); 276 299 BvhInterior *node = new BvhInterior(parentBox, leaf->GetParent()); 300 301 302 //////////////////////////////// 303 //-- create front and back leaf 304 305 AxisAlignedBox3 fbox = ComputeBoundingBox(sc.mFrontObjects, &parentBox); 306 AxisAlignedBox3 bbox = ComputeBoundingBox(sc.mBackObjects, &parentBox); 307 308 BvhLeaf *back = 309 new BvhLeaf(bbox, node, (int)sc.mBackObjects.size()); 310 BvhLeaf *front = 311 new BvhLeaf(fbox, node, (int)sc.mFrontObjects.size()); 312 313 BvhInterior *parent = leaf->GetParent(); 314 315 // replace a link from node's parent 316 if (parent) 317 { 318 parent->ReplaceChildLink(leaf, node); 319 node->SetParent(parent); 320 } 321 else // no parent => this node is the root 322 { 323 mRoot = node; 324 } 325 326 // and setup child links 327 node->SetupChildLinks(front, back); 328 329 ++ mBvhStats.splits; 330 277 331 278 332 /////////////////////////////////////////////////////////////////// … … 281 335 frontData.mDepth = backData.mDepth = tData.mDepth + 1; 282 336 283 frontData.mBoundingBox = ComputeBoundingBox(sc.mFrontObjects, &tData.mBoundingBox);284 backData.mBoundingBox = ComputeBoundingBox(sc.mBackObjects, &tData.mBoundingBox);285 286 287 ////////////////////////////////288 //-- create front and back leaf289 290 BvhLeaf *back =291 new BvhLeaf(backData.mBoundingBox, node, (int)sc.mBackObjects.size());292 BvhLeaf *front =293 new BvhLeaf(frontData.mBoundingBox, node, (int)sc.mFrontObjects.size());294 295 BvhInterior *parent = leaf->GetParent();296 297 // replace a link from node's parent298 if (parent)299 {300 parent->ReplaceChildLink(leaf, node);301 node->SetParent(parent);302 }303 else // no parent => this node is the root304 {305 mRoot = node;306 }307 308 // and setup child links309 node->SetupChildLinks(front, back);310 311 ++ mBvhStats.splits;312 313 ////////////////////////////////////314 //-- fill traversal data315 316 337 frontData.mNode = front; 317 338 backData.mNode = back; … … 319 340 back->mObjects = sc.mBackObjects; 320 341 front->mObjects = sc.mFrontObjects; 342 343 // if the number of rays is too low, no assumptions can be made 344 // (=> switch to surface area heuristics?) 345 frontData.mNumRays = CountRays(sc.mFrontObjects); 346 backData.mNumRays = CountRays(sc.mBackObjects); 321 347 322 348 AssociateObjectsWithLeaf(back); 323 349 AssociateObjectsWithLeaf(front); 324 350 351 #if PROBABILIY_IS_BV_VOLUME 352 // volume of bvh (= probability that this bvh can be seen) 353 frontData.mProbability = fbox.GetVolume(); 354 backData.mProbability = bbox.GetVolume(); 355 #else 325 356 // compute probability of this node being visible, 326 357 // i.e., volume of the view cells that can see this node 327 358 frontData.mProbability = EvalViewCellsVolume(sc.mFrontObjects); 328 359 backData.mProbability = EvalViewCellsVolume(sc.mBackObjects); 360 #endif 329 361 330 362 // how often was max cost ratio missed in this branch? … … 389 421 tBackData.mNode->SetSubdivisionCandidate(backCandidate); 390 422 391 Debug << "leaf: " << tFrontData.mNode << " setting f candidate: "392 << tFrontData.mNode->GetSubdivisionCandidate() << " type: "393 << tFrontData.mNode->GetSubdivisionCandidate()->Type() << endl;394 395 Debug << "leaf: " << tBackData.mNode << " setting b candidate: "396 << tBackData.mNode->GetSubdivisionCandidate() << " type: "397 << tBackData.mNode->GetSubdivisionCandidate()->Type() << endl;398 399 423 tQueue.Push(frontCandidate); 400 424 tQueue.Push(backCandidate); … … 460 484 const float renderCostDecr = oldRenderCost - newRenderCost; 461 485 462 Debug << "\nbvh render cost decr: " << renderCostDecr << endl;486 //Debug << "\nbvh render cost decr: " << renderCostDecr << endl; 463 487 splitCandidate.SetRenderCostDecrease(renderCostDecr); 464 488 … … 481 505 // matt: TODO 482 506 return ( 0 483 //|| ((int)data.mNode->mObjects.size() < mTermMinObjects) 484 //|| (data.mProbability <= mTermMinProbability) 485 //|| (data.mDepth >= mTermMaxDepth) 507 || ((int)data.mNode->mObjects.size() < mTermMinObjects) 508 || (data.mProbability <= mTermMinProbability) 509 || (data.mDepth >= mTermMaxDepth) 510 || (data.mNumRays <= mTermMinRays) 486 511 ); 487 512 } … … 493 518 return (0 494 519 || (mBvhStats.Leaves() >= mTermMaxLeaves) 495 //|| (mGlobalCostMisses >= mTermGlobalCostMissTolerance)520 || (mGlobalCostMisses >= mTermGlobalCostMissTolerance) 496 521 //|| mOutOfMemory 497 522 ); … … 506 531 ++ mCreatedLeaves; 507 532 533 534 if (data.mProbability <= mTermMinProbability) 535 { 536 ++ mBvhStats.minProbabilityNodes; 537 } 538 539 //////////////////////////////////////////// 540 // depth related stuff 541 542 if (data.mDepth > mBvhStats.maxDepth) 543 { 544 mBvhStats.maxDepth = data.mDepth; 545 } 546 547 if (data.mDepth < mBvhStats.minDepth) 548 { 549 mBvhStats.minDepth = data.mDepth; 550 } 551 508 552 if (data.mDepth >= mTermMaxDepth) 509 553 { 510 554 ++ mBvhStats.maxDepthNodes; 511 //Debug << "new max depth: " << mVspStats.maxDepthNodes << endl; 512 } 513 514 if (data.mDepth < mTermMaxDepth) 515 { 516 ++ mBvhStats.minDepthNodes; 517 } 518 519 if (data.mProbability <= mTermMinProbability) 520 ++ mBvhStats.minProbabilityNodes; 521 555 } 556 522 557 // accumulate depth to compute average depth 523 558 mBvhStats.accumDepth += data.mDepth; 524 525 if ((int)(leaf->mObjects.size()) < mTermMinObjects) 559 560 561 //////////////////////////////////////////// 562 // objects related stuff 563 564 // note: this number should always accumulate to the total number of objects 565 mBvhStats.objectRefs += (int)leaf->mObjects.size(); 566 567 if ((int)leaf->mObjects.size() <= mTermMinObjects) 568 { 526 569 ++ mBvhStats.minObjectsNodes; 527 528 if ((int)(leaf->mObjects.size()) > mBvhStats.maxObjectRefs) 570 } 571 572 if ((int)leaf->mObjects.size() > mBvhStats.maxObjectRefs) 573 { 529 574 mBvhStats.maxObjectRefs = (int)leaf->mObjects.size(); 575 } 576 577 if ((int)leaf->mObjects.size() < mBvhStats.minObjectRefs) 578 { 579 mBvhStats.minObjectRefs = (int)leaf->mObjects.size(); 580 } 581 582 //////////////////////////////////////////// 583 // ray related stuff 584 585 // note: this number should always accumulate to the total number of rays 586 mBvhStats.rayRefs += data.mNumRays; 587 588 if (data.mNumRays <= mTermMinRays) 589 { 590 ++ mBvhStats.minRaysNodes; 591 } 592 593 if (data.mNumRays > mBvhStats.maxRayRefs) 594 { 595 mBvhStats.maxRayRefs = data.mNumRays; 596 } 597 598 if (data.mNumRays < mBvhStats.minRayRefs) 599 { 600 mBvhStats.minRayRefs = data.mNumRays; 601 } 602 603 cout << "depth: " << data.mDepth << " objects: " << (int)leaf->mObjects.size() 604 << " rays: " << data.mNumRays << " rays / objects " 605 << (float)data.mNumRays / (float)leaf->mObjects.size() << endl; 530 606 } 531 607 532 608 533 609 #if 0 610 611 /// compute object boundaries using spatial mid split 534 612 float BvHierarchy::EvalLocalObjectPartition(const BvhTraversalData &tData, 535 613 const int axis, … … 553 631 // object mailed => belongs to back objects 554 632 if (objMid < midPoint) 633 { 555 634 objectsBack.push_back(obj); 635 } 556 636 else 637 { 557 638 objectsFront.push_back(obj); 558 } 559 560 const float oldRenderCost = tData.mProbability * (float)tData.mNode->mObjects.size(); 639 } 640 } 641 642 const float oldProp = EvalViewCellsVolume(tData.mNode->mObjects); 643 //const float oldProp = tData.mProbability; 644 645 const float oldRenderCost = oldProb * (float)tData.mNode->mObjects.size(); 561 646 const float newRenderCost = 562 647 EvalRenderCost(tData, objectsFront, objectsBack); … … 568 653 #else 569 654 655 /// compute object partition by getting balanced objects on the left and right side 570 656 float BvHierarchy::EvalLocalObjectPartition(const BvhTraversalData &tData, 571 657 const int axis, … … 592 678 593 679 const float oldProp = EvalViewCellsVolume(tData.mNode->mObjects); 594 //const float oldProp 2= tData.mProbability;680 //const float oldProp = tData.mProbability; 595 681 596 682 const float oldRenderCost = oldProp * (float)tData.mNode->mObjects.size(); … … 649 735 650 736 vector<float>::const_iterator bit = bordersRight.begin(); 651 737 cout << "here42" << endl; 652 738 SortableEntryContainer::const_iterator cit, cit_end = mSubdivisionCandidates->end(); 653 739 for (cit = mSubdivisionCandidates->begin(); cit != cit_end; ++ cit, ++ bit) … … 671 757 const float sum = objectsLeft * lbox.SurfaceArea() + objectsRight * rbox.SurfaceArea(); 672 758 673 // cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl; 674 // cout<<"cost= "<<sum<<endl; 759 cout << "pos=" << (*cit).mPos << "\t q=(" << objectsLeft << "," << objectsRight <<")\t r=(" 760 << lbox.SurfaceArea() << "," << rbox.SurfaceArea() << ")" << endl; 761 cout << "cost= " << sum << endl; 675 762 676 763 if (sum < minSum) 677 764 { 678 765 minSum = sum; 679 // objects belong sto left side now766 // objects belong to left side now 680 767 for (; currentPos != (cit + 1); ++ currentPos); 681 768 } 682 769 } 683 770 771 //////////////////////////////////////////// 684 772 //-- assign object to front and back volume 685 773 … … 796 884 { 797 885 Intersectable *object = (*cit).mObject; 798 886 799 887 // evaluate change in l and r volume 800 888 // voll = view cells that see only left node (i.e., left pvs) … … 864 952 { 865 953 //-- insert object queries 866 ObjectContainer *objects; 867 868 if (!mUseGlobalSorting) 869 objects = &tData.mNode->mObjects; 870 else 871 objects = tData.mSortedObjects[axis]; 872 873 CreateLocalSubdivisionCandidates(*objects, &mSubdivisionCandidates, mUseGlobalSorting, axis); 954 ObjectContainer *objects = mUseGlobalSorting ? tData.mSortedObjects[axis] : &tData.mNode->mObjects; 955 956 CreateLocalSubdivisionCandidates(*objects, &mSubdivisionCandidates, !mUseGlobalSorting, axis); 874 957 } 875 958 … … 937 1020 } 938 1021 939 // mail the objects on the left side 940 Intersectable::NewMail(); 941 // mail view cells on the left side 1022 // we will mail view cells switching to the back side 942 1023 ViewCell::NewMail(); 943 1024 … … 1009 1090 ObjectContainer nFrontObjects[3]; 1010 1091 ObjectContainer nBackObjects[3]; 1011 1012 1092 float nCostRatio[3]; 1013 1093 1014 // create bounding box of node geometry1015 AxisAlignedBox3 box = tData.mBoundingBox;1016 1017 1094 int sAxis = 0; 1018 1095 int bestAxis = -1; … … 1020 1097 if (mOnlyDrivingAxis) 1021 1098 { 1099 const AxisAlignedBox3 box = tData.mNode->GetBoundingBox(); 1022 1100 sAxis = box.Size().DrivingAxis(); 1023 1101 } … … 1032 1110 if (mUseCostHeuristics) 1033 1111 { 1034 //-- partition objects using heuristics 1035 nCostRatio[axis] = 1036 EvalLocalCostHeuristics( 1037 tData, 1038 axis, 1039 nFrontObjects[axis], 1040 nBackObjects[axis]); 1112 ////////////////////////////////// 1113 //-- split objects using heuristics 1114 1115 if (mHierarchyManager->GetViewSpaceSubdivisionType() == 1116 HierarchyManager::KD_BASED_VIEWSPACE_SUBDIV) 1117 { 1118 //-- heuristics using objects weighted by view cells volume 1119 nCostRatio[axis] = 1120 EvalLocalCostHeuristics( 1121 tData, 1122 axis, 1123 nFrontObjects[axis], 1124 nBackObjects[axis]); 1125 } 1126 else 1127 { 1128 //-- use surface area heuristic because view cells not constructed yet 1129 nCostRatio[axis] = 1130 EvalLocalCostHeuristics( 1131 tData, 1132 axis, 1133 nFrontObjects[axis], 1134 nBackObjects[axis]); 1135 } 1041 1136 } 1042 1137 else 1043 1138 { 1139 //-- split objects using some simple criteria 1140 1044 1141 nCostRatio[axis] = 1045 1142 EvalLocalObjectPartition( … … 1072 1169 1073 1170 1074 void BvHierarchy::AssociateObjectsWithRays(const VssRayContainer &rays) 1075 { 1076 1171 int BvHierarchy::AssociateObjectsWithRays(const VssRayContainer &rays) const 1172 { 1173 int nRays = 0; 1077 1174 VssRayContainer::const_iterator rit, rit_end = rays.end(); 1175 1176 VssRay::NewMail(); 1078 1177 1079 1178 for (rit = rays.begin(); rit != rays.end(); ++ rit) … … 1084 1183 { 1085 1184 ray->mTerminationObject->mVssRays.push_back(ray); 1086 } 1087 1088 if (0 && ray->mOriginObject) 1185 if (!ray->Mailed()) 1186 { 1187 ray->Mail(); 1188 ++ nRays; 1189 } 1190 } 1191 1192 if (1 && ray->mOriginObject) 1089 1193 { 1090 1194 ray->mOriginObject->mVssRays.push_back(ray); 1091 } 1092 } 1195 1196 if (!ray->Mailed()) 1197 { 1198 ray->Mail(); 1199 ++ nRays; 1200 } 1201 } 1202 } 1203 1204 return nRays; 1093 1205 } 1094 1206 … … 1137 1249 const ObjectContainer &objectsBack) const 1138 1250 { 1139 BvhLeaf *leaf = tData.mNode;1140 1141 1251 // probability that view point lies in a view cell which sees this node 1142 1252 const float pFront = EvalViewCellsVolume(objectsFront); 1143 1253 const float pBack = EvalViewCellsVolume(objectsBack); 1144 1254 1145 const int totalObjects = (int)leaf->mObjects.size();1146 const int nObjectsFront = (int)objectsFront.size();1147 const int nObjectsBack = (int)objectsBack.size();1148 1149 1255 //-- pvs rendering heuristics 1150 const float newRenderCost = nObjectsFront * pFront + nObjectsBack* pBack;1256 const float newRenderCost = (int)objectsFront.size() * pFront + (int)objectsBack.size() * pBack; 1151 1257 1152 1258 #ifdef _DEBUG … … 1171 1277 ObjectContainer::const_iterator oit, oit_end = objects.end(); 1172 1278 1173 //-- compute bounding box1174 1279 for (oit = objects.begin(); oit != oit_end; ++ oit) 1175 1280 { 1176 1281 Intersectable *obj = *oit; 1177 1282 1178 // compute bounding box of view space1283 // grow bounding box to include all objects 1179 1284 box.Include(obj->GetBox()); 1180 1285 } … … 1496 1601 BvhSubdivisionCandidate::sBvHierarchy = this; 1497 1602 mBvhStats.nodes = 1; 1603 mGlobalCostMisses = 0; 1498 1604 1499 1605 // compute bounding box from objects … … 1502 1608 BvhLeaf *bvhleaf = dynamic_cast<BvhLeaf *>(mRoot); 1503 1609 1610 // multiply termination criterium for comparison, 1611 // so it can be set between zero and one and 1612 // no division is necessary during traversal 1613 1614 #if PROBABILIY_IS_BV_VOLUME 1504 1615 mTermMinProbability *= mBoundingBox.GetVolume(); 1505 mGlobalCostMisses = 0; 1506 1616 // probability that bounding volume is seen 1617 const float prop = GetBoundingBox().GetVolume(); 1618 #else 1619 mTermMinProbability *= mVspTree->GetBoundingBox().GetVolume(); 1620 // probability that volume is "seen" from the view cells 1621 const float prop = EvalViewCellsVolume(objects); 1622 #endif 1623 1507 1624 // only rays intersecting objects in node are interesting 1508 AssociateObjectsWithRays(sampleRays); 1509 1510 // probabilty is voume of all "seen" view cells 1511 #if 1 1512 const float prop = EvalViewCellsVolume(objects); 1513 #else 1514 const float prop = GetBoundingBox().GetVolume(); 1515 #endif 1625 const int nRays = AssociateObjectsWithRays(sampleRays); 1626 //Debug << "using " << nRays << " of " << (int)sampleRays.size() << " rays" << endl; 1516 1627 1517 1628 // create bvh traversal data 1518 BvhTraversalData oData(bvhleaf, 0, mBoundingBox, prop);1629 BvhTraversalData oData(bvhleaf, 0, prop, nRays); 1519 1630 1520 1631 // create sorted object lists for the first data … … 1540 1651 1541 1652 return oSubdivisionCandidate; 1542 }1543 1544 1545 bool BvHierarchy::AddLeafToPvs(BvhLeaf *leaf,1546 ViewCell *vc,1547 const float pdf,1548 float &contribution)1549 {1550 // add kd intersecable to pvs1551 BvhIntersectable *bvhObj = GetOrCreateBvhIntersectable(leaf);1552 1553 return vc->AddPvsSample(bvhObj, pdf, contribution);1554 1653 } 1555 1654 … … 1602 1701 backData.mSortedObjects[i]->reserve((int)sc.mFrontObjects.size()); 1603 1702 1604 ObjectContainer::const_iterator oit, oit_end = sc.mParentData.m Node->mObjects.end();1605 1606 for (oit = sc.mParentData.m Node->mObjects.begin(); oit != oit_end; ++ oit)1703 ObjectContainer::const_iterator oit, oit_end = sc.mParentData.mSortedObjects[i]->end(); 1704 1705 for (oit = sc.mParentData.mSortedObjects[i]->begin(); oit != oit_end; ++ oit) 1607 1706 { 1608 1707 if ((*oit)->Mailed()) … … 1635 1734 app << "#AXIS_ALIGNED_SPLITS (number of axis aligned splits)\n" << splits << endl; 1636 1735 1637 app << "#N_PMINDEPTHLEAVES ( Percentage of leaves at minimum depth )\n" 1638 << minDepthNodes * 100 / (double)Leaves() << endl; 1639 1736 app << "#N_MAXCOSTNODES ( Percentage of leaves with terminated because of max cost ratio )\n" 1737 << maxCostNodes * 100 / (double)Leaves() << endl; 1738 1739 app << "#N_PMINPROBABILITYLEAVES ( Percentage of leaves with mininum probability )\n" 1740 << minProbabilityNodes * 100 / (double)Leaves() << endl; 1741 1742 1743 ////////////////////////////////////////////////// 1744 1640 1745 app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n" 1641 1746 << maxDepthNodes * 100 / (double)Leaves() << endl; 1642 1643 app << "#N_MAXCOSTNODES ( Percentage of leaves with terminated because of max cost ratio )\n" 1644 << maxCostNodes * 100 / (double)Leaves() << endl; 1645 1646 app << "#N_PMINPROBABILITYLEAVES ( Percentage of leaves with mininum probability )\n" 1647 << minProbabilityNodes * 100 / (double)Leaves() << endl; 1648 1747 1748 app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl; 1749 1750 app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl; 1751 1752 app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl; 1753 1754 1755 //////////////////////////////////////////////////////// 1756 1649 1757 app << "#N_PMINOBJECTSLEAVES ( Percentage of leaves with mininum objects )\n" 1650 1758 << minObjectsNodes * 100 / (double)Leaves() << endl; 1651 1759 1652 app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl;1653 1654 app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl;1655 1656 app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl;1657 1658 app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl;1659 1660 1760 app << "#N_MAXOBJECTREFS ( Max number of object refs / leaf )\n" << maxObjectRefs << "\n"; 1661 1761 1662 //app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl; 1663 1664 app << "========== END OF VspTree statistics ==========\n"; 1665 } 1666 1667 1668 } 1762 app << "#N_MINOBJECTREFS ( Min number of object refs / leaf )\n" << minObjectRefs << "\n"; 1763 1764 app << "#N_PAVGOBJECTSLEAVES ( average object refs / leaf)\n" << AvgObjectRefs() << endl; 1765 1766 1767 //////////////////////////////////////////////////////// 1768 1769 app << "#N_PMINRAYSLEAVES ( Percentage of leaves with mininum rays )\n" 1770 << minRaysNodes * 100 / (double)Leaves() << endl; 1771 1772 app << "#N_MAXRAYREFS ( Max number of ray refs / leaf )\n" << maxRayRefs << "\n"; 1773 1774 app << "#N_MINRAYREFS ( Min number of ray refs / leaf )\n" << minRayRefs << "\n"; 1775 1776 app << "#N_PAVGRAYLEAVES ( average ray refs / leaf )\n" << AvgRayRefs() << endl; 1777 1778 app << "#N_PAVGRAYCONTRIBLEAVES ( Average ray contribution)\n" << 1779 rayRefs / (double)objectRefs << endl; 1780 1781 app << "#N_PMAXRAYCONTRIBLEAVES ( Percentage of leaves with maximal ray contribution )\n"<< 1782 maxRayContriNodes * 100 / (double)Leaves() << endl; 1783 1784 app << "========== END OF BvHierarchy statistics ==========\n"; 1785 } 1786 1787 1788 } -
GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
r1357 r1370 35 35 class VspTree; 36 36 class ViewCellsContainer; 37 class HierarchyManager; 37 38 38 39 … … 42 43 { 43 44 public: 45 46 /// Constructor 47 BvhStatistics() 48 { 49 Reset(); 50 } 51 52 int Nodes() const {return nodes;} 53 int Interior() const { return nodes / 2; } 54 int Leaves() const { return (nodes / 2) + 1; } 55 56 double AvgDepth() const 57 { return accumDepth / (double)Leaves(); } 58 59 double AvgObjectRefs() const 60 { return objectRefs / (double)Leaves(); } 61 62 double AvgRayRefs() const 63 { return rayRefs / (double)Leaves(); } 64 65 66 void Reset() 67 { 68 nodes = 0; 69 splits = 0; 70 maxDepth = 0; 71 minDepth = 99999; 72 accumDepth = 0; 73 maxDepthNodes = 0; 74 minProbabilityNodes = 0; 75 maxCostNodes = 0; 76 77 /////////////////// 78 minObjectsNodes = 0; 79 maxObjectRefs = 0; 80 minObjectRefs = 999999999; 81 objectRefs = 0; 82 83 /////////////////// 84 minRaysNodes = 0; 85 maxRayRefs = 0; 86 minRayRefs = 999999999; 87 rayRefs = 0; 88 maxRayContriNodes = 0; 89 } 90 91 92 public: 93 44 94 // total number of nodes 45 95 int nodes; … … 52 102 // max depth nodes 53 103 int maxDepthNodes; 54 // minimum depth nodes 55 int minDepthNodes; 56 // nodes with minimum objects 57 int minObjectsNodes; 104 // accumulated depth (used to compute average) 105 int accumDepth; 58 106 // minimum area nodes 59 107 int minProbabilityNodes; 60 108 /// nodes termination because of max cost ratio; 61 109 int maxCostNodes; 110 111 /////////////////////////// 112 // nodes with minimum objects 113 int minObjectsNodes; 62 114 // max number of rays per node 63 115 int maxObjectRefs; 64 /// number of invalid leaves 65 int invalidLeaves; 66 /// accumulated number of rays refs 67 //int accumRays; 68 // accumulated depth (used to compute average) 69 int accumDepth; 116 // min number of rays per node 117 int minObjectRefs; 70 118 /// object references 71 119 int objectRefs; 72 120 73 // Constructor 74 BvhStatistics() 75 { 76 Reset(); 77 } 78 79 int Nodes() const {return nodes;} 80 int Interior() const { return nodes / 2; } 81 int Leaves() const { return (nodes / 2) + 1; } 82 83 // TODO: computation wrong 84 double AvgDepth() const 85 { return accumDepth / (double)Leaves(); } 86 87 void Reset() 88 { 89 nodes = 0; 90 splits = 0; 91 92 maxDepth = 0; 93 minDepth = 99999; 94 accumDepth = 0; 95 maxDepthNodes = 0; 96 minObjectsNodes = 0; 97 minProbabilityNodes = 0; 98 maxCostNodes = 0; 99 invalidLeaves = 0; 100 maxObjectRefs = 0; 101 objectRefs = 0; 102 } 121 122 ////////////////////////// 123 // nodes with minimum rays 124 int minRaysNodes; 125 // max number of rays per node 126 int maxRayRefs; 127 // min number of rays per node 128 int minRayRefs; 129 /// object references 130 int rayRefs; 131 /// nodes with max ray contribution 132 int maxRayContriNodes; 103 133 104 134 void Print(ostream &app) const; … … 298 328 mProbability(0.0), 299 329 mMaxCostMisses(0), 300 mAxis(0) 330 mAxis(0), 331 mNumRays(0) 301 332 { 302 333 mSortedObjects[0] = mSortedObjects[1] = mSortedObjects[2] = NULL; … … 305 336 BvhTraversalData(BvhLeaf *node, 306 337 const int depth, 307 const AxisAlignedBox3 &box,308 const float v):338 const float v, 339 const int numRays): 309 340 mNode(node), 310 341 mDepth(depth), 311 mBoundingBox(box),342 //mBoundingBox(box), 312 343 mProbability(v), 313 344 mMaxCostMisses(0), 314 mAxis(0) 345 mAxis(0), 346 mNumRays(numRays) 315 347 { 316 348 mSortedObjects[0] = mSortedObjects[1] = mSortedObjects[2] = NULL; … … 322 354 { 323 355 DEL_PTR(mNode); 324 /*DEL_PTR(mSortedObjects[0]);356 DEL_PTR(mSortedObjects[0]); 325 357 DEL_PTR(mSortedObjects[1]); 326 DEL_PTR(mSortedObjects[2]); */358 DEL_PTR(mSortedObjects[2]); 327 359 } 328 360 … … 334 366 float mProbability; 335 367 /// the bounding box of the node 336 AxisAlignedBox3 mBoundingBox;368 //AxisAlignedBox3 mBoundingBox; 337 369 /// how often this branch has missed the max-cost ratio 338 370 int mMaxCostMisses; 339 371 /// current axis 340 372 int mAxis; 373 /// number of rays 374 int mNumRays; 341 375 /// the sorted objects for the three dimensions 342 376 ObjectContainer *mSortedObjects[3]; … … 496 530 ViewCellContainer &viewCells) const; 497 531 498 499 532 /** Returns leaf the point pt lies in, starting from root. 500 533 */ 501 534 BvhLeaf *GetLeaf(Intersectable *obj, BvhNode *root = NULL) const; 502 535 536 /** Sets a pointer to the view cells tree. 537 */ 503 538 ViewCellsTree *GetViewCellsTree() const { return mViewCellsTree; } 504 539 /** See Get 540 */ 505 541 void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; } 506 542 507 /** Add the bvh leaf to the pvs of the view cell.508 */509 bool AddLeafToPvs(510 BvhLeaf *leaf,511 ViewCell *vc,512 const float pdf,513 float &contribution);514 543 515 544 protected: … … 668 697 float PrepareHeuristics(const BvhTraversalData &tData, const int axis); 669 698 670 671 699 //////////////////////////////////////////////// 672 700 … … 678 706 const AxisAlignedBox3 *parentBox = NULL); 679 707 708 /** Collects list of invalid candidates. Candidates 709 are invalidated by a view space subdivision step 710 that affects this candidate. 711 */ 680 712 void CollectDirtyCandidates( 681 713 BvhSubdivisionCandidate *sc, … … 708 740 void PrintSubdivisionStats(const SubdivisionCandidate &tData); 709 741 742 /** Prints out the stats for this subdivision. 743 */ 710 744 void AddSubdivisionStats( 711 745 const int viewCells, … … 713 747 const float totalRenderCost); 714 748 715 void AssociateObjectsWithRays(const VssRayContainer &rays); 716 749 /** Stores rays with objects that see the rays. 750 */ 751 int AssociateObjectsWithRays(const VssRayContainer &rays) const; 752 753 /** Tests if object is in this leaf. 754 @note: assumes that objects are sorted by their id. 755 */ 717 756 bool IsObjectInLeaf(BvhLeaf *, Intersectable *object) const; 718 757 758 /** Prepares the construction of the bv hierarchy and returns 759 the first subdivision candidate. 760 */ 719 761 SubdivisionCandidate *PrepareConstruction( 720 762 const VssRayContainer &sampleRays, 721 const ObjectContainer &objects 722 ); 723 763 const ObjectContainer &objects); 764 765 /** Evaluates volume of view cells that see the objects. 766 */ 724 767 float EvalViewCellsVolume(const ObjectContainer &objects) const; 725 768 769 /** Creates initial list of sorted objects. 770 */ 726 771 void CreateInitialSortedObjectList(BvhTraversalData &tData); 727 772 773 /** Assigns sorted objects to front and back data. 774 */ 728 775 void AssignSortedObjects( 729 776 const BvhSubdivisionCandidate &sc, … … 736 783 /// pre-sorted subdivision candidtes for all three directions. 737 784 vector<SortableEntry> *mGlobalSubdivisionCandidates[3]; 738 739 785 /// pointer to the hierarchy of view cells 740 786 ViewCellsTree *mViewCellsTree; 741 787 /// pointer to the view space partition tree 742 788 VspTree *mVspTree; 743 744 789 /// The view cells manager 745 790 ViewCellsManager *mViewCellsManager; 746 747 791 /// candidates for placing split planes during cost heuristics 748 792 vector<SortableEntry> *mSubdivisionCandidates; 749 750 793 /// Pointer to the root of the tree 751 794 BvhNode *mRoot; 752 753 795 /// Statistics for the object space partition 754 BvhStatistics mBvhStats; 755 796 BvhStatistics mBvhStats; 756 797 /// box around the whole view domain 757 798 AxisAlignedBox3 mBoundingBox; 799 /// the hierarchy manager 800 HierarchyManager *mHierarchyManager; 758 801 759 802 … … 767 810 /// minimal number of objects 768 811 int mTermMinObjects; 769 /// maximal contribution per ray770 float mTermMaxRayContribution;771 812 /// maximal acceptable cost ratio 772 813 float mTermMaxCostRatio; 773 814 /// tolerance value indicating how often the max cost ratio can be failed 774 815 int mTermMissTolerance; 816 /// minimum number of rays 817 int mTermMinRays; 775 818 776 819 -
GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
r1359 r1370 2345 2345 "0.00001"); 2346 2346 2347 RegisterOption("BvHierarchy.Termination.minRays", 2348 optInt, 2349 "bvh_term_min_rays=", 2350 "0"); 2351 2347 2352 RegisterOption("BvHierarchy.Termination.missTolerance", 2348 2353 optInt, … … 2436 2441 "-1"); 2437 2442 2443 RegisterOption("Hierarchy.Construction.startWithObjectSpace", 2444 optBool, 2445 "hierarchy_construction_start_with_osp=", 2446 "true"); 2447 2438 2448 RegisterOption("Hierarchy.Construction.repairQueue", 2439 2449 optBool, … … 2441 2451 "true"); 2442 2452 2453 RegisterOption("Hierarchy.Construction.minDepthForVsp", 2454 optInt, 2455 "hierarchy_construction_min_depth_for_vsp=", 2456 "-1"); 2443 2457 2444 2458 ////////////////////////////////////////////////////////////////////////////////// -
GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
r1344 r1370 95 95 "Hierarchy.Termination.globalCostMissTolerance", mTermGlobalCostMissTolerance); 96 96 97 Environment::GetSingleton()->GetBoolValue( 98 "Hierarchy.Construction.startWithObjectSpace", mStartWithObjectSpace); 99 97 100 Environment::GetSingleton()->GetIntValue( 98 101 "Hierarchy.Termination.maxLeaves", mTermMaxLeaves); … … 103 106 Environment::GetSingleton()->GetIntValue( 104 107 "Hierarchy.Construction.minDepthForOsp", mMinDepthForObjectSpaceSubdivion); 108 109 Environment::GetSingleton()->GetIntValue( 110 "Hierarchy.Construction.minDepthForVsp", mMinDepthForViewSpaceSubdivion); 105 111 106 112 Environment::GetSingleton()->GetBoolValue( … … 125 131 126 132 133 int HierarchyManager::GetObjectSpaceSubdivisionType() const 134 { 135 return mObjectSpaceSubdivisionType; 136 } 137 138 139 int HierarchyManager::GetViewSpaceSubdivisionType() const 140 { 141 return mViewSpaceSubdivisionType; 142 } 143 144 127 145 void HierarchyManager::SetViewCellsManager(ViewCellsManager *vcm) 128 146 { … … 220 238 mObjectSpaceSubdivisionType = NO_OBJ_SUBDIV; 221 239 240 mSavedViewSpaceSubdivisionType = mViewSpaceSubdivisionType; 241 mViewSpaceSubdivisionType = NO_VIEWSPACE_SUBDIV; 242 222 243 // start with view space subdivison: prepare vsp tree for traversal 223 244 if (StartViewSpaceSubdivision()) … … 238 259 239 260 cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 261 240 262 mHierarchyStats.Stop(); 241 263 mVspTree->mVspStats.Stop(); 264 FinishObjectSpaceSubdivision(); 265 266 mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType; 267 mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType; 242 268 } 243 269 … … 247 273 AxisAlignedBox3 *forcedViewSpace) 248 274 { 275 cout << "starting view space hierarchy construction ... " << endl; 276 249 277 RayInfoContainer *viewSpaceRays = new RayInfoContainer(); 250 278 SubdivisionCandidate *vsc = … … 291 319 const ObjectContainer &objects) 292 320 { 321 cout << "starting osp tree construction ... " << endl; 322 293 323 RayInfoContainer *objectSpaceRays = new RayInfoContainer(); 294 295 cout << "starting osp tree construction ... " << endl;296 324 297 325 // start with one big kd cell - all objects can be seen from everywhere … … 342 370 343 371 372 int HierarchyManager::GetObjectSpaceSubdivisionDepth() const 373 { 374 int maxDepth = 0; 375 376 if (mObjectSpaceSubdivisionType == KD_BASED_OBJ_SUBDIV) 377 { 378 maxDepth = mOspTree->mOspStats.maxDepth; 379 } 380 else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV) 381 { 382 maxDepth = mBvHierarchy->mBvhStats.maxDepth; 383 } 384 385 return maxDepth; 386 } 387 388 344 389 bool HierarchyManager::StartObjectSpaceSubdivision() const 345 390 { 346 const bool ospDepthReached = 347 (mMinDepthForObjectSpaceSubdivion <= mVspTree->mVspStats.maxDepth); 348 349 return !ObjectSpaceSubdivisionConstructed() && 350 (mTQueue.Empty() || ((mConstructionType == INTERLEAVED) && ospDepthReached)); 391 // view space construction already started 392 if (ObjectSpaceSubdivisionConstructed()) 393 return false; 394 395 // start immediately with object space subdivision? 396 if (mStartWithObjectSpace) 397 return true; 398 399 // is the queue empty again? 400 if (ViewSpaceSubdivisionConstructed() && mTQueue.Empty()) 401 return true; 402 403 // has the depth for subdivision been reached? 404 return 405 ((mConstructionType == INTERLEAVED) && 406 (mMinDepthForObjectSpaceSubdivion <= mVspTree->mVspStats.maxDepth)); 351 407 } 352 408 … … 354 410 bool HierarchyManager::StartViewSpaceSubdivision() const 355 411 { 356 const bool vspDepthReached = 357 (mMinDepthForObjectSpaceSubdivion <= mVspTree->mVspStats.maxDepth); 358 359 return !ViewSpaceSubdivisionConstructed() && 360 (mTQueue.Empty() || ((mConstructionType == INTERLEAVED) && vspDepthReached)); 412 // view space construction already started 413 if (ViewSpaceSubdivisionConstructed()) 414 return false; 415 416 // start immediately with view space subdivision? 417 if (!mStartWithObjectSpace) 418 return true; 419 420 // is the queue empty again? 421 if (ObjectSpaceSubdivisionConstructed() && mTQueue.Empty()) 422 return true; 423 424 // has the depth for subdivision been reached? 425 return 426 ((mConstructionType == INTERLEAVED) && 427 (mMinDepthForViewSpaceSubdivion <= GetObjectSpaceSubdivisionDepth())); 361 428 } 362 429 … … 384 451 } 385 452 453 /////////////////////////// 386 454 //-- subdivide leaf node 387 455 if (ApplySubdivisionCandidate(mCurrentCandidate)) … … 420 488 421 489 cout << "starting view space subdivision at depth " 422 << mVspTree->mVspStats.maxDepth<< " ("423 << mMinDepthFor ObjectSpaceSubdivion << ") " << endl;490 << GetObjectSpaceSubdivisionDepth() << " (" 491 << mMinDepthForViewSpaceSubdivion << ") " << endl; 424 492 425 493 PrepareViewSpaceSubdivision(sampleRays, objects, forcedViewSpace); … … 432 500 DEL_PTR(mCurrentCandidate); 433 501 } 434 435 mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;436 502 } 437 503 … … 632 698 { 633 699 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 634 return mBvHierarchy->AddLeafToPvs(leaf, vc, pdf, contribution); 700 BvhIntersectable *bvhObj = mBvHierarchy->GetOrCreateBvhIntersectable(leaf); 701 702 return vc->AddPvsSample(bvhObj, pdf, contribution); 635 703 } 636 704 default: … … 647 715 stream << mVspTree->GetStatistics() << endl; 648 716 stream << "\nobject space:" << endl << endl; 717 649 718 switch (mObjectSpaceSubdivisionType) 650 719 { … … 726 795 727 796 728 } 797 void HierarchyManager::FinishObjectSpaceSubdivision() const 798 { 799 switch (mObjectSpaceSubdivisionType) 800 { 801 case KD_BASED_OBJ_SUBDIV: 802 { 803 mOspTree->mOspStats.Stop(); 804 break; 805 } 806 case BV_BASED_OBJ_SUBDIV: 807 { 808 mBvHierarchy->mBvhStats.Stop(); 809 break; 810 } 811 default: 812 break; 813 } 814 } 815 816 } -
GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
r1329 r1370 166 166 }; 167 167 168 enum 169 { 170 NO_VIEWSPACE_SUBDIV, 171 KD_BASED_VIEWSPACE_SUBDIV 172 }; 173 168 174 /** The type of object space subdivison 169 175 */ 170 int GetObjectSpaceSubdivisionType() const 171 { 172 return mObjectSpaceSubdivisionType; 173 } 174 176 int GetObjectSpaceSubdivisionType() const; 177 /** The type of view space space subdivison 178 */ 179 int GetViewSpaceSubdivisionType() const; 180 /** Sets a pointer to the view cells manager. 181 */ 175 182 void SetViewCellsManager(ViewCellsManager *vcm); 176 183 /** Sets a pointer to the view cells tree. 184 */ 177 185 void SetViewCellsTree(ViewCellsTree *vcTree); 178 186 /** Exports the object hierarchy to disc. 187 */ 179 188 void ExportObjectSpaceHierarchy(OUT_STREAM &stream); 180 189 /** Adds a sample to the pvs of the specified view cell. 190 */ 181 191 bool AddSampleToPvs( 182 192 Intersectable *obj, … … 264 274 void ResetQueue(); 265 275 276 void FinishObjectSpaceSubdivision() const; 277 278 int GetObjectSpaceSubdivisionDepth() const; 266 279 267 280 protected: … … 299 312 300 313 int mMinDepthForObjectSpaceSubdivion; 314 int mMinDepthForViewSpaceSubdivion; 301 315 302 316 int mTermMaxLeaves; … … 304 318 305 319 bool mRepairQueue; 320 321 bool mStartWithObjectSpace; 306 322 }; 307 323 -
GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
r1315 r1370 527 527 { 528 528 const bool localTerminationCriteriaMet = (0 529 //|| ((int)data.mRays->size() <= mTermMinRays)530 //|| (data.mPvs <= mTermMinPvs)531 //|| (data.mProbability <= mTermMinProbability)532 //|| (data.GetAvgRayContribution() > mTermMaxRayContribution)533 //|| (data.mDepth >= mTermMaxDepth)529 || ((int)data.mRays->size() <= mTermMinRays) 530 || (data.mPvs <= mTermMinPvs) 531 || (data.mProbability <= mTermMinProbability) 532 || (data.GetAvgRayContribution() > mTermMaxRayContribution) 533 || (data.mDepth >= mTermMaxDepth) 534 534 ); 535 535 … … 1335 1335 int bestAxis = -1; 1336 1336 1337 // if we use some kind of specialised fixed axis1337 // do we use some kind of specialised "fixed" axis? 1338 1338 const bool useSpecialAxis = 1339 1339 mOnlyDrivingAxis || mCirculatingAxis; … … 1369 1369 else 1370 1370 { 1371 //-- split plane position is spatial median 1371 //-- split plane position is spatial median 1372 1372 nPosition[axis] = (box.Min()[axis] + box.Max()[axis]) * 0.5f; 1373 1373 nCostRatio[axis] = EvalLocalSplitCost(tData, … … 1390 1390 } 1391 1391 1392 //////////////////////////////// 1392 1393 //-- assign values of best split 1394 1393 1395 plane.mAxis = bestAxis; 1394 plane.mPosition = nPosition[bestAxis]; // split plane position 1396 // best split plane position 1397 plane.mPosition = nPosition[bestAxis]; 1395 1398 1396 1399 pFront = nProbFront[bestAxis];
Note: See TracChangeset
for help on using the changeset viewer.