Changeset 1357 for GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
- Timestamp:
- 09/13/06 17:15:26 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
r1345 r1357 24 24 #define USE_FIXEDPOINT_T 0 25 25 26 static float debugVol = 0; 27 28 int BvhNode::sMailId = 10000;//2147483647; 26 int BvhNode::sMailId = 10000; //2147483647; 29 27 int BvhNode::sReservedMailboxes = 1; 30 28 … … 32 30 33 31 32 /// sorting operator 34 33 inline static bool ilt(Intersectable *obj1, Intersectable *obj2) 35 34 { … … 171 170 { 172 171 ReadEnvironment(); 173 mSubdivisionCandidates = new vector<SortableEntry>;172 mSubdivisionCandidates = new SortableEntryContainer; 174 173 } 175 174 … … 228 227 "BvHierarchy.Construction.renderCostDecreaseWeight", mRenderCostDecreaseWeight); 229 228 230 229 Environment::GetSingleton()->GetBoolValue("BvHierarchy.useGlobalSort", mUseGlobalSorting); 230 231 232 /////////////////// 231 233 //-- debug output 232 233 234 Debug << "******* Bvh hierarchy options ******** " << endl; 234 235 Debug << "max depth: " << mTermMaxDepth << endl; … … 245 246 Debug << "use cost heuristics: " << mUseCostHeuristics << endl; 246 247 Debug << "subdivision stats log: " << subdivisionStatsLog << endl; 247 248 248 Debug << "split borders: " << mSplitBorder << endl; 249 249 Debug << "render cost decrease weight: " << mRenderCostDecreaseWeight << endl; 250 Debug << "use global sort: " << mUseGlobalSorting << endl; 250 251 Debug << endl; 251 252 } 252 253 253 254 254 void AssociateObjectsWithLeaf(BvhLeaf *leaf)255 static void AssociateObjectsWithLeaf(BvhLeaf *leaf) 255 256 { 256 257 ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end(); … … 274 275 275 276 276 //-- the front and back traversal data is filled with the new values 277 /////////////////////////////////////////////////////////////////// 278 //-- fill front and back traversal data with the new values 277 279 278 280 frontData.mDepth = backData.mDepth = tData.mDepth + 1; … … 328 330 frontData.mMaxCostMisses = sc.mMaxCostMisses; 329 331 backData.mMaxCostMisses = sc.mMaxCostMisses; 330 331 // assign positions of the iterators 332 #if 0 333 frontData.mObjectsStart = sc.mFrontObjectsStart; 334 frontData.mObjectsEnd = sc.mFrontObjectsEnd; 335 336 backData.mObjectsStart = sc.mBackObjectsStart; 337 backData.mObjectsEnd = sc.mBackObjectsEnd; 338 #endif 332 333 // assign the objects in sorted order 334 if (mUseGlobalSorting) 335 { 336 AssignSortedObjects(sc, frontData, backData); 337 } 338 339 339 // return the new interior node 340 340 return node; … … 388 388 tBackData.mNode->SetSubdivisionCandidate(backCandidate); 389 389 390 Debug << "leaf: " << tFrontData.mNode << " setting f candidate: " << tFrontData.mNode->GetSubdivisionCandidate() << " type: " << tFrontData.mNode->GetSubdivisionCandidate()->Type() << endl; 391 Debug << "leaf: " << tBackData.mNode << " setting b candidate: " << tBackData.mNode->GetSubdivisionCandidate() << " type: " << tBackData.mNode->GetSubdivisionCandidate()->Type() << endl; 390 Debug << "leaf: " << tFrontData.mNode << " setting f candidate: " 391 << tFrontData.mNode->GetSubdivisionCandidate() << " type: " 392 << tFrontData.mNode->GetSubdivisionCandidate()->Type() << endl; 393 394 Debug << "leaf: " << tBackData.mNode << " setting b candidate: " 395 << tBackData.mNode->GetSubdivisionCandidate() << " type: " 396 << tBackData.mNode->GetSubdivisionCandidate()->Type() << endl; 392 397 393 398 tQueue.Push(frontCandidate); … … 443 448 const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 444 449 const float oldProp = EvalViewCellsVolume(leaf->mObjects); 445 //const float oldProp2 = splitCandidate.mParentData.mProbability; Debug << "here8 " << (oldProp - oldProp2) / viewSpaceVol << " " << oldProp / viewSpaceVol << " " << oldProp2 / viewSpaceVol << endl;446 450 447 451 const float oldRenderCost = oldProp * (float)leaf->mObjects.size() / viewSpaceVol; … … 568 572 ObjectContainer &objectsBack) 569 573 { 570 SortSubdivisionCandidates(tData.mNode->mObjects, &mSubdivisionCandidates, axis);571 572 vector<SortableEntry>::const_iterator cit, cit_end = mSubdivisionCandidates->end();574 PrepareLocalSubdivisionCandidates(tData, axis); 575 576 SortableEntryContainer::const_iterator cit, cit_end = mSubdivisionCandidates->end(); 573 577 574 578 int i = 0; … … 603 607 ObjectContainer &objectsBack) 604 608 { 605 SortSubdivisionCandidates(tData.mNode->mObjects, &mSubdivisionCandidates, axis);609 PrepareLocalSubdivisionCandidates(tData, axis); 606 610 607 611 // go through the lists, count the number of objects left and right … … 624 628 float maxBorder = minBox; 625 629 626 vector<SortableEntry>::const_iterator currentPos =630 SortableEntryContainer::const_iterator currentPos = 627 631 mSubdivisionCandidates->begin(); 628 632 629 vector<SortableEntry>::reverse_iterator rcit =633 SortableEntryContainer::reverse_iterator rcit = 630 634 mSubdivisionCandidates->rbegin(), rcit_end = mSubdivisionCandidates->rend(); 631 635 … … 645 649 vector<float>::const_iterator bit = bordersRight.begin(); 646 650 647 vector<SortableEntry>::const_iterator cit, cit_end = mSubdivisionCandidates->end();651 SortableEntryContainer::const_iterator cit, cit_end = mSubdivisionCandidates->end(); 648 652 for (cit = mSubdivisionCandidates->begin(); cit != cit_end; ++ cit, ++ bit) 649 653 { … … 750 754 ObjectContainer &objectsBack) 751 755 { 756 //////////////////////////////////////////////////////////////// 757 // go through the lists, count the number of objects left and right 758 // and evaluate the cost funcion 759 752 760 // prepare the heuristics by setting mailboxes and counters. 753 761 const float totalVol = PrepareHeuristics(tData, axis); 754 755 // go through the lists, count the number of objects left and right 756 // and evaluate the cost funcion 757 762 758 763 // local helper variables 759 764 float volLeft = 0; 760 765 float volRight = totalVol; 761 762 766 int nObjectsLeft = 0; 763 764 767 const int nTotalObjects = (int)tData.mNode->mObjects.size(); 765 768 const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 766 769 767 vector<SortableEntry>::const_iterator currentPos = 768 mSubdivisionCandidates->begin(); 770 SortableEntryContainer::const_iterator backObjectsStart = mSubdivisionCandidates->begin(); 769 771 770 772 ///////////////////////////////// 771 // the parameters for the current optimum773 //-- the parameters for the current optimum 772 774 773 775 float volBack = volLeft; … … 782 784 const bool printStats = 783 785 PrepareOutput(axis, mBvhStats.Leaves(), sumStats, vollStats, volrStats); 784 785 786 #endif 786 787 787 ///////////////////////////// 788 // the sweep heuristics 789 788 /////////////////////////////////////////////////// 789 //-- the sweep heuristics 790 790 //-- traverse through events and find best split plane 791 791 792 vector<SortableEntry>::const_iterator cit,cit_end = mSubdivisionCandidates->end();792 SortableEntryContainer::const_iterator cit, cit_end = cit_end = mSubdivisionCandidates->end(); 793 793 794 794 for (cit = mSubdivisionCandidates->begin(); cit != cit_end; ++ cit) … … 802 802 803 803 ++ nObjectsLeft; 804 805 804 const int nObjectsRight = nTotalObjects - nObjectsLeft; 806 805 … … 811 810 #ifdef _DEBUG 812 811 if (printStats) 812 { 813 813 PrintHeuristics(nObjectsRight, sum, volLeft, volRight, viewSpaceVol, 814 814 sumStats, vollStats, volrStats); 815 } 815 816 #endif 816 817 … … 823 824 824 825 // objects belongs to left side now 825 for (; currentPos != (cit + 1); ++ currentPos);826 for (; backObjectsStart != (cit + 1); ++ backObjectsStart); 826 827 } 827 828 } 828 829 830 //////////////////////////////////////////// 829 831 //-- assign object to front and back volume 830 832 831 833 // belongs to back bv 832 for (cit = mSubdivisionCandidates->begin(); cit != currentPos; ++ cit) 834 for (cit = mSubdivisionCandidates->begin(); cit != backObjectsStart; ++ cit) 835 { 833 836 objectsBack.push_back((*cit).mObject); 834 837 } 835 838 // belongs to front bv 836 for (cit = currentPos; cit != cit_end; ++ cit) 839 for (cit = backObjectsStart; cit != cit_end; ++ cit) 840 { 837 841 objectsFront.push_back((*cit).mObject); 838 842 } 843 844 // render cost of the old parent 839 845 const float oldRenderCost = (float)nTotalObjects * totalVol + Limits::Small; 840 846 // the relative cost ratio … … 853 859 854 860 855 void BvHierarchy::SortSubdivisionCandidates(const ObjectContainer &objects, 856 vector<SortableEntry> **subdivisionCandidates, 857 const int axis) 861 void BvHierarchy::PrepareLocalSubdivisionCandidates(const BvhTraversalData &tData, 862 const int axis) 863 { 864 //-- insert object queries 865 ObjectContainer *objects; 866 867 if (!mUseGlobalSorting) 868 objects = &tData.mNode->mObjects; 869 else 870 objects = tData.mSortedObjects[axis]; 871 872 CreateLocalSubdivisionCandidates(*objects, &mSubdivisionCandidates, mUseGlobalSorting, axis); 873 } 874 875 876 void BvHierarchy::CreateLocalSubdivisionCandidates(const ObjectContainer &objects, 877 SortableEntryContainer **subdivisionCandidates, 878 const bool sort, 879 const int axis) 858 880 { 859 881 (*subdivisionCandidates)->clear(); 860 882 861 // compute requested size 883 // compute requested size and look if subdivision candidate has to be recomputed 862 884 const int requestedSize = (int)objects.size() * 2; 863 885 … … 866 888 requestedSize < (int)((*subdivisionCandidates)->capacity() / 10) ) 867 889 { 868 delete *subdivisionCandidates;869 *subdivisionCandidates = new vector<SortableEntry>;890 delete (*subdivisionCandidates); 891 (*subdivisionCandidates) = new SortableEntryContainer; 870 892 } 871 893 872 894 (*subdivisionCandidates)->reserve(requestedSize); 873 895 874 //-- insert object queries875 //-- These queries can induce a change in pvs size.876 //-- Note that they cannot induce a change in view cell volume, as877 //-- there is no ray associated with these events!!878 879 896 ObjectContainer::const_iterator oit, oit_end = objects.end(); 880 897 881 898 for (oit = objects.begin(); oit < oit_end; ++ oit) 882 899 { 883 Intersectable *obj = *oit;884 885 900 Intersectable *object = *oit; 886 901 const AxisAlignedBox3 &box = object->GetBox(); … … 890 905 } 891 906 892 stable_sort((*subdivisionCandidates)->begin(), (*subdivisionCandidates)->end()); 907 if (sort) 908 { 909 stable_sort((*subdivisionCandidates)->begin(), (*subdivisionCandidates)->end()); 910 } 893 911 } 894 912 … … 905 923 float vol = 0; 906 924 907 908 SortSubdivisionCandidates(tData.mNode->mObjects, &mSubdivisionCandidates, axis);909 925 // sort so we can use a sweep from right to left 926 PrepareLocalSubdivisionCandidates(tData, axis); 927 910 928 // collect and mark the view cells as belonging to front pvs 911 929 ViewCellContainer viewCells; … … 939 957 CollectViewCells(obj, viewCells, useMailboxing); 940 958 941 // /classify view cells and compute volume contri accordingly942 // /possible view cell classifications:943 // /view cell mailed => view cell can be seen from left child node944 // /view cell counter > 0 view cell can be seen from right child node945 // /combined: view cell volume belongs to both nodes959 // classify view cells and compute volume contri accordingly 960 // possible view cell classifications: 961 // view cell mailed => view cell can be seen from left child node 962 // view cell counter > 0 view cell can be seen from right child node 963 // combined: view cell volume belongs to both nodes 946 964 ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 947 965 … … 956 974 { 957 975 viewCell->Mail(); 958 959 976 // we now see view cell from both nodes 960 977 // => add volume to left node … … 964 981 // last reference into the right node 965 982 if (-- viewCell->mCounter == 0) 966 { 983 { 967 984 // view cell was previously seen from both nodes => 968 985 // remove volume from right node … … 1005 1022 } 1006 1023 1007 // -- evaluate split cost for all three axis 1024 //////////////////////////////////////////// 1025 //-- evaluate split cost for all three axis 1008 1026 1009 1027 for (int axis = 0; axis < 3; ++ axis) … … 1042 1060 } 1043 1061 1062 ///////////////////////////////////// 1044 1063 //-- assign values 1045 1064 … … 1129 1148 //-- pvs rendering heuristics 1130 1149 const float newRenderCost = nObjectsFront * pFront + nObjectsBack * pBack; 1131 /* 1150 1151 #ifdef _DEBUG 1132 1152 const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 1133 1153 Debug << "\nbvh render cost\n" 1134 1154 << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << endl 1135 1155 << "new rc: " << newRenderCost / viewSpaceVol << endl;*/ 1156 #endif 1136 1157 1137 1158 return newRenderCost; … … 1448 1469 } 1449 1470 1471 1450 1472 void BvHierarchy::CreateRoot(const ObjectContainer &objects) 1451 1473 { … … 1454 1476 BvhLeaf *bvhleaf = new BvhLeaf(box, NULL, (int)objects.size()); 1455 1477 bvhleaf->mObjects = objects; 1456 1457 1478 mRoot = bvhleaf; 1458 1479 … … 1465 1486 const ObjectContainer &objects) 1466 1487 { 1488 /////////////////////////////////////////////////////////////// 1489 // note matt: we assume that we have objects sorted by their id 1490 1467 1491 mBvhStats.Reset(); 1468 1492 mBvhStats.Start(); 1469 1493 mBvhStats.nodes = 1; 1470 1471 for (int i = 0; i < 3; ++ i)1472 {1473 mGlobalSubdivisionCandidates[i] = new vector<SortableEntry>();1474 SortSubdivisionCandidates(objects, &mGlobalSubdivisionCandidates[i], i);1475 }1476 1477 // note matt: we assume that we have objects sorted by their id1478 1494 1479 1495 // store pointer to this tree … … 1502 1518 BvhTraversalData oData(bvhleaf, 0, mBoundingBox, prop); 1503 1519 1520 // create sorted object lists for the first data 1521 if (mUseGlobalSorting) 1522 { 1523 CreateInitialSortedObjectList(oData); 1524 } 1525 1526 1527 //////////////////////////////////////////////////// 1504 1528 //-- add first candidate for object space partition 1529 1505 1530 BvhSubdivisionCandidate *oSubdivisionCandidate = 1506 1531 new BvhSubdivisionCandidate(oData); … … 1530 1555 1531 1556 1557 void BvHierarchy::CreateInitialSortedObjectList(BvhTraversalData &tData) 1558 { 1559 SortableEntryContainer *sortedObjects = new SortableEntryContainer(); 1560 1561 // we sort the objects as a preprocess so they don't have 1562 // to be sorted for each split 1563 for (int i = 0; i < 3; ++ i) 1564 { 1565 CreateLocalSubdivisionCandidates(tData.mNode->mObjects, &sortedObjects, true, i); 1566 1567 tData.mSortedObjects[i] = new ObjectContainer(); 1568 tData.mSortedObjects[i]->reserve((int)sortedObjects->size()); 1569 1570 SortableEntryContainer::const_iterator oit, oit_end = sortedObjects->end(); 1571 for (oit = sortedObjects->begin(); oit != oit_end; ++ oit) 1572 { 1573 tData.mSortedObjects[i]->push_back((*oit).mObject); 1574 } 1575 } 1576 1577 delete sortedObjects; 1578 } 1579 1580 1581 void BvHierarchy::AssignSortedObjects(const BvhSubdivisionCandidate &sc, 1582 BvhTraversalData &frontData, 1583 BvhTraversalData &backData) 1584 { 1585 Intersectable::NewMail(); 1586 1587 // we sorted the objects as a preprocess so they don't have 1588 // to be sorted for each split 1589 ObjectContainer::const_iterator fit, fit_end = sc.mFrontObjects.end(); 1590 1591 for (fit = sc.mFrontObjects.begin(); fit != fit_end; ++ fit) 1592 { 1593 (*fit)->Mail(); 1594 } 1595 1596 for (int i = 0; i < 3; ++ i) 1597 { 1598 frontData.mSortedObjects[i]->reserve((int)sc.mFrontObjects.size()); 1599 backData.mSortedObjects[i]->reserve((int)sc.mFrontObjects.size()); 1600 1601 ObjectContainer::const_iterator oit, oit_end = sc.mParentData.mNode->mObjects.end(); 1602 1603 for (oit = sc.mParentData.mNode->mObjects.begin(); oit != oit_end; ++ oit) 1604 { 1605 if ((*oit)->Mailed()) 1606 { 1607 frontData.mSortedObjects[i]->push_back(*oit); 1608 } 1609 else 1610 { 1611 backData.mSortedObjects[i]->push_back(*oit); 1612 } 1613 } 1614 } 1615 } 1616 1617 1532 1618 void BvhStatistics::Print(ostream &app) const 1533 1619 {
Note: See TracChangeset
for help on using the changeset viewer.