Changeset 1370 for GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
- Timestamp:
- 09/14/06 18:55:38 (18 years ago)
- File:
-
- 1 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 }
Note: See TracChangeset
for help on using the changeset viewer.