- Timestamp:
- 09/26/05 02:00:42 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
r294 r297 65 65 66 66 BspTree { 67 splitPlaneStrategy 14 67 # next polygon = 1 68 # axis aligned = 2 69 # least splits = 4 70 # balanced polygons = 8 71 # balanced view cells = 16 72 # largest polygon area = 32 73 # vertical axis = 64 74 75 # least splits + balanced polygons 76 #splitPlaneStrategy 12 77 # axis aligned + vertical axis 78 #splitPlaneStrategy 66 79 # axis aligned + balanced view cells 80 #splitPlaneStrategy 18 81 # largest polygon area 82 #splitPlaneStrategy 32 83 splitPlaneStrategy 72 68 84 # constructionMethod rays 69 85 constructionMethod viewCells … … 72 88 maxViewCells 999999 73 89 Termination { 90 maxPolysForAxisAligned 50 74 91 maxPolygons 0 75 92 maxDepth 100 -
trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
r268 r297 1161 1161 "5"); 1162 1162 1163 RegisterOption("BspTree.Termination.maxPolysForAxisAligned", 1164 optInt, 1165 "-bsp_term_max_polygons=", 1166 "50"); 1167 1163 1168 RegisterOption("BspTree.Termination.maxDepth", 1164 1169 optInt, -
trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
r295 r297 124 124 bool onFrontSide = false; 125 125 bool onBackSide = false; 126 // threshold for coincident classification 127 const float dot_thres = 0.99f; 128 126 129 127 int count = 0; 130 128 // find possible line-plane intersections … … 145 143 // 3 vertices enough to decide coincident 146 144 else if (((++ count) >= 3) && !onFrontSide && !onBackSide) 147 { 148 // Decide if plane and surface normal are same 149 if (DotProd(plane.mNormal, GetSupportingPlane().mNormal) > dot_thres) 150 return COINCIDENT; // plane and polygon are coincident 151 else 152 return FRONT_SIDE; 153 } 145 return COINCIDENT; 154 146 } 155 147 … … 163 155 } 164 156 165 // Decide if plane and surface normal are same 166 if (DotProd(plane.mNormal, GetSupportingPlane().mNormal) > dot_thres) 167 return COINCIDENT; // plane and polygon are coincident 168 else 169 return FRONT_SIDE; 157 return COINCIDENT; // plane and polygon are coincident 170 158 } 171 159 -
trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
r265 r297 9 9 Preprocessor::Preprocessor(): 10 10 mKdTree(NULL), 11 mBspTree(NULL) 11 mBspTree(NULL), 12 mRootViewCell(NULL) 12 13 { 13 14 } … … 18 19 DEL_PTR(mBspTree); 19 20 DEL_PTR(mKdTree); 21 DEL_PTR(mRootViewCell); 20 22 } 21 23 … … 87 89 { 88 90 DEL_PTR(mBspTree); 89 mBspTree = new BspTree(); 91 DEL_PTR(mRootViewCell); 92 mRootViewCell = new ViewCell(); 93 mBspTree = new BspTree(mRootViewCell); 90 94 91 95 ObjectContainer objects; -
trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
r263 r297 105 105 /// BSP tree representing the viewcells 106 106 BspTree *mBspTree; 107 108 /// the root view cell of the bsp tree 109 ViewCell *mRootViewCell; 107 110 }; 108 111 -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r296 r297 18 18 int BspTree::sSplitPlaneStrategy = NEXT_POLYGON; 19 19 int BspTree::sConstructionMethod = VIEW_CELLS; 20 float BspTree::sLeastSplitsFactor = 1.0f 21 float BspTree::sBalancedTreeFactor = 2.0f; 22 float BspTree::sVerticalFactor = 50.0f // very important criterium for 2.5d scenes 20 int BspTree::sTermMaxPolysForAxisAligned = 50; 21 22 //-- factors for bsp tree split plane heuristics 23 float BspTree::sLeastSplitsFactor = 1.0f; 24 float BspTree::sBalancedPolysFactor = 2.0f; 25 float BspTree::sBalancedViewCellsFactor = 2.0f; 26 float BspTree::sVerticalSplitsFactor = 1.0f; // very important criterium for 2.5d scenes 23 27 24 28 … … 30 34 contribution for a minimum number splits in the tree. 31 35 */ 32 float BspTree::sBalanced TreeTable[] = {-1, 1, 0, 0};36 float BspTree::sBalancedPolysTable[] = {-1, 1, 0, 0}; 33 37 34 38 //int counter = 0; … … 187 191 188 192 ++ splits; // increase number of splits 189 // check if polygon still valid 193 194 // check if polygons still valid 190 195 if (front_piece->mVertices.size() >= 3) 191 196 frontPolys->push_back(front_piece); 192 197 else 193 198 DEL_PTR(front_piece); 194 // check if polygon still valid199 195 200 if (back_piece->mVertices.size() >= 3) 196 201 backPolys->push_back(back_piece); … … 248 253 /****************************************************************/ 249 254 250 BspTree::BspTree( ):255 BspTree::BspTree(ViewCell *viewCell): 251 256 mRoot(NULL), 252 mV erticalAxis(Vector3(0, 0, 1)),257 mViewCell(viewCell), 253 258 //mStorePolys(true) 254 259 mStorePolys(false) … … 369 374 BspNode *firstNode = mRoot ? mRoot : new BspLeaf(); 370 375 371 tStack.push(BspTraversalData(firstNode, polys, 0, NULL));376 tStack.push(BspTraversalData(firstNode, polys, 0, mViewCell)); 372 377 373 378 while (!tStack.empty()) … … 398 403 mStorePolys); 399 404 400 // get view cell associated with the split polygon 401 ViewCell *viewCell = (coincident.size() > 0) ? 402 dynamic_cast<ViewCell *>(coincident.front()->mParent) : NULL; 405 // extract view cells associated with the split polygons 406 ViewCell *frontViewCell = mViewCell; 407 ViewCell *backViewCell = mViewCell; 408 409 if (!viewCells) 410 { 411 ExtractViewCells(&backViewCell, 412 &frontViewCell, 413 coincident, 414 interior->mPlane, 415 frontPolys->empty(), 416 backPolys->empty()); 417 } 418 419 // don't need coincident polygons anymore 403 420 interior->ProcessPolygons(&coincident, mStorePolys); 404 421 … … 407 424 408 425 // push the children on the stack 409 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, NULL));410 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, viewCell));426 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, frontViewCell)); 427 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, backViewCell)); 411 428 } 412 429 … … 533 550 std::stack<BspTraversalData> tStack; 534 551 535 BspTraversalData tData(new BspLeaf(), polys, 0, NULL);552 BspTraversalData tData(new BspLeaf(), polys, 0, mViewCell); 536 553 537 554 tStack.push(tData); … … 563 580 if ((tData.mPolygons->size() <= sTermMaxPolygons) || (tData.mDepth >= sTermMaxDepth)) 564 581 { 565 #ifdef _DEBUG582 //#ifdef _DEBUG 566 583 Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " << (int)tData.mPolygons->size() << endl; 567 #endif584 //#endif 568 585 569 586 EvaluateLeafStats(tData); … … 580 597 } 581 598 //-- add viewcell stored in split polygon 582 else if (tData.mViewCell)599 else 583 600 { 584 601 if (leaf->GetViewCell()) … … 586 603 587 604 //leaf->mViewCellIdx = counter; Debug << "insert view cell " << tData.mViewCell << endl; 588 leaf->SetViewCell( dynamic_cast<ViewCell *>(tData.mViewCell));605 leaf->SetViewCell(tData.mViewCell); 589 606 } 590 607 … … 608 625 &coincident); 609 626 610 // view cell associated with the first split polygon 611 ViewCell *viewCell = (coincident.size() > 0) ? 612 dynamic_cast<ViewCell *>(coincident.front()->mParent) : NULL; 627 //-- extract view cells from coincident polygons according to plane normal 628 ViewCell *frontViewCell = mViewCell; 629 ViewCell *backViewCell = mViewCell; 630 631 if (!viewCells) 632 { 633 ExtractViewCells(&backViewCell, 634 &frontViewCell, 635 coincident, 636 interior->mPlane, 637 frontPolys->empty(), 638 backPolys->empty()); 639 } 640 641 // don't need coincident polygons anymore 613 642 interior->ProcessPolygons(&coincident, mStorePolys); 614 643 615 644 // push the children on the stack 616 645 // split polygon is only needed in the back leaf 617 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, NULL));618 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, viewCell));646 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, frontViewCell)); 647 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, backViewCell)); 619 648 620 649 // cleanup … … 625 654 } 626 655 656 void BspTree::ExtractViewCells(ViewCell **backViewCell, 657 ViewCell **frontViewCell, 658 const PolygonContainer &coincident, 659 const Plane3 splitPlane, 660 const bool extractFront, 661 const bool extractBack) const 662 { 663 bool foundFront = !extractFront, foundBack = !extractBack; 664 665 PolygonContainer::const_iterator it, it_end = coincident.end(); 666 667 for (it = coincident.begin(); !(foundFront && foundBack) && 668 (it < coincident.end()); ++it) 669 { 670 if (DotProd((*it)->GetSupportingPlane().mNormal, splitPlane.mNormal > 0)) 671 { 672 *backViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 673 foundBack = true; 674 } 675 else 676 { 677 *frontViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 678 foundFront = true; 679 } 680 } 681 } 627 682 628 683 BspInterior *BspTree::SubdivideNode(BspLeaf *leaf, … … 671 726 } 672 727 673 // simple strategy: just take next polygon 674 if (sSplitPlaneStrategy & NEXT_POLYGON) 675 { 676 return polys.front()->GetSupportingPlane(); 677 } 678 679 if (sSplitPlaneStrategy & AXIS_ALIGNED) 728 if ((sSplitPlaneStrategy & AXIS_ALIGNED) && 729 ((int)polys.size() > sTermMaxPolysForAxisAligned)) 680 730 { 681 731 AxisAlignedBox3 box; 682 732 box.Initialize(); 683 733 734 // todo: area subdivision 684 735 Polygon3::IncludeInBox(polys, box); 685 736 … … 690 741 691 742 return Plane3(norm, pt); 743 } 744 745 // simplest strategy: just take next polygon 746 if (sSplitPlaneStrategy & NEXT_POLYGON) 747 { 748 return polys.front()->GetSupportingPlane(); 692 749 } 693 750 … … 729 786 } 730 787 } 731 //Debug << "Plane lowest cost: " << lowestCost << endl;788 Debug << "Plane lowest cost: " << lowestCost << endl; 732 789 733 790 return polys[bestPlaneIdx]->GetSupportingPlane(); … … 741 798 float BspTree::EvalSplitPlane(const PolygonContainer &polys, const Plane3 &candidatePlane) const 742 799 { 743 float sumBalanced = 0, sumLeastSplits = 0, verticalAxis = 0; 800 float sumBalancedPolys = 0; 801 float sumBalancedViewCells = 0; 802 float sumLeastSplits = 0; 803 float verticalAxis = 0; 744 804 745 805 if (sSplitPlaneStrategy & VERTICAL_AXIS) 746 806 { 747 Vector3 thinAxis(0,0,0); thinAxis[mBox.size().ThinAxis()] = 1.0f; 748 // want to minimize this dot product 749 verticalAxis = DotProd(candidatePlane.mNormal, thinAxis); 750 751 //drivingAxis = (candidatePlane.mNormal.DrivingAxis() == mBox.Size().DrivingAxis()) ? 99.0f : 0.0f; 752 } 753 if ((sSplitPlaneStrategy & BALANCED_TREE) || (sSplitPlaneStrategy & LEAST_SPLITS)) 807 Vector3 tinyAxis(0,0,0); tinyAxis[mBox.Size().TinyAxis()] = 1.0f; 808 // want to put a penalty on the dot product between the "tiny" vertical axis 809 // and the split plane axis 810 verticalAxis = fabs(DotProd(candidatePlane.mNormal, tinyAxis)) * (float)polys.size(); 811 } 812 //-- strategies where the effect of the split plane on the polygons is tested 813 if ((sSplitPlaneStrategy & BALANCED_POLYS) || 814 (sSplitPlaneStrategy & LEAST_SPLITS) || 815 (sSplitPlaneStrategy & LARGEST_POLY_AREA)) 754 816 { 755 817 PolygonContainer::const_iterator it, it_end = polys.end(); … … 759 821 int classification = (*it)->ClassifyPlane(candidatePlane); 760 822 761 if (sSplitPlaneStrategy & BALANCED_ TREE)762 sumBalanced += sBalancedTreeTable[classification];763 823 if (sSplitPlaneStrategy & BALANCED_POLYS) 824 sumBalancedPolys += sBalancedPolysTable[classification]; 825 764 826 if (sSplitPlaneStrategy & LEAST_SPLITS) 765 827 sumLeastSplits += sLeastSplitsTable[classification]; 766 828 } 767 829 } 830 831 if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) 832 { 833 // store view cells 834 ObjectContainer frontViewCells; 835 ObjectContainer backViewCells; 836 837 PolygonContainer::const_iterator it, it_end = polys.end(); 838 839 for (it = polys.begin(); it != it_end; ++ it) 840 { 841 int classification = (*it)->ClassifyPlane(candidatePlane); 842 Intersectable *viewCell = (*it)->mParent; 843 844 if (viewCell && (classification == Polygon3::FRONT_SIDE)) 845 frontViewCells.push_back(viewCell); 846 else if (viewCell && (classification == Polygon3::BACK_SIDE)) 847 backViewCells.push_back(viewCell); 848 } 849 850 // count number of unique view cells 851 sort(frontViewCells.begin(), frontViewCells.end()); 852 sort(backViewCells.begin(), backViewCells.end()); 853 854 ObjectContainer::const_iterator frontIt, frontIt_end = frontViewCells.end(); 855 856 Intersectable *intersect = NULL; 857 // increase counter for view cells in front of plane 858 for (frontIt = frontViewCells.begin(); frontIt != frontIt_end; ++frontIt) 859 { 860 if (*frontIt != intersect) 861 { 862 intersect = *frontIt; 863 sumBalancedViewCells += 1; 864 } 865 } 866 867 ObjectContainer::const_iterator backIt, backIt_end = backViewCells.end(); 868 intersect = NULL; 869 // decrease counter for view cells on back side of plane 870 for (backIt = backViewCells.begin(); backIt != backIt_end; ++backIt) 871 { 872 if (*backIt != intersect) 873 { 874 intersect = *backIt; 875 sumBalancedViewCells -= 1; 876 } 877 } 878 } 768 879 769 880 // return linear combination of the sums 770 return sBalancedFactor * fabs(sumBalanced) + sLeastSplitsFactor * sumLeastSplits + sVerticalFactor * dotProd; 881 return sBalancedPolysFactor * fabs(sumBalancedPolys) + 882 sBalancedViewCellsFactor * fabs(sumBalancedViewCells) + 883 sLeastSplitsFactor * sumLeastSplits + 884 sVerticalSplitsFactor * verticalAxis; 771 885 } 772 886 … … 775 889 environment->GetIntValue("BspTree.Termination.maxDepth", sTermMaxDepth); 776 890 environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons); 891 environment->GetIntValue("BspTree.Termination.maxPolysForAxisAligned", 892 sTermMaxPolysForAxisAligned); 777 893 environment->GetIntValue("BspTree.maxCandidates", sMaxCandidates); 778 894 environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy); 779 895 780 896 Debug << "BSP max depth: " << sTermMaxDepth << endl; 781 897 Debug << "BSP max polys: " << sTermMaxPolygons << endl; 782 898 Debug << "BSP max candidates: " << sMaxCandidates << endl; 899 900 Debug << "Split plane strategy: "; 901 if (sSplitPlaneStrategy & NEXT_POLYGON) 902 Debug << "next polygon "; 903 if (sSplitPlaneStrategy & AXIS_ALIGNED) 904 Debug << "axis aligned "; 905 if (sSplitPlaneStrategy & LEAST_SPLITS) 906 Debug << "least splits "; 907 if (sSplitPlaneStrategy & BALANCED_POLYS) 908 Debug << "balanced polygons "; 909 if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) 910 Debug << "balanced view cells "; 911 if (sSplitPlaneStrategy & LARGEST_POLY_AREA) 912 Debug << "largest polygon area "; 913 if (sSplitPlaneStrategy & VERTICAL_AXIS) 914 Debug << "vertical axis "; 915 916 Debug << endl; 783 917 784 918 //-- parse BSP tree construction method -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
r296 r297 162 162 class BspInterior : public BspNode 163 163 { 164 friend BspTree; 164 165 public: 165 166 /** Standard contructor taking split plane as argument. … … 275 276 276 277 /** Default constructor creating an empty tree. 278 @param viewCell view cell corresponding to unbounded space 277 279 */ 278 BspTree( );280 BspTree(ViewCell *viewCell); 279 281 280 282 ~BspTree(); … … 427 429 inline int GetNextCandidateIdx(const int max) const; 428 430 431 /** Helper function which extracts a view cell on the front and the back 432 of the split plane. 433 @param backViewCell returns view cell on the back of the split plane 434 @param frontViewCell returns a view cell on the front of the split plane 435 @param coincident container of polygons coincident to the split plane 436 @param splitPlane the split plane which decides about back and front 437 @param extractFront if a front view cell is extracted 438 @param extractBack if a back view cell is extracted 439 */ 440 void ExtractViewCells(ViewCell **backViewCell, 441 ViewCell **frontViewCell, 442 const PolygonContainer &coincident, 443 const Plane3 splitPlane, 444 const bool extractFront, 445 const bool extractBack) const; 446 429 447 /// Pointer to the root of the tree 430 448 BspNode *mRoot; … … 436 454 437 455 /// Strategies for choosing next split plane. 438 enum {NEXT_POLYGON = 0, 439 LEAST_SPLITS = 2, 440 BALANCED_TREE = 4, 441 VERTICAL_AXIS = 8, 442 AXIS_ALIGNED = 16}; 456 enum {NO_STRATEGY = 0, 457 NEXT_POLYGON = 1, 458 AXIS_ALIGNED = 2, 459 LEAST_SPLITS = 4, 460 BALANCED_POLYS = 8, 461 BALANCED_VIEW_CELLS = 16, 462 LARGEST_POLY_AREA = 32, 463 VERTICAL_AXIS = 64 464 }; 443 465 444 466 /// box around the whole view domain … … 448 470 bool mStorePolys; 449 471 450 /// v ertical axis of scene451 V ector3 mVerticalAxis;472 /// view cell corresponding to unbounded space 473 ViewCell *mViewCell; 452 474 453 475 public: … … 465 487 /// BSP tree construction method 466 488 static int sConstructionMethod; 467 489 /// maximal number of polygons where we do axis aligned splits 490 static int sTermMaxPolysForAxisAligned; 491 492 // factors to guid the split plane heuristics 468 493 static float sLeastSplitsFactor; 469 static float sBalancedTreeFactor; 470 static float sVerticalFactor; 471 494 static float sBalancedPolysFactor; 495 static float sBalancedViewCellsFactor; 496 static float sVerticalSplitsFactor; 497 472 498 private: 473 499 /** Evaluates split plane classification with respect to the plane's … … 478 504 contribution for a minimum number splits in the tree. 479 505 */ 480 static float sBalanced TreeTable[4];506 static float sBalancedPolysTable[4]; 481 507 }; 482 508 -
trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
r294 r297 47 47 p->GenerateViewCells(); 48 48 49 Debug << "Viewcells loaded / generated. Number of view cells: " << p->mViewCells.size() << endl;49 Debug << "Viewcells loaded / generated. Number of view cells: " << (int)p->mViewCells.size() << endl; 50 50 } 51 51
Note: See TracChangeset
for help on using the changeset viewer.