Changeset 302 for trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
- Timestamp:
- 09/29/05 18:42:04 (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r301 r302 19 19 int BspTree::sConstructionMethod = VIEW_CELLS; 20 20 int BspTree::sTermMaxPolysForAxisAligned = 50; 21 22 float BspTree::sCt_div_ci = 1.0f; 23 float BspTree::sSplitBorder = 1.0f; 24 float BspTree::sMaxCostRatio = 0.9; 21 25 22 26 //-- factors for bsp tree split plane heuristics … … 581 585 if ((tData.mPolygons->size() <= sTermMaxPolygons) || (tData.mDepth >= sTermMaxDepth)) 582 586 { 583 #ifdef _DEBUG587 //#ifdef _DEBUG 584 588 Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " << (int)tData.mPolygons->size() << endl; 585 #endif589 //#endif 586 590 587 591 EvaluateLeafStats(tData); … … 691 695 692 696 // add the new nodes to the tree + select subdivision plane 693 BspInterior *interior = new BspInterior(SelectPlane( *polys));697 BspInterior *interior = new BspInterior(SelectPlane(leaf, *polys)); 694 698 695 699 #ifdef _DEBUG … … 719 723 } 720 724 721 Plane3 BspTree::SelectPlane(const PolygonContainer &polys) const 725 void BspTree::SortSplitCandidates(const PolygonContainer &polys, 726 const int axis, 727 vector<SortableEntry> &splitCandidates) const 728 { 729 splitCandidates.clear(); 730 731 int requestedSize = 2 * (int)polys.size(); 732 // creates a sorted split candidates array 733 splitCandidates.reserve(requestedSize); 734 735 PolygonContainer::const_iterator it, it_end = polys.end(); 736 737 AxisAlignedBox3 box; 738 739 // insert all queries 740 for(it = polys.begin(); it != it_end; ++ it) 741 { 742 box.Initialize(); 743 box.Include(*(*it)); 744 745 splitCandidates.push_back(SortableEntry(SortableEntry::POLY_MIN, box.Min(axis), *it)); 746 splitCandidates.push_back(SortableEntry(SortableEntry::POLY_MAX, box.Max(axis), *it)); 747 } 748 749 stable_sort(splitCandidates.begin(), splitCandidates.end()); 750 } 751 752 753 float BspTree::BestCostRatio(const PolygonContainer &polys, 754 const AxisAlignedBox3 &box, 755 const int axis, 756 float &position, 757 int &objectsBack, 758 int &objectsFront) const 759 { 760 vector<SortableEntry> splitCandidates; 761 762 SortSplitCandidates(polys, axis, splitCandidates); 763 764 // go through the lists, count the number of objects left and right 765 // and evaluate the following cost funcion: 766 // C = ct_div_ci + (ol + or)/queries 767 768 int objectsLeft = 0, objectsRight = (int)polys.size(); 769 770 float minBox = box.Min(axis); 771 float maxBox = box.Max(axis); 772 float boxArea = box.SurfaceArea(); 773 774 float minBand = minBox + sSplitBorder * (maxBox - minBox); 775 float maxBand = minBox + (1.0f - sSplitBorder) * (maxBox - minBox); 776 777 float minSum = 1e20f; 778 vector<SortableEntry>::const_iterator ci, ci_end = splitCandidates.end(); 779 780 for(ci = splitCandidates.begin(); ci != ci_end; ++ ci) 781 { 782 switch ((*ci).type) 783 { 784 case SortableEntry::POLY_MIN: 785 ++ objectsLeft; 786 break; 787 case SortableEntry::POLY_MAX: 788 -- objectsRight; 789 break; 790 default: 791 break; 792 } 793 794 if ((*ci).value > minBand && (*ci).value < maxBand) 795 { 796 AxisAlignedBox3 lbox = box; 797 AxisAlignedBox3 rbox = box; 798 lbox.SetMax(axis, (*ci).value); 799 rbox.SetMin(axis, (*ci).value); 800 801 float sum = objectsLeft * lbox.SurfaceArea() + 802 objectsRight * rbox.SurfaceArea(); 803 804 if (sum < minSum) 805 { 806 minSum = sum; 807 position = (*ci).value; 808 809 objectsBack = objectsLeft; 810 objectsFront = objectsRight; 811 } 812 } 813 } 814 815 float oldCost = (float)polys.size(); 816 float newCost = sCt_div_ci + minSum / boxArea; 817 float ratio = newCost / oldCost; 818 819 820 #if 0 821 Debug << "====================" << endl; 822 Debug << "costRatio=" << ratio << " pos=" << position<<" t=" << (position - minBox)/(maxBox - minBox) 823 << "\t o=(" << objectsBack << "," << objectsFront << ")" << endl; 824 #endif 825 return ratio; 826 } 827 828 Plane3 BspTree::SelectPlane(BspLeaf *leaf, const PolygonContainer &polys) const 722 829 { 723 830 if (polys.size() == 0) … … 741 848 Vector3 position; 742 849 743 for (int i =0; i < 3; i++)850 for (int i = 0; i < 3; ++ i) 744 851 { 745 852 float p = 0; 746 float r = 0;/*BestCostRatio(leaf, 747 box, 748 i, 749 p, 750 objectsBack, 751 objectsFront);*/ 853 float r = BestCostRatio(polys, box, i, p, objectsBack, objectsFront); 854 752 855 if (r < costRatio) 753 856 { … … 758 861 } 759 862 760 //if (costRatio > mMaxCostRatio) axis = -1; 761 Vector3 norm(0,0,0); norm[axis] = 1.0f; 762 return Plane3(norm, position); 763 863 if (costRatio < sMaxCostRatio) 864 { 865 Vector3 norm(0,0,0); norm[axis] = 1.0f; 866 return Plane3(norm, position); 867 } 764 868 /*int axis = box.Size().DrivingAxis(); 765 869 Vector3 norm(0,0,0); norm[axis] = 1; 766 870 Vector3 pt = (box.Min()[axis] + box.Max()[axis]) * 0.5f;*/ 767 //Debug << "splitting axis aligned" << endl;871 768 872 //return Plane3(norm, pt); 769 873 } … … 775 879 } 776 880 777 /*if (sSplitPlaneStrategy & VERTICAL_AXIS)778 {779 const float dot_thres = 0.999;780 PolygonContainer::const_iterator it, it_end = polys->end();781 782 for (it = polys->begin(); it != it_end; ++ it)783 {784 if (DotProd((*it)->GetSupportingPlane().mNormal, mVerticalAxis) > dot_thres)785 return (*it)->GetSupportingPlane();786 }787 }*/788 789 881 // use heuristics to find appropriate plane 790 882 return SelectPlaneHeuristics(polys, sMaxCandidates); … … 932 1024 environment->GetIntValue("BspTree.maxCandidates", sMaxCandidates); 933 1025 environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy); 1026 1027 // need kdtree criteria for axis aligned split 1028 environment->GetFloatValue("MeshKdTree.Termination.ct_div_ci", sCt_div_ci); 1029 environment->GetFloatValue("MeshKdTree.splitBorder", sSplitBorder); 1030 environment->GetFloatValue("MeshKdTree.Termination.maxCostRatio", sMaxCostRatio); 934 1031 935 1032 Debug << "BSP max depth: " << sTermMaxDepth << endl;
Note: See TracChangeset
for help on using the changeset viewer.