- Timestamp:
- 11/08/05 19:00:49 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/scripts/Preprocessor.vcproj
r378 r390 20 20 Name="VCCLCompilerTool" 21 21 Optimization="0" 22 AdditionalIncludeDirectories="..\ include"22 AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include" 23 23 PreprocessorDefinitions="WIN32;_DEBUG;_LIB" 24 24 MinimalRebuild="TRUE" … … 62 62 <Tool 63 63 Name="VCCLCompilerTool" 64 AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include; "$(QTDIR)\include";"$(QTDIR)\include\Qt";..\include"64 AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include" 65 65 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;" 66 66 RuntimeLibrary="2" … … 285 285 </File> 286 286 <File 287 RelativePath="..\src\VisibilityVector3.h">288 </File>289 <File290 287 RelativePath="..\src\VssPreprocessor.cpp"> 291 288 </File> … … 365 362 </File> 366 363 </Filter> 367 <File368 RelativePath=".\VTune\Preprocessor.vpj">369 </File>370 364 </Files> 371 365 <Globals> -
trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
r389 r390 1215 1215 "5"); 1216 1216 1217 RegisterOption("BspTree.Termination.minPvs", 1218 optInt, 1219 "-bsp_term_min_pvs=", 1220 "20"); 1221 1217 1222 RegisterOption("BspTree.Termination.maxRays", 1218 1223 optInt, … … 1276 1281 1277 1282 1278 RegisterOption("Bsp tree.Visualization.samples",1283 RegisterOption("BspTree.Visualization.samples", 1279 1284 optInt, 1280 1285 "-bsp_visualization_samples=", … … 1285 1290 "-bsp_visualization.exportSplits", 1286 1291 "false"); 1287 1288 RegisterOption("BspTree.Visualization.storePolys",1289 optBool,1290 "-bsp_visualization_store_polys=",1291 "false");1292 1292 1293 1293 RegisterOption("Preprocessor.type", -
trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h
r387 r390 153 153 154 154 virtual ostream &Describe(ostream &s) { 155 return s<<"Mesh #vertices="<< mVertices.size()<<" #faces="<<mFaces.size();155 return s<<"Mesh #vertices="<<(int)mVertices.size()<<" #faces="<<(int)mFaces.size(); 156 156 } 157 157 -
trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
r384 r390 439 439 440 440 for (pit = cell.begin(); pit != cell.end(); ++ pit) 441 { 441 442 area += (*pit)->GetArea(); 442 443 } 443 444 return area; 444 445 } -
trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
r389 r390 15 15 environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples); 16 16 environment->GetIntValue("ViewCells.PostProcessing.samples", mPostProcessSamples); 17 environment->GetIntValue("BspTree. visualizationSamples", mVisualizationSamples);17 environment->GetIntValue("BspTree.Visualization.samples", mVisualizationSamples); 18 18 19 19 mKdPvsDepth = 100; … … 728 728 } 729 729 // save rays for post processing 730 else if (( int)mSampleRays.size() < mPostProcessSamples) ||731 (((int)mSampleRays.size() < mVisualizationSamples))730 else if (((int)mSampleRays.size() < mPostProcessSamples) || 731 ((int)mSampleRays.size() < mVisualizationSamples)) 732 732 { 733 733 mSampleRays.push_back(new Ray(ray)); … … 747 747 for (int i = 0; i < limit; ++i) 748 748 { 749 Ray *ray = mSample sRays[i];749 Ray *ray = mSampleRays[i]; 750 750 751 751 // traverse leaves stored in the rays and compare and merge consecutive … … 842 842 //-- some rays for output 843 843 const int raysOut = min((int)mSampleRays.size(), mVisualizationSamples); 844 cout << "visualization using " << mVisualizationSamples << " samples" << endl; 844 845 vector<Ray *> vcRays[leafOut]; 845 846 … … 882 883 ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 883 884 885 //exporter->SetWireframe(); 886 exporter->SetFilled(); 887 888 Material m;//= RandomMaterial(); 889 m.mDiffuseColor = RgbColor(0, 1, 0); 890 exporter->SetForcedMaterial(m); 891 892 if (vc->GetMesh()) 893 exporter->ExportViewCell(vc); 894 else 895 { 896 PolygonContainer cell; 897 // export view cell geometry 898 mBspTree->ConstructGeometry(vc, cell); 899 exporter->ExportPolygons(cell); 900 CLEAR_CONTAINER(cell); 901 } 902 903 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 904 << ", piercing rays=" << (int)vcRays[i].size() << endl; 905 906 // export rays piercing this view cell 907 exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0)); 908 909 m.mDiffuseColor = RgbColor(1, 0, 0); 910 exporter->SetForcedMaterial(m); 911 884 912 exporter->SetWireframe(); 913 914 // output PVS of view cell 915 for (; it != vc->GetPvs().mEntries.end(); ++ it) 916 { 917 Intersectable *intersect = (*it).first; 918 if (!intersect->Mailed()) 919 { 920 exporter->ExportIntersectable(intersect); 921 intersect->Mail(); 922 } 923 } 924 925 // output rest of the objects 926 if (0) 927 { 928 Material m;//= RandomMaterial(); 929 m.mDiffuseColor = RgbColor(0, 0, 1); 930 exporter->SetForcedMaterial(m); 931 932 for (int j = 0; j < objects.size(); ++ j) 933 if (!objects[j]->Mailed()) 934 { 935 exporter->SetForcedMaterial(m); 936 exporter->ExportIntersectable(objects[j]); 937 objects[j]->Mail(); 938 } 939 } 940 DEL_PTR(exporter); 941 cout << "finished" << endl; 942 } 943 } 944 else 945 { 946 ViewCellContainer viewCells; 947 948 mBspTree->CollectViewCells(viewCells); 949 stable_sort(viewCells.begin(), viewCells.end(), vc_gt); 950 951 int limit = min(leafOut, (int)viewCells.size()); 952 953 for (int i = 0; i < limit; ++ i) 954 { 955 cout << "creating output for view cell " << i << " ... "; 956 957 Intersectable::NewMail(); 958 BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]); 959 960 cout << "creating output for view cell " << i << " ... "; 961 // check whether we can add the current ray to the output rays 962 for (int k = 0; k < raysOut; ++ k) 963 { 964 Ray *ray = mSampleRays[k]; 965 966 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 967 { 968 BspLeaf *leaf = ray->bspIntersections[j].mLeaf; 969 970 if (vc == leaf->GetViewCell()) 971 { 972 vcRays[i].push_back(ray); 973 } 974 } 975 } 976 977 //bspLeaves[j]->Mail(); 978 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 979 980 Exporter *exporter = Exporter::GetExporter(s); 981 exporter->SetFilled(); 982 983 ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 984 985 exporter->SetFilled();//Wireframe(); 885 986 886 987 Material m;//= RandomMaterial(); … … 899 1000 } 900 1001 901 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 902 << ", piercing rays=" << (int)vcRays[i].size() << endl; 903 1002 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() << endl; 1003 1004 904 1005 // export rays piercing this view cell 905 exporter->ExportRays(vcRays[i], 1000 , RgbColor(0, 1, 0));1006 exporter->ExportRays(vcRays[i], 10000, RgbColor(0, 1, 0)); 906 1007 907 1008 m.mDiffuseColor = RgbColor(1, 0, 0); … … 919 1020 } 920 1021 921 // output rest of the objects922 if (0)923 {924 Material m;//= RandomMaterial();925 m.mDiffuseColor = RgbColor(0, 0, 1);926 exporter->SetForcedMaterial(m);927 928 for (int j = 0; j < objects.size(); ++ j)929 if (!objects[j]->Mailed())930 {931 exporter->SetForcedMaterial(m);932 exporter->ExportIntersectable(objects[j]);933 objects[j]->Mail();934 }935 }936 DEL_PTR(exporter);937 cout << "finished" << endl;938 }939 }940 else941 {942 ViewCellContainer viewCells;943 944 mBspTree->CollectViewCells(viewCells);945 stable_sort(viewCells.begin(), viewCells.end(), vc_gt);946 947 int limit = min(leafOut, (int)viewCells.size());948 949 for (int i = 0; i < limit; ++ i)950 {951 cout << "creating output for view cell " << i << " ... ";952 953 Intersectable::NewMail();954 BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);955 956 cout << "creating output for view cell " << i << " ... ";957 // check whether we can add the current ray to the output rays958 for (int k = 0; k < raysOut; ++ k)959 {960 Ray *ray = mSampleRays[k];961 962 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)963 {964 BspLeaf *leaf = ray->bspIntersections[j].mLeaf;965 966 if (vc == leaf->GetViewCell())967 {968 vcRays[i].push_back(ray);969 }970 }971 }972 973 //bspLeaves[j]->Mail();974 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);975 976 Exporter *exporter = Exporter::GetExporter(s);977 exporter->SetFilled();978 979 ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();980 981 exporter->SetWireframe();982 983 Material m;//= RandomMaterial();984 m.mDiffuseColor = RgbColor(0, 1, 0);985 exporter->SetForcedMaterial(m);986 987 if (vc->GetMesh())988 exporter->ExportViewCell(vc);989 else990 {991 PolygonContainer cell;992 // export view cell993 mBspTree->ConstructGeometry(vc, cell);994 exporter->ExportPolygons(cell);995 CLEAR_CONTAINER(cell);996 }997 998 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() << endl;999 1000 1001 // export rays piercing this view cell1002 exporter->ExportRays(vcRays[i], 10000, RgbColor(0, 1, 0));1003 1004 m.mDiffuseColor = RgbColor(1, 0, 0);1005 exporter->SetForcedMaterial(m);1006 1007 // output PVS of view cell1008 for (; it != vc->GetPvs().mEntries.end(); ++ it)1009 {1010 Intersectable *intersect = (*it).first;1011 if (!intersect->Mailed())1012 {1013 exporter->ExportIntersectable(intersect);1014 intersect->Mail();1015 }1016 }1017 1018 1022 DEL_PTR(exporter); 1019 1023 cout << "finished" << endl; -
trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
r380 r390 30 30 int mBspConstructionSamples; 31 31 int mPostProcessSamples; 32 32 int mVisualizationSamples; 33 33 34 34 void -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r389 r390 15 15 16 16 int BspTree::sTermMaxPolygons = 10; 17 int BspTree::sTermMinPvs = 20; 17 18 int BspTree::sTermMaxDepth = 20; 18 19 int BspTree::sMaxPolyCandidates = 10; … … 46 47 float BspTree::sPvsFactor = 1.0f; 47 48 48 bool BspTree::sStoreSplitPolys = false;49 50 49 int BspNode::mailID = 1; 51 50 … … 73 72 74 73 BspNode::BspNode(): 75 mParent(NULL) , mPolygons(NULL)74 mParent(NULL) 76 75 {} 77 76 78 77 BspNode::BspNode(BspInterior *parent): 79 mParent(parent) , mPolygons(NULL)78 mParent(parent) 80 79 {} 81 80 82 BspNode::~BspNode()83 {84 if (mPolygons)85 {86 CLEAR_CONTAINER(*mPolygons);87 DEL_PTR(mPolygons);88 }89 }90 81 91 82 bool BspNode::IsRoot() const … … 103 94 mParent = parent; 104 95 } 105 106 PolygonContainer *BspNode::GetPolygons()107 {108 if (!mPolygons)109 mPolygons = new PolygonContainer();110 111 return mPolygons;112 }113 114 void BspNode::ProcessPolygons(PolygonContainer *polys, bool storePolys)115 {116 if (storePolys)117 {118 while (!polys->empty())119 {120 GetPolygons()->push_back(polys->back());121 polys->pop_back();122 }123 }124 else CLEAR_CONTAINER(*polys);125 }126 127 96 128 97 /****************************************************************/ … … 169 138 } 170 139 171 void BspInterior::ProcessPolygon(Polygon3 **poly, const bool storePolys)172 {173 if (storePolys)174 GetPolygons()->push_back(*poly);175 else176 DEL_PTR(*poly);177 }178 179 140 int BspInterior::SplitPolygons(PolygonContainer &polys, 180 141 PolygonContainer &frontPolys, 181 142 PolygonContainer &backPolys, 182 PolygonContainer &coincident, 183 const bool storePolys) 143 PolygonContainer &coincident) 184 144 { 185 145 Polygon3 *splitPoly = NULL; … … 246 206 Debug << "split " << *poly << endl << *front_piece << endl << *back_piece << endl; 247 207 #endif 248 ProcessPolygon(&poly, storePolys);208 DEL_PTR(poly); 249 209 break; 250 210 default: … … 449 409 mRoot = new BspLeaf(); 450 410 451 tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new BoundedRayContainer())); 411 tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new BoundedRayContainer(), 0, 412 mBox.SurfaceArea(), new BspNodeGeometry())); 452 413 453 414 while (!tStack.empty()) … … 471 432 472 433 // split viewcell polygons with respect to split plane 473 splits += interior->SplitPolygons(*tData.mPolygons, 434 splits += interior->SplitPolygons(*tData.mPolygons, 474 435 *frontPolys, 475 436 *backPolys, 476 coincident, 477 sStoreSplitPolys); 437 coincident); 478 438 479 439 // extract view cells associated with the split polygons 480 440 ViewCell *frontViewCell = mRootCell; 481 441 ViewCell *backViewCell = mRootCell; 482 442 443 BspTraversalData frontData(interior->GetFront(), 444 frontPolys, 445 tData.mDepth + 1, 446 mRootCell, 447 tData.mRays, 448 tData.mPvs, 449 mBox.SurfaceArea(), 450 new BspNodeGeometry()); 451 452 BspTraversalData backData(interior->GetBack(), 453 backPolys, 454 tData.mDepth + 1, 455 mRootCell, 456 tData.mRays, 457 tData.mPvs, 458 mBox.SurfaceArea(), 459 new BspNodeGeometry()); 460 483 461 if (!mGenerateViewCells) 484 462 { 485 ExtractViewCells(&backViewCell, 486 &frontViewCell, 487 coincident, 488 interior->mPlane, 489 frontPolys->empty(), 490 backPolys->empty()); 463 ExtractViewCells(frontData, 464 backData, 465 coincident, 466 interior->mPlane); 491 467 } 492 468 493 469 // don't need coincident polygons anymore 494 interior->ProcessPolygons(&coincident, sStoreSplitPolys);470 CLEAR_CONTAINER(coincident); 495 471 496 472 mStat.splits += splits; 497 473 498 474 // push the children on the stack 499 tStack.push(BspTraversalData(interior->GetFront(), 500 frontPolys, 501 tData.mDepth + 1, 502 frontViewCell, 503 tData.mRays)); 504 505 tStack.push(BspTraversalData(interior->GetBack(), 506 backPolys, 507 tData.mDepth + 1, 508 backViewCell, 509 new BoundedRayContainer())); 475 tStack.push(frontData); 476 tStack.push(backData); 510 477 } 511 478 … … 704 671 mRoot = new BspLeaf(); 705 672 706 BspTraversalData tData(mRoot, polys, 0, mRootCell, rays); 673 BspNodeGeometry *cell = new BspNodeGeometry(); 674 ConstructGeometry(mRoot, *cell); 675 676 BspTraversalData tData(mRoot, polys, 0, mRootCell, rays, 677 ComputePvsSize(*rays), cell->GetArea(), cell); 678 707 679 tStack.push(tData); 708 680 … … 728 700 //-- terminate traversal 729 701 if (((int)tData.mPolygons->size() <= sTermMaxPolygons) || 730 ((int)tData.mRays->size() <= sTermMaxRays) || 731 (tData.mDepth >= sTermMaxDepth)) 702 ((int)tData.mRays->size() <= sTermMaxRays) || 703 ((int)tData.mPvs <= sTermMinPvs) || 704 (tData.mDepth >= sTermMaxDepth)) 732 705 733 706 { … … 754 727 //-- clean up 755 728 756 // remaining polygons are discarded or added to node 757 leaf->ProcessPolygons(tData.mPolygons, sStoreSplitPolys); 758 DEL_PTR(tData.mPolygons); 729 // discard polygons 730 CLEAR_CONTAINER(*tData.mPolygons); 759 731 // discard rays 760 732 CLEAR_CONTAINER(*tData.mRays); 733 734 DEL_PTR(tData.mPolygons); 761 735 DEL_PTR(tData.mRays); 762 736 DEL_PTR(tData.mCell); 737 763 738 return leaf; 764 739 } … … 774 749 BoundedRayContainer *backRays = new BoundedRayContainer(); 775 750 751 BspTraversalData tFrontData(NULL, new PolygonContainer(), tData.mDepth + 1, mRootCell, 752 new BoundedRayContainer(), 0, NULL, 0); 753 BspTraversalData tBackData(NULL, new PolygonContainer(), tData.mDepth + 1, mRootCell, 754 new BoundedRayContainer(), 0, NULL, 0); 755 776 756 // create new interior node and two leaf nodes 777 BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode), 778 *tData.mPolygons, 779 *frontPolys, 780 *backPolys, 781 coincident, 782 *tData.mRays, 783 *frontRays, 784 *backRays); 785 ViewCell *frontViewCell = mRootCell; 786 ViewCell *backViewCell = mRootCell; 787 788 757 BspInterior *interior = SubdivideNode(tData, 758 tFrontData, 759 tBackData, 760 coincident); 761 789 762 #ifdef _DEBUG 790 763 if (frontPolys->empty() && backPolys->empty() && (coincident.size() > 2)) … … 798 771 if (!mGenerateViewCells) 799 772 { 800 ExtractViewCells( &backViewCell,801 &frontViewCell,773 ExtractViewCells(tFrontData, 774 tBackData, 802 775 coincident, 803 interior->mPlane, 804 backPolys->empty(), 805 frontPolys->empty()); 806 } 807 808 // don't need coincident polygons anymore 809 interior->ProcessPolygons(&coincident, sStoreSplitPolys); 776 interior->mPlane); 777 778 } 779 780 // don't need coincident polygons anymory 781 CLEAR_CONTAINER(coincident); 810 782 811 783 // push the children on the stack 812 tStack.push(BspTraversalData(interior->GetBack(), 813 backPolys, 814 tData.mDepth + 1, 815 backViewCell, 816 backRays)); 817 818 tStack.push(BspTraversalData(interior->GetFront(), 819 frontPolys, 820 tData.mDepth + 1, 821 frontViewCell, 822 frontRays)); 784 tStack.push(tFrontData); 785 tStack.push(tBackData); 823 786 824 787 // cleanup … … 826 789 DEL_PTR(tData.mPolygons); 827 790 DEL_PTR(tData.mRays); 791 DEL_PTR(tData.mCell); 828 792 829 793 return interior; 830 794 } 831 795 832 void BspTree::ExtractViewCells( ViewCell **backViewCell,833 ViewCell **frontViewCell,796 void BspTree::ExtractViewCells(BspTraversalData &frontData, 797 BspTraversalData &backData, 834 798 const PolygonContainer &coincident, 835 const Plane3 splitPlane ,836 const bool extractBack, 837 const bool extractFront) const838 { 839 bool found Front = !extractFront, foundBack = !extractBack;799 const Plane3 splitPlane) const 800 { 801 // if not empty, tree is further subdivided => don't have to find view cell 802 bool foundFront = !frontData.mPolygons->empty(); 803 bool foundBack = !frontData.mPolygons->empty(); 840 804 841 805 PolygonContainer::const_iterator it = … … 847 811 if (DotProd((*it)->GetNormal(), splitPlane.mNormal) > 0) 848 812 { 849 *backViewCell = dynamic_cast<ViewCell *>((*it)->mParent);813 backData.mViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 850 814 foundBack = true; 851 815 } 852 816 else 853 817 { 854 *frontViewCell = dynamic_cast<ViewCell *>((*it)->mParent);818 frontData.mViewCell = dynamic_cast<ViewCell *>((*it)->mParent); 855 819 foundFront = true; 856 820 } 857 821 } 858 //if (extractFront && foundFront) Debug << "front view cell: " << *frontViewCell << endl; 859 //if (extractBack && foundBack) Debug << "back view cell: " << *backViewCell << endl; 860 } 861 862 BspInterior *BspTree::SubdivideNode(BspLeaf *leaf, 863 PolygonContainer &polys, 864 PolygonContainer &frontPolys, 865 PolygonContainer &backPolys, 866 PolygonContainer &coincident, 867 BoundedRayContainer &rays, 868 BoundedRayContainer &frontRays, 869 BoundedRayContainer &backRays) 822 } 823 824 BspInterior *BspTree::SubdivideNode(BspTraversalData &tData, 825 BspTraversalData &frontData, 826 BspTraversalData &backData, 827 PolygonContainer &coincident) 870 828 { 871 829 mStat.nodes += 2; 872 830 831 BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode); 873 832 // select subdivision plane 874 833 BspInterior *interior = 875 new BspInterior(SelectPlane(leaf, polys, rays));834 new BspInterior(SelectPlane(leaf, tData, frontData, backData)); 876 835 877 836 #ifdef _DEBUG … … 880 839 881 840 // subdivide rays into front and back rays 882 SplitRays(interior->mPlane, rays, frontRays, backRays);841 SplitRays(interior->mPlane, *tData.mRays, *frontData.mRays, *backData.mRays); 883 842 884 843 // subdivide polygons with plane 885 mStat.splits += interior->SplitPolygons(polys, 886 frontPolys, 887 backPolys, 888 coincident, 889 sStoreSplitPolys); 844 mStat.splits += interior->SplitPolygons(*tData.mPolygons, 845 *frontData.mPolygons, 846 *backData.mPolygons, 847 coincident); 890 848 891 849 BspInterior *parent = leaf->GetParent(); … … 904 862 // and setup child links 905 863 interior->SetupChildLinks(new BspLeaf(interior), new BspLeaf(interior)); 864 865 frontData.mNode = interior->mFront; 866 backData.mNode = interior->mBack; 906 867 907 868 return interior; … … 1049 1010 1050 1011 Plane3 BspTree::SelectPlane(BspLeaf *leaf, 1051 PolygonContainer &polys, 1052 const BoundedRayContainer &rays) 1053 { 1054 if (polys.empty() && rays.empty()) 1012 BspTraversalData &data, 1013 BspTraversalData &frontData, 1014 BspTraversalData &backData) 1015 { 1016 if (data.mPolygons->empty() && data.mRays->empty()) 1055 1017 { 1056 1018 Debug << "Warning: No autopartition polygon candidate available\n"; … … 1061 1023 1062 1024 // create bounding box of region 1063 Polygon3::IncludeInBox( polys, box);1025 Polygon3::IncludeInBox(*data.mPolygons, box); 1064 1026 1065 1027 const int axis = box.Size().DrivingAxis(); … … 1071 1033 1072 1034 if ((sSplitPlaneStrategy & AXIS_ALIGNED) && 1073 ((int) polys.size() > sTermMaxPolysForAxisAligned) &&1074 ((int) rays.size() > sTermMaxRaysForAxisAligned) &&1035 ((int)data.mPolygons->size() > sTermMaxPolysForAxisAligned) && 1036 ((int)data.mRays->size() > sTermMaxRaysForAxisAligned) && 1075 1037 ((sTermMaxObjectsForAxisAligned < 0) || 1076 (Polygon3::ParentObjectsSize( polys) > sTermMaxObjectsForAxisAligned)))1038 (Polygon3::ParentObjectsSize(*data.mPolygons) > sTermMaxObjectsForAxisAligned))) 1077 1039 { 1078 1040 Plane3 plane; 1079 if (SelectAxisAlignedPlane(plane, polys))1041 if (SelectAxisAlignedPlane(plane, *data.mPolygons)) 1080 1042 return plane; 1081 1043 } … … 1084 1046 if (sSplitPlaneStrategy & RANDOM_POLYGON) 1085 1047 { 1086 return polys[Random((int)polys.size())]->GetSupportingPlane(); 1048 Polygon3 *nextPoly = (*data.mPolygons)[Random((int)data.mPolygons->size())]; 1049 return nextPoly->GetSupportingPlane(); 1087 1050 } 1088 1051 1089 1052 // use heuristics to find appropriate plane 1090 return SelectPlaneHeuristics(leaf, polys, rays, sMaxPolyCandidates, 1091 sMaxRayCandidates); 1053 return SelectPlaneHeuristics(leaf, data, frontData, backData); 1092 1054 } 1093 1055 1094 1056 Plane3 BspTree::SelectPlaneHeuristics(BspLeaf *leaf, 1095 PolygonContainer &polys, 1096 const BoundedRayContainer &rays, 1097 const int maxPolyCandidates, 1098 const int maxRayCandidates) 1057 BspTraversalData &data, 1058 BspTraversalData &frontData, 1059 BspTraversalData &backData) 1099 1060 { 1100 1061 float lowestCost = MAX_FLOAT; 1101 int bestPlaneIdx = 0;1102 1103 int limit = maxPolyCandidates > 0 ?1104 Min((int) polys.size(), maxPolyCandidates) : (int)polys.size();1062 Plane3 bestPlane; 1063 1064 int limit = sMaxPolyCandidates > 0 ? 1065 Min((int)data.mPolygons->size(), sMaxPolyCandidates) : (int)data.mPolygons->size(); 1105 1066 1106 1067 int candidateIdx = limit; 1107 1068 1108 // only for pvs criterium1109 PolygonContainer cell;1110 vector<Plane3 *> planes;1111 vector<bool> sides;1112 int pvsSize = 0;1113 1114 if (sSplitPlaneStrategy & PVS)1115 {1116 ConstructGeometry(leaf, cell);1117 ExtractSplitPlanes(leaf, planes, sides);1118 pvsSize = ComputePvsSize(rays);1119 }1120 1121 1069 for (int i = 0; i < limit; ++ i) 1122 1070 { 1123 candidateIdx = GetNextCandidateIdx(candidateIdx, polys); 1124 1071 candidateIdx = GetNextCandidateIdx(candidateIdx, *data.mPolygons); 1072 1073 Polygon3 *poly = (*data.mPolygons)[candidateIdx]; 1125 1074 // evaluate current candidate 1126 1075 const float candidateCost = 1127 SplitPlaneCost(poly s[candidateIdx]->GetSupportingPlane(),1128 polys, rays, cell, planes, sides, pvsSize); 1129 1130 //Debug << polys[candidateIdx] << endl; 1076 SplitPlaneCost(poly->GetSupportingPlane(), data, frontData, backData); 1077 1078 Debug << "cost: " << candidateCost << ", lowest: " << lowestCost << endl; 1079 1131 1080 if (candidateCost < lowestCost) 1132 1081 { 1133 bestPlane Idx = candidateIdx;1082 bestPlane = poly->GetSupportingPlane(); 1134 1083 lowestCost = candidateCost; 1135 1084 } 1136 1085 } 1137 1086 1138 //limit = maxRaysCandidates > 0 ? Min((int)rays.size(), maxRayCandidates) : (int)rays.size(); 1139 bool chooseFromRays = false; 1140 int bestIdx[3]; 1141 1142 for (int i = 0; i < maxRayCandidates; ++ i) 1143 { 1144 Vector3 pt[3]; 1145 int idx[3]; 1146 1147 for (int j = 0; j < 3; j ++) 1148 { 1149 idx[j] = Random((int)rays.size() * 2); 1087 //limit = maxRaysCandidates > 0 ? Min((int)rays.size(), maxRayCandidates) : (int)rays.size(); 1088 const BoundedRayContainer *rays = data.mRays; 1089 1090 for (int i = 0; i < sMaxRayCandidates; ++ i) 1091 { 1092 Plane3 plane; 1093 1094 if (1) 1095 { 1096 Vector3 pt[3]; 1097 int idx[3]; 1098 1099 for (int j = 0; j < 3; j ++) 1100 { 1101 idx[j] = Random((int)rays->size() * 2); 1150 1102 1151 if (idx[j] < (int)rays.size()) 1152 pt[j] = rays[idx[j]]->mRay->Extrap(rays[idx[j]]->mMinT); 1153 else 1154 { 1155 idx[j] -= (int)rays.size(); 1156 pt[j] = rays[idx[j]]->mRay->Extrap(rays[idx[j]]->mMaxT); 1157 } 1158 1159 } 1160 1161 const float candidateCost = 1162 SplitPlaneCost(Plane3(pt[0], pt[1], pt[2]), 1163 polys, rays, cell, planes, sides, pvsSize); 1103 BoundedRay *bRay = (*rays)[idx[j]]; 1104 Ray *ray = bRay->mRay; 1105 1106 if (idx[j] < (int)rays->size()) 1107 pt[j] = ray->Extrap(bRay->mMinT); 1108 else 1109 { 1110 idx[j] -= (int)rays->size(); 1111 pt[j] = ray->Extrap(bRay->mMaxT); 1112 } 1113 } 1114 1115 plane = Plane3(pt[0], pt[1], pt[2]); 1116 } 1117 else 1118 { 1119 candidateIdx = Random((int)rays->size()); 1120 BoundedRay *bRay = (*rays)[candidateIdx]; 1121 1122 Ray *ray = bRay->mRay; 1123 1124 const Vector3 minPt = ray->Extrap(bRay->mMinT); 1125 const Vector3 maxPt = ray->Extrap(bRay->mMaxT); 1126 1127 const Vector3 pt = (maxPt + minPt) * 0.5; 1128 1129 const Vector3 normal = ray->GetDir(); 1130 1131 plane = Plane3(normal, pt); 1132 } 1133 1134 const float candidateCost = 1135 SplitPlaneCost(plane, data, frontData, backData); 1164 1136 1165 1137 if (candidateCost < lowestCost) 1166 1138 { 1167 chooseFromRays = true;1168 best Idx[0] = idx[0]; bestIdx[1]= idx[1]; bestIdx[2] = idx[2];1139 Debug << "choose ray plane: " << lowestCost << endl; 1140 bestPlane = plane; 1169 1141 1170 1142 lowestCost = candidateCost; 1171 1143 } 1172 } 1173 1174 CLEAR_CONTAINER(cell); 1175 1176 if (chooseFromRays) 1177 { 1178 Debug << "choose ray plane: " << lowestCost << endl; 1179 return Plane3(rays[bestIdx[0]]->mRay->Extrap(rays[bestIdx[0]]->mMaxT), 1180 rays[bestIdx[1]]->mRay->Extrap(rays[bestIdx[1]]->mMaxT), 1181 rays[bestIdx[2]]->mRay->Extrap(rays[bestIdx[2]]->mMaxT)); 1144 else 1145 Debug << "ray cost: " << candidateCost << ", lowest: " << lowestCost << endl; 1182 1146 } 1183 1147 1184 1148 //Debug << "Plane lowest cost: " << lowestCost << endl; 1185 return polys[bestPlaneIdx]->GetSupportingPlane();1149 return bestPlane; 1186 1150 } 1187 1151 … … 1337 1301 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 1338 1302 const BoundedRayContainer &rays, 1339 const float frontArea, 1340 const float backArea, 1341 const int pvsSize) const 1303 const int pvs, 1304 const float area, 1305 const BspNodeGeometry &cell, 1306 BspTraversalData &frontData, 1307 BspTraversalData &backData) const 1342 1308 { 1343 1309 float val = 0; … … 1345 1311 float sumBalancedRays = 0; 1346 1312 float sumRaySplits = 0; 1347 float frontPvs = 0; 1348 float backPvs = 0; 1349 1350 float totalSize = 0; 1351 1352 // create three unique ids for pvs heuristics 1353 Intersectable::NewMail(); const int backId = ViewCell::sMailId; 1354 Intersectable::NewMail(); const int frontId = ViewCell::sMailId; 1355 Intersectable::NewMail(); const int frontAndBackId = ViewCell::sMailId; 1356 1357 int frontRays = 0; 1358 int backRays = 0; 1359 1313 1314 int backId = 0; 1315 int frontId = 0; 1316 int frontAndBackId = 0; 1317 1318 frontData.mPvs = 0; 1319 backData.mPvs = 0; 1320 frontData.mArea = 0; 1321 backData.mArea = 0; 1322 1323 // probability that view point lies in child 1324 float pOverall = 0; 1325 float pFront = 0; 1326 float pBack = 0; 1327 1328 if (sSplitPlaneStrategy & PVS) 1329 { 1330 // create three unique ids for pvs heuristics 1331 Intersectable::NewMail(); backId = ViewCell::sMailId; 1332 Intersectable::NewMail(); frontId = ViewCell::sMailId; 1333 Intersectable::NewMail(); frontAndBackId = ViewCell::sMailId; 1334 1335 if (1) // use front and back cell areas to approximate volume 1336 { 1337 //-- compute area 1338 1339 // construct child geometry with regard to the candidate split plane 1340 frontData.mCell = cell.ConstructChild(*this, candidatePlane, true); 1341 backData.mCell = cell.ConstructChild(*this, candidatePlane, false); 1342 1343 frontData.mArea = frontData.mCell->GetArea(); 1344 backData.mArea = backData.mCell->GetArea(); 1345 1346 pFront = frontData.mArea; 1347 pBack = backData.mArea; 1348 1349 pOverall = area; 1350 } 1351 else 1352 { 1353 pOverall = (float)rays.size(); 1354 } 1355 } 1356 1360 1357 BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 1361 1358 … … 1386 1383 // assure that we only count a object 1387 1384 // once for the front and once for the back side of the plane 1388 AddToPvs(*ray->intersections[0].mObject, 1389 frontPvs, backPvs, 1390 cf, frontId, backId, frontAndBackId); 1385 AddToPvs(*ray->intersections[0].mObject, frontData.mPvs, backData.mPvs, 1386 cf, frontId, backId, frontAndBackId); 1391 1387 } 1392 1388 1393 1389 // the source object in the origin of the ray 1394 AddToPvs(*ray->sourceObject.mObject, 1395 frontPvs, backPvs,1396 cf, frontId, backId, frontAndBackId); 1397 1390 AddToPvs(*ray->sourceObject.mObject, frontData.mPvs, backData.mPvs, 1391 cf, frontId, backId, frontAndBackId); 1392 1393 // use #rays to approximate volume 1398 1394 if (0) 1399 1395 { 1400 1396 if ((cf == Ray::BACK) || (cf == Ray::FRONT_BACK) || (cf == Ray::BACK_FRONT)) 1401 ++ backRays;1397 ++ pFront; 1402 1398 if ((cf == Ray::FRONT) || (cf == Ray::FRONT_BACK) || (cf == Ray::BACK_FRONT)) 1403 ++ frontRays;1399 ++ pBack; 1404 1400 } 1405 1401 } 1406 1402 } 1407 1403 1408 if (sSplitPlaneStrategy & LEAST_RAY_SPLITS) 1409 if (!rays.empty()) 1404 if ((sSplitPlaneStrategy & LEAST_RAY_SPLITS) && !rays.empty()) 1410 1405 val += sLeastRaySplitsFactor * sumRaySplits / (float)rays.size(); 1411 1406 1412 if (sSplitPlaneStrategy & BALANCED_RAYS) 1413 if (!rays.empty()) 1407 if ((sSplitPlaneStrategy & BALANCED_RAYS) && !rays.empty()) 1414 1408 val += sBalancedRaysFactor * fabs(sumBalancedRays) / (float)rays.size(); 1415 1409 1416 if ( sSplitPlaneStrategy & PVS)1417 if (0 && !rays.empty()) // HACK (should divide by maximal possible pvs)1418 val += sPvsFactor * (frontPvs * (float)frontRays + (backPvs * (float)backRays)) / (float)rays.size(); 1419 else1420 val += sPvsFactor * (frontPvs * frontArea + (backPvs * backArea)) /1421 ((frontArea + backArea) * (float)pvsSize);1422 1423 //Debug << "pvs: " << pvsSize << " val " << val << endl; 1410 if ((sSplitPlaneStrategy & PVS) && area && pvs) 1411 val += sPvsFactor * (frontData.mPvs * pFront + (backData.mPvs * pBack)) / (pOverall * (float)pvs * 2); 1412 1413 Debug << "pvs: " << pvs << " totalArea: " << area 1414 << " frontpvs: " << frontData.mPvs << " pFront: " << pFront 1415 << " backpvs: " << backData.mPvs << " pBack: " << pBack 1416 << " val " << val << endl; 1417 1424 1418 return val; 1425 1419 } 1426 1420 1427 1421 void BspTree::AddToPvs(Intersectable &obj, 1428 float &frontPvs,1429 float &backPvs,1422 int &frontPvs, 1423 int &backPvs, 1430 1424 const int cf, 1431 1425 const int frontId, … … 1441 1435 (obj.mMailbox != frontAndBackId)) 1442 1436 { 1443 frontPvs += 1.0;1437 ++ frontPvs; 1444 1438 1445 1439 if (obj.mMailbox != backId) … … 1454 1448 (obj.mMailbox != frontAndBackId)) 1455 1449 { 1456 backPvs += 1.0;1450 ++ backPvs; 1457 1451 1458 1452 if (obj.mMailbox != frontId) … … 1468 1462 { 1469 1463 if (obj.mMailbox != frontId) 1470 frontPvs += 1.0;1464 ++ frontPvs; 1471 1465 if (obj.mMailbox != backId) 1472 backPvs += 1.0;1466 ++ backPvs; 1473 1467 1474 1468 obj.mMailbox = frontAndBackId; … … 1477 1471 } 1478 1472 1479 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 1480 const PolygonContainer &polys, 1481 const BoundedRayContainer &rays, 1482 const PolygonContainer &cell, 1483 const vector<Plane3 *> &planes, 1484 const vector<bool> &sides, 1485 const int pvsSize) const 1473 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 1474 BspTraversalData &data, 1475 BspTraversalData &frontData, 1476 BspTraversalData &backData) const 1486 1477 { 1487 1478 float val = 0; … … 1503 1494 (sSplitPlaneStrategy & BLOCKED_RAYS)) 1504 1495 { 1505 val += SplitPlaneCost(candidatePlane, polys);1496 val += SplitPlaneCost(candidatePlane, *data.mPolygons); 1506 1497 } 1507 1498 … … 1511 1502 (sSplitPlaneStrategy & PVS)) 1512 1503 { 1513 float frontArea = 0; 1514 float backArea = 0; 1515 1516 if (sSplitPlaneStrategy & PVS) 1517 { 1518 PolygonContainer frontCell; 1519 PolygonContainer backCell; 1520 1521 // construct child geometry with regard to the candidate split plane 1522 ConstructChildGeometry(frontCell, cell, planes, sides, candidatePlane, true); 1523 ConstructChildGeometry(backCell, cell, planes, sides, candidatePlane, false); 1524 1525 frontArea = Polygon3::GetArea(frontCell); 1526 backArea = Polygon3::GetArea(backCell); 1527 1528 CLEAR_CONTAINER(frontCell); 1529 CLEAR_CONTAINER(backCell); 1530 } 1531 1532 val += SplitPlaneCost(candidatePlane, rays, frontArea, backArea, pvsSize); 1504 val += SplitPlaneCost(candidatePlane, *data.mRays, data.mPvs, 1505 data.mArea, *data.mCell, frontData, backData); 1533 1506 } 1534 1507 … … 1562 1535 //-- termination criteria for autopartition 1563 1536 environment->GetIntValue("BspTree.Termination.maxDepth", sTermMaxDepth); 1537 environment->GetIntValue("BspTree.Termination.minPvs", sTermMinPvs); 1564 1538 environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons); 1565 1539 environment->GetIntValue("BspTree.Termination.maxRays", sTermMaxRays); … … 1579 1553 environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy); 1580 1554 environment->GetFloatValue("BspTree.AxisAligned.splitBorder", sSplitBorder); 1581 1582 environment->GetBoolValue("BspTree.Visualization.storePolys", sStoreSplitPolys);1583 1555 1584 1556 environment->GetFloatValue("BspTree.Construction.sideTolerance", Vector3::sDistTolerance); … … 1591 1563 1592 1564 Debug << "BSP max depth: " << sTermMaxDepth << endl; 1565 Debug << "BSP min PVS: " << sTermMinPvs << endl; 1593 1566 Debug << "BSP max polys: " << sTermMaxPolygons << endl; 1594 1567 Debug << "BSP max rays: " << sTermMaxRays << endl; … … 1673 1646 mStat.minDepth = data.mDepth; 1674 1647 1648 // store minimal and maximal pvs 1649 /*if (data.mPvs > mStat.pvs) 1650 mStat.pvs = data.mPvs; 1651 1652 if (data.mPvs < mStat.pvs) 1653 mStat.pvs = data.mPvs;*/ 1654 1675 1655 // accumulate depth to compute average 1676 1656 mStat.accumDepth += data.mDepth; … … 1679 1659 Debug << "BSP stats: " 1680 1660 << "Depth: " << data.mDepth << " (max: " << sTermMaxDepth << "), " 1661 << "PVS: " << data.mPvs << " (max: " << sTermMinPvs << "), " 1681 1662 << "#polygons: " << (int)data.mPolygons->size() << " (max: " << sTermMaxPolygons << "), " 1682 1663 << "#rays: " << (int)data.mRays->size() << " (max: " << sTermMaxRays << "), " … … 1975 1956 { 1976 1957 case Ray::COINCIDENT: 1977 frontRays.push_back(bRay);1958 //frontRays.push_back(bRay); 1978 1959 break; 1979 1960 case Ray::BACK: … … 2024 2005 2025 2006 void BspTree::ExtractSplitPlanes(BspNode *n, 2026 vector<Plane3 *> &planes,2007 vector<Plane3> &planes, 2027 2008 vector<bool> &sides) const 2028 2009 { … … 2040 2021 BspInterior *interior = dynamic_cast<BspInterior *>(n); 2041 2022 2042 planes.push_back( dynamic_cast<BspInterior *>(interior)->GetPlane());2023 planes.push_back(* dynamic_cast<BspInterior *>(interior)->GetPlane()); 2043 2024 sides.push_back(interior->mFront == lastNode); 2044 2025 } … … 2047 2028 } 2048 2029 2049 bool BspTree::ConstructChildGeometry(PolygonContainer &childCell, 2050 const PolygonContainer &cell, 2051 const vector<Plane3 *> &planes, 2052 const vector<bool> &sides, 2053 const Plane3 &splitPlane, 2054 const bool side) const 2055 { 2030 void BspTree::ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const 2031 { 2032 stack<BspNode *> tStack; 2033 2034 vector<Plane3> planes; 2035 vector<bool> sides; 2036 2037 ExtractSplitPlanes(n, cell.mPlanes, cell.mSides); 2038 2039 PolygonContainer candidatePolys; 2040 2041 // bounded planes are added to the polygons 2042 for (int i = 0; i < (int)cell.mPlanes.size(); ++ i) 2043 { 2044 candidatePolys.push_back(GetBoundingBox().CrossSection(cell.mPlanes[i])); 2045 } 2046 2047 // add faces of bounding box (also could be faces of the cell) 2048 for (int i = 0; i < 6; ++ i) 2049 { 2050 VertexContainer vertices; 2051 2052 for (int j = 0; j < 4; ++ j) 2053 vertices.push_back(mBox.GetFace(i).mVertices[j]); 2054 2055 candidatePolys.push_back(new Polygon3(vertices)); 2056 } 2057 2058 for (int i = 0; i < (int)candidatePolys.size(); ++ i) 2059 { 2060 bool inside = true; 2061 2062 // polygon is split by all other planes 2063 for (int j = 0; (j < cell.mPlanes.size()) && inside; ++ j) 2064 { 2065 if (i == j) // same plane 2066 continue; 2067 2068 VertexContainer splitPts; 2069 Polygon3 *frontPoly, *backPoly; 2070 2071 const int cf = candidatePolys[i]->ClassifyPlane(cell.mPlanes[j]); 2072 2073 switch (cf) 2074 { 2075 case Polygon3::SPLIT: 2076 frontPoly = new Polygon3(); 2077 backPoly = new Polygon3(); 2078 2079 candidatePolys[i]->Split(cell.mPlanes[j], *frontPoly, 2080 *backPoly, splitPts); 2081 DEL_PTR(candidatePolys[i]); 2082 2083 if(sides[j] == true) 2084 { 2085 candidatePolys[i] = frontPoly; 2086 DEL_PTR(backPoly); 2087 } 2088 else 2089 { 2090 candidatePolys[i] = backPoly; 2091 DEL_PTR(frontPoly); 2092 } 2093 2094 break; 2095 2096 case Polygon3::BACK_SIDE: 2097 if (cell.mSides[j]) 2098 inside = false; 2099 break; 2100 case Polygon3::FRONT_SIDE: 2101 if (!cell.mSides[j]) 2102 inside = false; 2103 break; 2104 case Polygon3::COINCIDENT: 2105 break; 2106 default: 2107 break; 2108 } 2109 } 2110 2111 if (inside) 2112 cell.mPolys.push_back(candidatePolys[i]); 2113 else 2114 DEL_PTR(candidatePolys[i]); 2115 } 2116 } 2117 2118 void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 2119 { 2120 stack<BspNode *> tStack; 2121 2122 vector<Plane3> planes; 2123 vector<bool> sides; 2124 2125 ExtractSplitPlanes(n, planes, sides); 2126 2127 PolygonContainer candidatePolys; 2128 2129 // bounded planes are added to the polygons 2130 for (int i = 0; i < (int)planes.size(); ++ i) 2131 { 2132 candidatePolys.push_back(GetBoundingBox().CrossSection(planes[i])); 2133 } 2134 2135 // add faces of bounding box (also could be faces of the cell) 2136 for (int i = 0; i < 6; ++ i) 2137 { 2138 VertexContainer vertices; 2139 2140 for (int j = 0; j < 4; ++ j) 2141 vertices.push_back(mBox.GetFace(i).mVertices[j]); 2142 2143 candidatePolys.push_back(new Polygon3(vertices)); 2144 } 2145 2146 for (int i = 0; i < (int)candidatePolys.size(); ++ i) 2147 { 2148 bool inside = true; 2149 2150 // polygon is split by all other planes 2151 for (int j = 0; (j < planes.size()) && inside; ++ j) 2152 { 2153 if (i == j) // same plane 2154 continue; 2155 2156 VertexContainer splitPts; 2157 Polygon3 *frontPoly, *backPoly; 2158 2159 const int cf = candidatePolys[i]->ClassifyPlane(planes[j]); 2160 2161 switch (cf) 2162 { 2163 case Polygon3::SPLIT: 2164 frontPoly = new Polygon3(); 2165 backPoly = new Polygon3(); 2166 2167 candidatePolys[i]->Split(planes[j], *frontPoly, 2168 *backPoly, splitPts); 2169 DEL_PTR(candidatePolys[i]); 2170 2171 if(sides[j] == true) 2172 { 2173 candidatePolys[i] = frontPoly; 2174 DEL_PTR(backPoly); 2175 } 2176 else 2177 { 2178 candidatePolys[i] = backPoly; 2179 DEL_PTR(frontPoly); 2180 } 2181 2182 break; 2183 2184 case Polygon3::BACK_SIDE: 2185 if (sides[j]) 2186 inside = false; 2187 break; 2188 case Polygon3::FRONT_SIDE: 2189 if (!sides[j]) 2190 inside = false; 2191 break; 2192 case Polygon3::COINCIDENT: 2193 break; 2194 default: 2195 break; 2196 } 2197 } 2198 2199 if (inside) 2200 cell.push_back(candidatePolys[i]); 2201 else 2202 DEL_PTR(candidatePolys[i]); 2203 } 2204 } 2205 2206 void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const 2207 { 2208 vector<BspLeaf *> leaves = vc->mBspLeaves; 2209 2210 vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 2211 2212 for (it = leaves.begin(); it != it_end; ++ it) 2213 ConstructGeometry(*it, cell); 2214 } 2215 2216 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 2217 const bool onlyUnmailed) const 2218 { 2219 PolygonContainer cell; 2220 2221 ConstructGeometry(n, cell); 2222 2223 stack<BspNode *> nodeStack; 2224 nodeStack.push(mRoot); 2225 2226 // planes needed to verify that we found neighbor leaf. 2227 vector<Plane3> planes; 2228 vector<bool> sides; 2229 2230 ExtractSplitPlanes(n, planes, sides); 2231 2232 while (!nodeStack.empty()) 2233 { 2234 BspNode *node = nodeStack.top(); 2235 nodeStack.pop(); 2236 2237 if (node->IsLeaf()) 2238 { 2239 if (node != n && (!onlyUnmailed || !node->Mailed())) 2240 { 2241 // test all planes of current node on neighbour 2242 PolygonContainer neighborCandidate; 2243 ConstructGeometry(node, neighborCandidate); 2244 2245 bool isAdjacent = true; 2246 for (int i = 0; (i < planes.size()) && isAdjacent; ++ i) 2247 { 2248 const int cf = 2249 Polygon3::ClassifyPlane(neighborCandidate, planes[i]); 2250 2251 if ((cf == Polygon3::BACK_SIDE) && sides[i]) 2252 isAdjacent = false; 2253 else if ((cf == Polygon3::FRONT_SIDE) && !sides[i]) 2254 isAdjacent = false; 2255 } 2256 2257 if (isAdjacent) 2258 neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 2259 2260 CLEAR_CONTAINER(neighborCandidate); 2261 } 2262 } 2263 else 2264 { 2265 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2266 2267 const int cf = Polygon3::ClassifyPlane(cell, interior->mPlane); 2268 2269 if (cf == Polygon3::FRONT_SIDE) 2270 nodeStack.push(interior->mFront); 2271 else 2272 if (cf == Polygon3::BACK_SIDE) 2273 nodeStack.push(interior->mBack); 2274 else 2275 { 2276 // random decision 2277 nodeStack.push(interior->mBack); 2278 nodeStack.push(interior->mFront); 2279 } 2280 } 2281 } 2282 2283 CLEAR_CONTAINER(cell); 2284 return (int)neighbors.size(); 2285 } 2286 2287 BspLeaf *BspTree::GetRandomLeaf(const Plane3 &halfspace) 2288 { 2289 stack<BspNode *> nodeStack; 2290 nodeStack.push(mRoot); 2291 2292 int mask = rand(); 2293 2294 while (!nodeStack.empty()) 2295 { 2296 BspNode *node = nodeStack.top(); 2297 nodeStack.pop(); 2298 2299 if (node->IsLeaf()) 2300 { 2301 return dynamic_cast<BspLeaf *>(node); 2302 } 2303 else 2304 { 2305 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2306 2307 BspNode *next; 2308 2309 PolygonContainer cell; 2310 2311 // todo: not very efficient: constructs full cell everytime 2312 ConstructGeometry(interior, cell); 2313 2314 const int cf = Polygon3::ClassifyPlane(cell, halfspace); 2315 2316 if (cf == Polygon3::BACK_SIDE) 2317 next = interior->mFront; 2318 else 2319 if (cf == Polygon3::FRONT_SIDE) 2320 next = interior->mFront; 2321 else 2322 { 2323 // random decision 2324 if (mask & 1) 2325 next = interior->mBack; 2326 else 2327 next = interior->mFront; 2328 mask = mask >> 1; 2329 } 2330 2331 nodeStack.push(next); 2332 } 2333 } 2334 2335 return NULL; 2336 } 2337 2338 BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 2339 { 2340 stack<BspNode *> nodeStack; 2341 2342 nodeStack.push(mRoot); 2343 2344 int mask = rand(); 2345 2346 while (!nodeStack.empty()) 2347 { 2348 BspNode *node = nodeStack.top(); 2349 nodeStack.pop(); 2350 2351 if (node->IsLeaf()) 2352 { 2353 if ( (!onlyUnmailed || !node->Mailed()) ) 2354 return dynamic_cast<BspLeaf *>(node); 2355 } 2356 else 2357 { 2358 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2359 2360 // random decision 2361 if (mask & 1) 2362 nodeStack.push(interior->mBack); 2363 else 2364 nodeStack.push(interior->mFront); 2365 2366 mask = mask >> 1; 2367 } 2368 } 2369 2370 return NULL; 2371 } 2372 2373 int BspTree::ComputePvsSize(const BoundedRayContainer &rays) const 2374 { 2375 int pvsSize = 0; 2376 2377 BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 2378 2379 Intersectable::NewMail(); 2380 2381 for (rit = rays.begin(); rit != rays.end(); ++ rit) 2382 { 2383 Ray *ray = (*rit)->mRay; 2384 2385 if (!ray->intersections.empty()) 2386 { 2387 if (!ray->intersections[0].mObject->Mailed()) 2388 { 2389 ray->intersections[0].mObject->Mail(); 2390 ++ pvsSize; 2391 } 2392 } 2393 if (!ray->sourceObject.mObject->Mailed()) 2394 { 2395 ray->sourceObject.mObject->Mail(); 2396 ++ pvsSize; 2397 } 2398 } 2399 2400 return pvsSize; 2401 } 2402 2403 /************************************************************* 2404 * BspNodeGeometry Implementation * 2405 *************************************************************/ 2406 2407 BspNodeGeometry::BspNodeGeometry(const PolygonContainer &polys, 2408 const vector<Plane3> &planes, 2409 const vector<bool> &sides): 2410 mPolys(polys), mPlanes(planes), mSides(sides) 2411 {} 2412 2413 BspNodeGeometry::BspNodeGeometry(const vector<Plane3> &planes, 2414 const vector<bool> &sides): 2415 mPlanes(planes), mSides(sides) 2416 {} 2417 2418 BspNodeGeometry::~BspNodeGeometry() 2419 { 2420 CLEAR_CONTAINER(mPolys); 2421 } 2422 2423 float BspNodeGeometry::GetArea() const 2424 { 2425 return Polygon3::GetArea(mPolys); 2426 } 2427 2428 BspNodeGeometry *BspNodeGeometry::ConstructChild(const BspTree &tree, 2429 const Plane3 &splitPlane, 2430 const bool side) const 2431 { 2432 BspNodeGeometry *childCell = new BspNodeGeometry(mPlanes, mSides); 2433 2056 2434 // get cross section of new polygon 2057 Polygon3 *planePoly = GetBoundingBox().CrossSection(splitPlane);2435 Polygon3 *planePoly = tree.GetBoundingBox().CrossSection(splitPlane); 2058 2436 2059 2437 // polygon is split by all other planes 2060 for (int i = 0; (i < (int) planes.size()) && planePoly; ++ i)2061 { 2062 const int cf = planePoly->ClassifyPlane( *planes[i]);2438 for (int i = 0; (i < (int)mPlanes.size()) && planePoly; ++ i) 2439 { 2440 const int cf = planePoly->ClassifyPlane(mPlanes[i]); 2063 2441 2064 2442 // split new polygon with all previous planes … … 2072 2450 Polygon3 *backPoly = new Polygon3(); 2073 2451 2074 planePoly->Split( *planes[i], *frontPoly, *backPoly, splitPts);2452 planePoly->Split(mPlanes[i], *frontPoly, *backPoly, splitPts); 2075 2453 DEL_PTR(planePoly); 2076 2454 2077 if( sides[i] == true)2455 if(mSides[i] == true) 2078 2456 { 2079 2457 planePoly = frontPoly; … … 2091 2469 break; 2092 2470 case Polygon3::BACK_SIDE: 2093 if ( sides[i])2471 if (mSides[i]) 2094 2472 DEL_PTR(planePoly); 2095 2473 break; 2096 2474 case Polygon3::FRONT_SIDE: 2097 if (! sides[i])2475 if (!mSides[i]) 2098 2476 DEL_PTR(planePoly); 2099 2477 break; … … 2108 2486 { 2109 2487 //geometry is not changed at all, hence just copy polygons 2110 PolygonContainer::const_iterator it, it_end = cell.end(); 2111 2112 for (it = cell.begin(); it != it_end; ++ it) 2113 childCell.push_back(new Polygon3((*it)->mVertices)); 2114 2115 return false; 2488 PolygonContainer::const_iterator it, it_end = mPolys.end(); 2489 for (it = mPolys.begin(); it != it_end; ++ it) 2490 childCell->mPolys.push_back(new Polygon3((*it)->mVertices)); 2491 2492 return childCell; 2116 2493 } 2117 2494 2118 2495 //-- plane poly splits all other cell polygons 2119 for (int i = 0; i < (int) cell.size(); ++ i)2120 { 2121 const int cf = cell[i]->ClassifyPlane(splitPlane);2496 for (int i = 0; i < (int)mPolys.size(); ++ i) 2497 { 2498 const int cf = mPolys[i]->ClassifyPlane(splitPlane); 2122 2499 2123 2500 // split new polygon with all previous planes … … 2126 2503 case Polygon3::SPLIT: 2127 2504 { 2128 Polygon3 *poly = new Polygon3( cell[i]->mVertices);2505 Polygon3 *poly = new Polygon3(mPolys[i]->mVertices); 2129 2506 2130 2507 Polygon3 *frontPoly = new Polygon3(); … … 2149 2526 DEL_PTR(poly); 2150 2527 else 2151 childCell .push_back(poly);2528 childCell->mPolys.push_back(poly); 2152 2529 } 2153 2530 … … 2155 2532 case Polygon3::BACK_SIDE: 2156 2533 if (!side) 2157 childCell .push_back(new Polygon3(cell[i]->mVertices));2534 childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices)); 2158 2535 break; 2159 2536 case Polygon3::FRONT_SIDE: 2160 2537 if (side) 2161 childCell .push_back(new Polygon3(cell[i]->mVertices));2538 childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices)); 2162 2539 break; 2163 2540 case Polygon3::COINCIDENT: 2164 childCell .push_back(new Polygon3(cell[i]->mVertices));2541 childCell->mPolys.push_back(new Polygon3(mPolys[i]->mVertices)); 2165 2542 break; 2166 2543 default: … … 2171 2548 2172 2549 //-- finally add the new polygon 2173 childCell.push_back(planePoly); 2174 2175 return true; 2176 } 2177 2178 2179 void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 2180 { 2181 stack<BspNode *> tStack; 2182 2183 vector<Plane3 *> planes; 2184 vector<bool> sides; 2185 2186 ExtractSplitPlanes(n, planes, sides); 2187 2188 PolygonContainer candidatePolys; 2189 2190 // bounded planes are added to the polygons 2191 for (int i = 0; i < (int)planes.size(); ++ i) 2192 { 2193 candidatePolys.push_back(GetBoundingBox().CrossSection(*planes[i])); 2194 } 2195 2196 // add faces of bounding box (also could be faces of the cell) 2197 for (int i = 0; i < 6; ++ i) 2198 { 2199 VertexContainer vertices; 2200 2201 for (int j = 0; j < 4; ++ j) 2202 vertices.push_back(mBox.GetFace(i).mVertices[j]); 2203 2204 candidatePolys.push_back(new Polygon3(vertices)); 2205 } 2206 2207 for (int i = 0; i < (int)candidatePolys.size(); ++ i) 2208 { 2209 bool inside = true; 2210 2211 // polygon is split by all other planes 2212 for (int j = 0; (j < planes.size()) && inside; ++ j) 2213 { 2214 Plane3 *plane = planes[j]; 2215 2216 if (i == j) // same plane 2217 continue; 2218 2219 VertexContainer splitPts; 2220 Polygon3 *frontPoly, *backPoly; 2221 2222 const int cf = candidatePolys[i]->ClassifyPlane(*plane); 2223 2224 switch (cf) 2225 { 2226 case Polygon3::SPLIT: 2227 frontPoly = new Polygon3(); 2228 backPoly = new Polygon3(); 2229 2230 candidatePolys[i]->Split(*plane, *frontPoly, 2231 *backPoly, splitPts); 2232 DEL_PTR(candidatePolys[i]); 2233 2234 if(sides[j] == true) 2235 { 2236 candidatePolys[i] = frontPoly; 2237 DEL_PTR(backPoly); 2238 } 2239 else 2240 { 2241 candidatePolys[i] = backPoly; 2242 DEL_PTR(frontPoly); 2243 } 2244 2245 break; 2246 2247 case Polygon3::BACK_SIDE: 2248 if (sides[j]) 2249 inside = false; 2250 break; 2251 case Polygon3::FRONT_SIDE: 2252 if (!sides[j]) 2253 inside = false; 2254 break; 2255 case Polygon3::COINCIDENT: 2256 break; 2257 default: 2258 break; 2259 } 2260 } 2261 2262 if (inside) 2263 cell.push_back(candidatePolys[i]); 2264 else 2265 DEL_PTR(candidatePolys[i]); 2266 } 2267 } 2268 2269 void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const 2270 { 2271 vector<BspLeaf *> leaves = vc->mBspLeaves; 2272 2273 vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 2274 2275 for (it = leaves.begin(); it != it_end; ++ it) 2276 ConstructGeometry(*it, cell); 2277 } 2278 2279 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 2280 const bool onlyUnmailed) const 2281 { 2282 PolygonContainer cell; 2283 2284 ConstructGeometry(n, cell); 2285 2286 stack<BspNode *> nodeStack; 2287 nodeStack.push(mRoot); 2288 2289 // planes needed to verify that we found neighbor leaf. 2290 vector<Plane3 *> planes; 2291 vector<bool> sides; 2292 2293 ExtractSplitPlanes(n, planes, sides); 2294 2295 while (!nodeStack.empty()) 2296 { 2297 BspNode *node = nodeStack.top(); 2298 nodeStack.pop(); 2299 2300 if (node->IsLeaf()) 2301 { 2302 if (node != n && (!onlyUnmailed || !node->Mailed())) 2303 { 2304 // test all planes of current node on neighbour 2305 PolygonContainer neighborCandidate; 2306 ConstructGeometry(node, neighborCandidate); 2307 2308 bool isAdjacent = true; 2309 for (int i = 0; (i < planes.size()) && isAdjacent; ++ i) 2310 { 2311 const int cf = 2312 Polygon3::ClassifyPlane(neighborCandidate, *planes[i]); 2313 2314 if ((cf == Polygon3::BACK_SIDE) && sides[i]) 2315 isAdjacent = false; 2316 else if ((cf == Polygon3::FRONT_SIDE) && !sides[i]) 2317 isAdjacent = false; 2318 } 2319 2320 if (isAdjacent) 2321 neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 2322 2323 CLEAR_CONTAINER(neighborCandidate); 2324 } 2325 } 2326 else 2327 { 2328 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2329 2330 const int cf = Polygon3::ClassifyPlane(cell, interior->mPlane); 2331 2332 if (cf == Polygon3::FRONT_SIDE) 2333 nodeStack.push(interior->mFront); 2334 else 2335 if (cf == Polygon3::BACK_SIDE) 2336 nodeStack.push(interior->mBack); 2337 else 2338 { 2339 // random decision 2340 nodeStack.push(interior->mBack); 2341 nodeStack.push(interior->mFront); 2342 } 2343 } 2344 } 2345 2346 CLEAR_CONTAINER(cell); 2347 return (int)neighbors.size(); 2348 } 2349 2350 BspLeaf *BspTree::GetRandomLeaf(const Plane3 &halfspace) 2351 { 2352 stack<BspNode *> nodeStack; 2353 nodeStack.push(mRoot); 2354 2355 int mask = rand(); 2356 2357 while (!nodeStack.empty()) 2358 { 2359 BspNode *node = nodeStack.top(); 2360 nodeStack.pop(); 2361 2362 if (node->IsLeaf()) 2363 { 2364 return dynamic_cast<BspLeaf *>(node); 2365 } 2366 else 2367 { 2368 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2369 2370 BspNode *next; 2371 2372 PolygonContainer cell; 2373 2374 // todo: not very efficient: constructs full cell everytime 2375 ConstructGeometry(interior, cell); 2376 2377 const int cf = Polygon3::ClassifyPlane(cell, halfspace); 2378 2379 if (cf == Polygon3::BACK_SIDE) 2380 next = interior->mFront; 2381 else 2382 if (cf == Polygon3::FRONT_SIDE) 2383 next = interior->mFront; 2384 else 2385 { 2386 // random decision 2387 if (mask & 1) 2388 next = interior->mBack; 2389 else 2390 next = interior->mFront; 2391 mask = mask >> 1; 2392 } 2393 2394 nodeStack.push(next); 2395 } 2396 } 2397 2398 return NULL; 2399 } 2400 2401 BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 2402 { 2403 stack<BspNode *> nodeStack; 2404 2405 nodeStack.push(mRoot); 2406 2407 int mask = rand(); 2408 2409 while (!nodeStack.empty()) 2410 { 2411 BspNode *node = nodeStack.top(); 2412 nodeStack.pop(); 2413 2414 if (node->IsLeaf()) 2415 { 2416 if ( (!onlyUnmailed || !node->Mailed()) ) 2417 return dynamic_cast<BspLeaf *>(node); 2418 } 2419 else 2420 { 2421 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2422 2423 // random decision 2424 if (mask & 1) 2425 nodeStack.push(interior->mBack); 2426 else 2427 nodeStack.push(interior->mFront); 2428 2429 mask = mask >> 1; 2430 } 2431 } 2432 2433 return NULL; 2434 } 2435 2436 int BspTree::ComputePvsSize(const BoundedRayContainer &rays) const 2437 { 2438 int pvsSize = 0; 2439 2440 BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 2441 2442 Intersectable::NewMail(); 2443 2444 for (rit = rays.begin(); rit != rays.end(); ++ rit) 2445 { 2446 Ray *ray = (*rit)->mRay; 2447 2448 if (!ray->intersections.empty()) 2449 { 2450 if (!ray->intersections[0].mObject->Mailed()) 2451 { 2452 ray->intersections[0].mObject->Mail(); 2453 ++ pvsSize; 2454 } 2455 } 2456 if (!ray->sourceObject.mObject->Mailed()) 2457 { 2458 ray->sourceObject.mObject->Mail(); 2459 ++ pvsSize; 2460 } 2461 } 2462 2463 return pvsSize; 2464 } 2550 childCell->mPolys.push_back(planePoly); 2551 childCell->mPlanes.push_back(splitPlane); 2552 childCell->mSides.push_back(side); 2553 2554 return childCell; 2555 } -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
r384 r390 4 4 #include "Mesh.h" 5 5 #include "Containers.h" 6 #include "Polygon3.h" 6 7 #include <stack> 7 8 … … 11 12 class BspTree; 12 13 class BspInterior; 13 class Polygon3;14 //class Polygon3; 14 15 class AxisAlignedBox3; 15 16 class Ray; 17 18 class BspNodeGeometry 19 { 20 public: 21 BspNodeGeometry() 22 {}; 23 24 BspNodeGeometry(const PolygonContainer &polys, 25 const vector<Plane3> &planes, 26 const vector<bool> &sides); 27 BspNodeGeometry(const vector<Plane3> &planes, 28 const vector<bool> &sides); 29 30 ~BspNodeGeometry(); 31 32 float GetArea() const; 33 34 /** Computes new cell based on the old cell definition and a new split plane 35 @param side indicates which side of the halfspace 36 @returns true if plane contributes to the cell. 37 */ 38 BspNodeGeometry *ConstructChild(const BspTree &tree, 39 const Plane3 &splitPlane, 40 const bool side) const; 41 42 vector<Plane3> mPlanes; 43 vector<bool> mSides; 44 PolygonContainer mPolys; 45 }; 16 46 17 47 /** Data structure used for optimized ray casting. … … 176 206 public: 177 207 BspNode(); 178 virtual ~BspNode() ;208 virtual ~BspNode(){}; 179 209 BspNode(BspInterior *parent); 180 210 … … 192 222 */ 193 223 BspInterior *GetParent(); 224 194 225 /** Sets parent node. 195 226 */ 196 227 void SetParent(BspInterior *parent); 197 228 198 /** Returns pointer to polygons. 199 */ 200 PolygonContainer *GetPolygons(); 201 /** Stores polygons in node or discards them according to storePolys. 202 */ 203 void ProcessPolygons(PolygonContainer *polys, const bool storePolys); 204 229 205 230 static int mailID; 206 231 int mailbox; … … 210 235 bool Mailed() const { return mailbox == mailID; } 211 236 212 //int mViewCellIdx;213 237 protected: 214 238 215 239 /// parent of this node 216 240 BspInterior *mParent; 217 218 /// store polygons created during BSP splits219 PolygonContainer *mPolygons;220 241 }; 221 242 … … 247 268 @param backPolys returns the polygons in the back of the split plane 248 269 @param coincident returns the polygons coincident to the split plane 249 @param storePolys if the polygons should be stored in the node 250 270 251 271 @returns the number of splits 252 272 */ … … 254 274 PolygonContainer &frontPolys, 255 275 PolygonContainer &backPolys, 256 PolygonContainer &coincident, 257 const bool storePolys = false); 258 259 /** Stores polygon in node or discards them according to storePolys. 260 @param polys the polygons 261 @param storePolys if the polygons should be stored or discarded 262 */ 263 void ProcessPolygon(Polygon3 **poly, const bool storePolys); 276 PolygonContainer &coincident); 264 277 265 278 friend ostream &operator<<(ostream &s, const BspInterior &A) … … 337 350 /// rays piercing this node 338 351 BoundedRayContainer *mRays; 339 352 /// area of current node 353 float mArea; 354 BspNodeGeometry *mCell; 355 356 /// pvs size 357 int mPvs; 358 340 359 BspTraversalData(): 341 360 mNode(NULL), … … 343 362 mDepth(0), 344 363 mViewCell(NULL), 345 mRays(NULL) 364 mRays(NULL), 365 mPvs(0), 366 mArea(0.0), 367 mCell(NULL) 346 368 {} 347 369 … … 350 372 const int depth, 351 373 ViewCell *viewCell, 352 BoundedRayContainer *rays): 374 BoundedRayContainer *rays, 375 int pvs, 376 float area, 377 BspNodeGeometry *cell): 353 378 mNode(node), 354 379 mPolygons(polys), 355 380 mDepth(depth), 356 381 mViewCell(viewCell), 357 mRays(rays) 382 mRays(rays), 383 mPvs(pvs), 384 mArea(area), 385 mCell(cell) 358 386 {} 359 387 }; … … 445 473 void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const; 446 474 475 void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const; 476 447 477 /** Returns random leaf of BSP tree. 448 478 @param halfspace defines the halfspace from which the leaf is taken. … … 454 484 */ 455 485 BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false); 456 457 /** Computes new cell based on the old cell definition and a new split plane458 @param side indicates which side of the halfspace459 @returns true if plane contributes to the cell.460 */461 bool ConstructChildGeometry(PolygonContainer &childCell,462 const PolygonContainer &cell,463 const vector<Plane3 *> &planes,464 const vector<bool> &sides,465 const Plane3 &splitPlane,466 const bool side) const;467 468 486 469 487 /** Returns true if merge criteria are reached. … … 530 548 */ 531 549 Plane3 SelectPlane(BspLeaf *leaf, 532 PolygonContainer &polys, 533 const BoundedRayContainer &ray); 550 BspTraversalData &data, 551 BspTraversalData &frontData, 552 BspTraversalData &backData); 534 553 535 554 /** Evaluates the contribution of the candidate split plane. … … 542 561 */ 543 562 float SplitPlaneCost(const Plane3 &candidatePlane, 544 const PolygonContainer &polys, 545 const BoundedRayContainer &rays, 546 const PolygonContainer &cell, 547 const vector<Plane3 *> &plane, 548 const vector<bool> &sides, 549 const int pvsSize) const; 563 BspTraversalData &data, 564 BspTraversalData &frontData, 565 BspTraversalData &backData) const; 550 566 551 567 /** Strategies where the effect of the split plane is tested … … 557 573 558 574 /** Strategies where the effect of the split plane is tested 559 on all input polygons.575 on all input rays. 560 576 561 577 @returns the cost of the candidate split plane 562 578 */ 563 float SplitPlaneCost(const Plane3 &candidatePlane, 579 float SplitPlaneCost(const Plane3 &candidatePlane, 564 580 const BoundedRayContainer &rays, 565 const float frontArea, 566 const float backArea, 567 const int pvsSize) const; 581 const int pvs, 582 const float area, 583 const BspNodeGeometry &cell, 584 BspTraversalData &frontData, 585 BspTraversalData &backData) const; 568 586 569 587 /** Filters next view cell down the tree and inserts it into the appropriate leaves … … 589 607 @returns the root of the subdivision 590 608 */ 591 BspInterior *SubdivideNode(BspLeaf *leaf, 592 PolygonContainer &polys, 593 PolygonContainer &frontPolys, 594 PolygonContainer &backPolys, 595 PolygonContainer &coincident, 596 BoundedRayContainer &rays, 597 BoundedRayContainer &frontRays, 598 BoundedRayContainer &backRays); 609 610 BspInterior *SubdivideNode(BspTraversalData &tData, 611 BspTraversalData &frontData, 612 BspTraversalData &backData, 613 PolygonContainer &coincident); 599 614 600 615 /** Filters polygons down the tree. … … 614 629 @param polygons container of polygons 615 630 @param rays bundle of rays on which the split can be based 616 @param maxPolyCandidates the maximal number of tested polygon candidates617 @param maxRayCandidates the maximal number of ray candidates618 631 */ 619 632 Plane3 SelectPlaneHeuristics(BspLeaf *leaf, 620 PolygonContainer &polys, 621 const BoundedRayContainer &rays, 622 const int maxPolyCandidates, 623 const int maxRayCandidates); 633 BspTraversalData &data, 634 BspTraversalData &frontData, 635 BspTraversalData &backData); 624 636 625 637 /** Extracts the meshes of the objects and adds them to polygons. … … 663 675 @param extractFront if a front view cell is extracted 664 676 */ 665 void ExtractViewCells( ViewCell **backViewCell,666 ViewCell **frontViewCell,677 void ExtractViewCells(BspTraversalData &frontData, 678 BspTraversalData &backData, 667 679 const PolygonContainer &coincident, 668 const Plane3 splitPlane, 669 const bool extractBack, 670 const bool extractFront) const; 680 const Plane3 splitPlane) const; 671 681 672 682 /** Computes best cost ratio for the suface area heuristics for axis aligned … … 723 733 /** Extracts the split planes representing the space bounded by node n. 724 734 */ 725 void ExtractSplitPlanes(BspNode *n, vector<Plane3 *> &planes, vector<bool> &sides) const;735 void ExtractSplitPlanes(BspNode *n, vector<Plane3> &planes, vector<bool> &sides) const; 726 736 727 737 /** Computes the pvs of the front and back leaf with a given classification. 728 738 */ 729 739 void AddToPvs(Intersectable &obj, 730 float &frontPvs,731 float &backPvs,732 733 734 735 740 int &frontPvs, 741 int &backPvs, 742 const int cf, 743 const int frontId, 744 const int backId, 745 const int frontAndBackId) const; 736 746 737 747 int ComputePvsSize(const BoundedRayContainer &rays) const; … … 779 789 /// maximal possible depth 780 790 static int sTermMaxDepth; 791 /// mininam pvs 792 static int sTermMinPvs; 781 793 /// strategy to get the best split plane 782 794 static int sSplitPlaneStrategy; … … 809 821 static float sPvsFactor; 810 822 811 /// if polygons should be stored in the tree812 static bool sStoreSplitPolys;813 814 823 //-- thresholds used for view cells are merging 815 824 static int sMinPvsDif; -
trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
r386 r390 547 547 SetFilled(); 548 548 549 //ViewCellContainer foundViewCells;550 551 if (BspTree::sStoreSplitPolys)552 {553 while (!tStack.empty())554 {555 BspNode *node = tStack.top();556 557 tStack.pop();558 559 PolygonContainer::const_iterator it;560 PolygonContainer::const_iterator it_end = node->GetPolygons()->end();561 562 for (it = node->GetPolygons()->begin(); it != it_end; ++ it)563 ExportPolygon(*it);564 565 if (!node->IsLeaf())566 {567 BspInterior *interior = dynamic_cast<BspInterior *>(node);568 569 tStack.push(interior->GetFront());570 tStack.push(interior->GetBack());571 572 }573 }574 }575 549 // export view cells 576 550 ExportBspViewCellPartition(tree);
Note: See TracChangeset
for help on using the changeset viewer.