- Timestamp:
- 09/13/06 17:15:26 (18 years ago)
- Location:
- GTP/trunk/Lib/Vis/Preprocessing/src
- Files:
-
- 3 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 { -
GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
r1345 r1357 35 35 class VspTree; 36 36 class ViewCellsContainer; 37 //class BvhSubdivisionCandidate;38 37 39 38 … … 149 148 /** The bounding box specifies the node extent. 150 149 */ 150 inline 151 151 AxisAlignedBox3 GetBoundingBox() const 152 152 { return mBoundingBox; } 153 153 154 154 155 inline 155 156 void SetBoundingBox(const AxisAlignedBox3 &boundingBox) 156 157 { mBoundingBox = boundingBox; } … … 298 299 mMaxCostMisses(0), 299 300 mAxis(0) 300 //mObjectsStart(0),301 //mObjectsEnd(0)302 {}301 { 302 mSortedObjects[0] = mSortedObjects[1] = mSortedObjects[2] = NULL; 303 } 303 304 304 305 BvhTraversalData(BvhLeaf *node, … … 312 313 mMaxCostMisses(0), 313 314 mAxis(0) 314 //mObjectsStart(0) 315 //mObjectsEnd(0) 316 {} 317 318 /// deletes contents and sets them to NULL 315 { 316 mSortedObjects[0] = mSortedObjects[1] = mSortedObjects[2] = NULL; 317 } 318 319 /** Deletes contents and sets them to NULL. 320 */ 319 321 void Clear() 320 322 { 321 323 DEL_PTR(mNode); 324 /*DEL_PTR(mSortedObjects[0]); 325 DEL_PTR(mSortedObjects[1]); 326 DEL_PTR(mSortedObjects[2]);*/ 322 327 } 323 328 … … 334 339 /// current axis 335 340 int mAxis; 336 /// start of objects 337 SortableEntryContainer::const_iterator mObjectsStart; 338 /// end of objects 339 SortableEntryContainer::const_iterator mObjectsEnd; 341 /// the sorted objects for the three dimensions 342 ObjectContainer *mSortedObjects[3]; 340 343 }; 341 344 342 /** Candidate for a view space split. 345 346 /** Candidate for a object space split. 343 347 */ 344 348 class BvhSubdivisionCandidate: public SubdivisionCandidate … … 618 622 619 623 620 /** Sortssplit candidates for cost heuristics using axis aligned splits.624 /** Prepare split candidates for cost heuristics using axis aligned splits. 621 625 @param node the current node 622 626 @param axis the current split axis 623 627 */ 624 static void SortSubdivisionCandidates( 625 const ObjectContainer &objects, 626 vector<SortableEntry> **subdivisionCandidates, 628 void PrepareLocalSubdivisionCandidates( 629 const BvhTraversalData &tData, 627 630 const int axis); 628 631 629 /** Computes best cost for axis aligned planes. 632 static void CreateLocalSubdivisionCandidates( 633 const ObjectContainer &objects, 634 SortableEntryContainer **subdivisionCandidates, 635 const bool sort, 636 const int axis); 637 638 /** Computes object partition with the best cost according to the heurisics. 639 @param tData the traversal data 640 @param axis the split axis 641 @param objectsFront the objects in the front child bv 642 @param objectsBack the objects in the back child bv 643 @param backObjectsStart the iterator marking the position where the back objects begin 644 645 @returns relative cost (relative to parent cost) 630 646 */ 631 647 float EvalLocalCostHeuristics( … … 633 649 const int axis, 634 650 ObjectContainer &objectsFront, 635 ObjectContainer &objects FBack);651 ObjectContainer &objectsBack); 636 652 637 653 /** Evaluates the contribution to the front and back volume … … 708 724 float EvalViewCellsVolume(const ObjectContainer &objects) const; 709 725 726 void CreateInitialSortedObjectList(BvhTraversalData &tData); 727 728 void AssignSortedObjects( 729 const BvhSubdivisionCandidate &sc, 730 BvhTraversalData &frontData, 731 BvhTraversalData &backData); 732 710 733 711 734 protected: … … 735 758 736 759 737 //-- local termination 760 //////////////////////////////// 761 //-- local termination criteria 738 762 739 763 /// maximal possible depth … … 751 775 752 776 753 //-- global criteria 777 //////////////////////////////////// 778 //-- global termination criteria 754 779 755 780 float mTermMinGlobalCostRatio; … … 765 790 766 791 792 //////////////////////////////////////// 767 793 //-- split heuristics based parameters 768 794 … … 772 798 /// if only driving axis should be used for split 773 799 bool mOnlyDrivingAxis; 774 775 800 /// current time stamp (used for keeping split history) 776 801 int mTimeStamp; 777 802 // if rays should be stored in leaves 778 803 bool mStoreRays; 779 780 /// epsilon for geometric comparisons 781 float mEpsilon; 782 783 /// subdivision stats output file 804 // subdivision stats output file 784 805 ofstream mSubdivisionStats; 785 806 /// keeps track of cost during subdivision … … 789 810 /// number of currenly generated view cells 790 811 int mCreatedLeaves; 791 792 812 /// represents min and max band for sweep 793 813 float mSplitBorder; 794 795 814 /// weight between render cost decrease and node render cost 796 815 float mRenderCostDecreaseWeight; 797 798 816 /// stores the kd node intersectables used for pvs 799 817 BvhIntersectableMap mBvhIntersectables; 800 818 819 bool mUseGlobalSorting; 801 820 }; 802 821 -
GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
r1314 r1357 256 256 257 257 protected: 258 258 /// bounding box for this interior node: should we really store this? 259 259 AxisAlignedBox3 mBoundingBox; 260 260
Note: See TracChangeset
for help on using the changeset viewer.