- Timestamp:
- 11/01/05 02:37:51 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
r361 r362 9 9 # filename vienna.x3d 10 10 # filename ../data/vienna/vienna-simple.x3d 11 filename ../data/vienna/vienna-buildings.x3d11 # filename ../data/vienna/vienna-buildings.x3d 12 12 # filename ../data/vienna/viewcells-25-sel.x3d 13 #filename ../data/atlanta/atlanta2.x3d13 filename ../data/atlanta/atlanta2.x3d 14 14 # filename ../data/soda/soda.dat 15 15 # filename ../data/soda/soda5.dat … … 56 56 57 57 Sampling { 58 totalSamples 20000 59 samplesPerPass 258 totalSamples 200000 59 samplesPerPass 3 60 60 } 61 61 … … 68 68 maxViewCells 0 69 69 70 minPvsDif 10 71 70 72 # filename ../data/atlanta/atlanta_viewcells_large.x3d 71 73 filename ../data/vienna/viewcells-25-sel.x3d … … 76 78 BspTree { 77 79 Construction { 78 #input fromRays79 input fromViewCells80 input fromRays 81 # input fromViewCells 80 82 # input fromSceneGeometry 81 samples 1 500083 samples 100000 82 84 sideTolerance 0.005 83 85 } … … 116 118 #splitPlaneStrategy 130 117 119 118 splitPlaneStrategy 66120 splitPlaneStrategy 130 119 121 120 122 maxCandidates 80 … … 122 124 Termination { 123 125 # autopartition 124 maxRays -1126 maxRays 80 125 127 maxPolygons 0 126 128 maxDepth 100 127 129 128 130 # axis aligned splits 129 maxPolysForAxisAligned 400 130 maxCostRatio 0.9 131 ct_div_ci 0.5 131 AxisAligned { 132 maxPolys 500 133 maxRays 300 134 maxObjects 20 135 maxCostRatio 0.9 136 ct_div_ci 0.5 137 } 132 138 } 133 139 134 #axis aligned split 135 splitBorder 0.01 136 140 AxisAligned { 141 splitBorder 0.01 142 } 143 137 144 # if split polys are stored for visualization 138 145 storeSplitPolys false -
trunk/VUT/GtpVisibilityPreprocessor/src/Camera.cpp
r263 r362 102 102 int k =0; 103 103 for (int j=0; j < rays.size(); j++) 104 if (rays[j]. leaves.size()) {104 if (rays[j].kdLeaves.size()) { 105 105 Ray *ray = &(rays[j]); 106 106 int i; 107 107 if (1) 108 for (i= 0; i < ray-> leaves.size(); i++)109 exporter->ExportBox(tree->GetBox(ray-> leaves[i]));108 for (i= 0; i < ray->kdLeaves.size(); i++) 109 exporter->ExportBox(tree->GetBox(ray->kdLeaves[i])); 110 110 if (0) 111 111 for (i= 0; i < ray->meshes.size(); i++) … … 130 130 131 131 ray.intersections.clear(); 132 ray. leaves.clear();132 ray.kdLeaves.clear(); 133 133 ray.meshes.clear(); 134 134 ray.bspLeaves.clear(); 135 135 136 ray.Init(mPosition, target, Ray::LOCAL_RAY); 136 137 -
trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
r332 r362 1147 1147 RegisterOption("Sampling.samplesPerPass", 1148 1148 optInt, 1149 "- total_samples=",1149 "-samples_per_pass=", 1150 1150 "10"); 1151 1151 … … 1155 1155 "bspTree"); 1156 1156 1157 RegisterOption("ViewCells.minPvsDif", 1158 optString, 1159 "-view_cells_min_pvs_dif", 1160 "10"); 1161 1157 1162 RegisterOption("ViewCells.filename", 1158 1163 optString, … … 1190 1195 "-1"); 1191 1196 1192 RegisterOption("BspTree.Termination.maxPolysForAxisAligned", 1197 RegisterOption("BspTree.Termination.AxisAligned.maxCostRatio", 1198 optFloat, 1199 "-bsp_term_max_cost_ratio=", 1200 "1.5"); 1201 1202 RegisterOption("BspTree.Termination.AxisAligned.ct_div_ci", 1203 optFloat, 1204 "-bsp_term_ct_div_ci=", 1205 "1.0"); 1206 1207 RegisterOption("BspTree.AxisAligned.splitBorder", 1208 optFloat, 1209 "-bsp_split_border=", 1210 "0.1"); 1211 1212 RegisterOption("BspTree.Termination.AxisAligned.maxPolys", 1193 1213 optInt, 1194 1214 "-bsp_term_max_polygons=", 1195 1215 "50"); 1216 1217 RegisterOption("BspTree.Termination.AxisAligned.maxObjects", 1218 optInt, 1219 "-bsp_term_max_objects=", 1220 "3"); 1221 1222 RegisterOption("BspTree.Termination.AxisAligned.maxRays", 1223 optInt, 1224 "-bsp_term_max_rays=", 1225 "-1"); 1196 1226 1197 1227 RegisterOption("BspTree.Termination.maxDepth", … … 1199 1229 "-bsp_term_max_depth=", 1200 1230 "100"); 1201 1202 RegisterOption("BspTree.Termination.maxCostRatio",1203 optFloat,1204 "-bsp_term_max_cost_ratio=",1205 "1.5");1206 1207 RegisterOption("BspTree.Termination.ct_div_ci",1208 optFloat,1209 "-bsp_term_ct_div_ci=",1210 "1.0");1211 1212 RegisterOption("BspTree.splitBorder",1213 optFloat,1214 "-bsp_split_border=",1215 "0.1");1216 1231 1217 1232 RegisterOption("BspTree.storeSplitPolys", -
trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h
r360 r362 16 16 class Intersectable; 17 17 class BspLeaf; 18 class Polygon3; 18 19 19 20 class Exporter … … 74 75 ExportLeavesGeometry(const BspTree &tree, const vector<BspLeaf *> &leaves) = 0; 75 76 77 virtual void 78 ExportPolygons(const PolygonContainer &polys) = 0; 79 76 80 void SetExportRayDensity(const bool d) { mExportRayDensity = d; } 77 81 -
trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp
r354 r362 572 572 // compute intersection with all objects in this leaf 573 573 KdLeaf *leaf = (KdLeaf *) node; 574 ray. leaves.push_back(leaf);574 ray.kdLeaves.push_back(leaf); 575 575 576 576 ObjectContainer::const_iterator mi; -
trunk/VUT/GtpVisibilityPreprocessor/src/Plane3.h
r349 r362 55 55 } 56 56 57 if (coplanar) (*coplanar) = false; 57 58 float u = - Distance(a) / dv; // TODO: could be done more efficiently 58 59 59 if (coplanar) (*coplanar) = false;60 60 if (t) (*t) = u; 61 61 62 //Debug << "t: " << u << ", b - a: " << v << ", norm: " << mNormal << ", dist(a): " << - Distance(a) << ", dv: " << dv << endl;63 //return a - Distance(a) * b / dv + Distance(a) * a / dv; // NOTE: gives better precision than calclulating a + u * v64 62 return a + u * v; 65 63 } 66 64 65 float FindT(const Vector3 &a, 66 const Vector3 &b) const 67 { 68 const Vector3 v = b - a; // line from A to B 69 const float dv = DotProd(v, mNormal); 70 71 if (signum(dv) == 0) 72 return 1; 73 74 return - Distance(a) / dv; // TODO: could be done more efficiently 75 } 76 67 77 friend bool 68 78 PlaneIntersection(const Plane3 &a, const Plane3 &b, const Plane3 &c, Vector3 &result); -
trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
r361 r362 147 147 for (it = mVertices.begin(); it != mVertices.end(); ++ it) 148 148 { 149 int side = plane.Side(*it, Vector3::sDistTolerance);149 const int side = plane.Side(*it, Vector3::sDistTolerance); 150 150 151 151 if (side > 0) … … 395 395 if ((cf == SPLIT) || (cf == COINCIDENT) || (onFrontSide && onBackSide)) 396 396 { 397 Debug << "here" << endl;398 397 return SPLIT; 399 398 } … … 411 410 return SPLIT; 412 411 } 412 413 int Polygon3::CountIntersectables(const PolygonContainer &polys) 414 { 415 int count = 0; 416 417 PolygonContainer::const_iterator it, it_end = polys.end(); 418 419 MeshInstance::NewMail(); 420 421 for (it = polys.begin(); it != it_end; ++ it) 422 { 423 if ((*it)->mParent && !(*it)->mParent->Mailed()) 424 { 425 ++ count; 426 (*it)->mParent->Mail(); 427 } 428 } 429 return count; 430 } -
trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h
r360 r362 118 118 void InheritRays(Polygon3 &front_piece, 119 119 Polygon3 &back_piece) const; 120 121 122 /** Counts the number of different intersectables associated with the polygons. 123 */ 124 static int CountIntersectables(const PolygonContainer &polys); 120 125 }; 121 126 -
trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
r350 r362 37 37 int GetSize() {return (int)mEntries.size();} 38 38 bool Empty() {return mEntries.size() == 0;} 39 /** Merges pvs of a and pvs of b into this pvs. 40 */ 39 41 void Merge(const Pvs<T> &a, const Pvs<T> &b); 42 /** Difference of pvs to pvs b. 43 @returns number of different entries. 44 */ 45 int Diff(const Pvs<T> &b); 40 46 41 47 PvsData<T> *Find(T sample); 42 48 int AddSample(T sample); 43 49 44 void GetData(const int index, 45 T &entry, 46 PvsData<T> &data); 50 void GetData(const int index, T &entry, PvsData<T> &data); 47 51 std::map<T, PvsData<T>, LtSample<T> > mEntries; 48 52 }; 49 53 50 54 template <typename T> 55 int Pvs<T>::Diff(const Pvs<T> &b) 56 { 57 int dif = 0; 58 59 std::map<T, PvsData<T>, LtSample<T> >::const_iterator it; 60 61 for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it) 62 { 63 PvsData<T> *data = Find((*it).first); 64 if (!data) ++ dif; 65 } 66 67 return dif; 68 } 69 70 template <typename T> 51 71 void Pvs<T>::Merge(const Pvs<T> &a, const Pvs<T> &b) 52 72 { 53 //std::merge(a.mEntries.begin(), a.mEntries.end(), 54 // b.mEntries.begin(), b.mEntries.end(), mEntries.begin()); 73 std::map<T, PvsData<T>, LtSample<T> >::const_iterator it; 74 75 // todo: copy all elements instead of inserting 76 for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it) 77 { 78 mEntries.insert(*it); 79 } 80 81 for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it) 82 { 83 PvsData<T> *data = Find((*it).first); 84 85 if (data) 86 data->mVisibleSamples += (*it).second.mVisibleSamples; 87 else 88 mEntries.insert(*it); 89 } 55 90 } 91 56 92 57 93 template <typename T> -
trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp
r349 r362 168 168 const int extSide = plane.Side(extp); 169 169 170 if ( (entSide == 0) && (extSide == 0))170 if (entSide < 0) 171 171 { 172 return COINCIDENT;173 }174 else if ((entSide <= 0) && (extSide <= 0))175 {172 if (extSide >= 0) 173 { 174 return BACK_FRONT; 175 } 176 176 return BACK; 177 177 } 178 else if ( (entSide >= 0) && (extSide >= 0))178 else if (entSide > 0) 179 179 { 180 if (extSide <= 0) 181 return FRONT_BACK; 182 180 183 return FRONT; 181 184 } 182 else if ((entSide <= 0) && (extSide >= 0)) 183 return BACK_FRONT; 185 else if (entSide == 0) 186 { 187 if (extSide > 0) 188 return BACK_FRONT; 189 else if (extSide < 0) 190 return FRONT_BACK; 191 } 184 192 185 return FRONT_BACK;193 return COINCIDENT; 186 194 } 187 195 -
trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h
r350 r362 12 12 class MeshInstance; 13 13 class ViewCell; 14 class BspLeaf; 14 15 15 16 // ------------------------------------------------------------------- … … 61 62 62 63 vector<Intersection> intersections; 63 vector<KdLeaf *> leaves;64 vector<KdLeaf *> kdLeaves; 64 65 vector<MeshInstance *> meshes; 65 vector< ViewCell *> viewCells;66 vector<BspLeaf *> bspLeaves; 66 67 67 68 // constructors -
trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
r361 r362 32 32 { 33 33 ray.intersections.clear(); 34 ray. leaves.clear();34 ray.kdLeaves.clear(); 35 35 ray.meshes.clear(); 36 ray. viewCells.clear();36 ray.bspLeaves.clear(); 37 37 38 38 // cout<<point<<" "<<direction<<endl; … … 68 68 mSceneGraph->CollectObjects(&objects); 69 69 mBspTree->Construct(objects); 70 71 mBspTree->CollectViewCells(mViewCells);72 70 break; 73 71 case BspTree::FROM_RAYS: … … 75 73 mBspTree->SetGenerateViewCells(true); 76 74 mBspTree->Construct(mSampleRays); 77 78 mBspTree->CollectViewCells(mViewCells);79 75 break; 80 76 default: … … 94 90 int contributingSamples = 0; 95 91 int j; 96 for (j=0; j < ray. leaves.size(); j++) {97 KdNode *node = GetNodeForPvs( ray. leaves[j] );92 for (j=0; j < ray.kdLeaves.size(); j++) { 93 KdNode *node = GetNodeForPvs( ray.kdLeaves[j] ); 98 94 contributingSamples += object->mKdPvs.AddSample(node); 99 95 } 100 96 101 97 if (mPass > 10) 102 for (j=1; j < ((int)ray. leaves.size() - 1); j++) {103 ray. leaves[j]->AddPassingRay(ray, contributingSamples ? 1 : 0);98 for (j=1; j < ((int)ray.kdLeaves.size() - 1); j++) { 99 ray.kdLeaves[j]->AddPassingRay(ray, contributingSamples ? 1 : 0); 104 100 } 105 101 … … 114 110 115 111 // object can be seen from the view cell => add to view cell pvs 116 for (j=0; j < ray. viewCells.size(); ++ j)112 for (j=0; j < ray.bspLeaves.size(); ++ j) 117 113 { // if ray not in unbounded space 118 if (ray.viewCells[j] != &mUnbounded) 119 contributingSamples += ray.viewCells[j]->GetPvs().AddSample(obj); 114 if (ray.bspLeaves[j]->GetViewCell() != &mUnbounded) 115 contributingSamples += 116 ray.bspLeaves[j]->GetViewCell()->GetPvs().AddSample(obj); 120 117 } 121 118 122 119 // rays passing through this viewcell 123 120 if (mPass > 1) 124 for (j=1; j < ((int)ray.viewCells.size() - 1); ++ j) 125 { 126 if (ray.viewCells[j] != &mUnbounded) 127 ray.viewCells[j]->AddPassingRay(ray, contributingSamples ? 1 : 0); 121 for (j=1; j < ((int)ray.bspLeaves.size() - 1); ++ j) 122 { 123 if (ray.bspLeaves[j]->GetViewCell() != &mUnbounded) 124 ray.bspLeaves[j]->GetViewCell()-> 125 AddPassingRay(ray, contributingSamples ? 1 : 0); 128 126 } 129 127 … … 183 181 else 184 182 { 185 if (ray. leaves.size()) {183 if (ray.kdLeaves.size()) { 186 184 if (!reverseRay) 187 185 sampleContributions += AddNodeSamples(object, ray); … … 372 370 373 371 vector<Ray> rays[10]; 374 375 vector<Ray> vcRays[5];376 ViewCellContainer pvsViewCells;377 vector<Ray> viewCellRays; // used for BSP tree construction378 372 379 373 while (totalSamples < mTotalSamples) { … … 462 456 } 463 457 //------------------- 464 465 458 if (mViewCellsType == BSP_VIEW_CELLS) 466 459 { 467 // save rays for bsp tree construction 468 if (collectSamplesForBsp) 469 { 470 // also add origin to sample in order to extract it as input polygons 471 MeshInstance *mi = dynamic_cast<MeshInstance *>(object); 472 ray.sourceObject = Ray::Intersection(0.0, mi, faceIndex); 473 474 mSampleRays.push_back(new Ray(ray)); 475 } 476 else 477 { 478 // construct BSP tree using the samples 479 if (!mBspTree) 480 { 481 BuildBspTree(); 482 483 cout << "generated " << (int)mViewCells.size() << " view cells" << endl; 484 485 passContributingSamples += mBspTree->GetStat().contributingSamples; 486 passSampleContributions += mBspTree->GetStat().sampleContributions; 487 488 BspTreeStatistics(Debug); 489 Export("vc_bsptree.x3d", false, false, true); 490 } 491 492 // some random view cells for output 493 if (pvsViewCells.empty()) 494 { 495 int vcPvsOut = Min((int)mViewCells.size(), 5); 496 497 for (int j = 0; j < vcPvsOut; ++ j) 498 { 499 int idx = Random((int)mViewCells.size()); 500 Debug << "output view cell=" << idx << endl; 501 pvsViewCells.push_back(mViewCells[Random((int)mViewCells.size())]); 502 } 503 } 504 else 505 { 506 // check whether we can add the current ray to the rays 507 for (int k = 0; k < (int)ray.viewCells.size(); ++ k) 508 for (int j = 0; j < (int)pvsViewCells.size(); ++ j) 509 if (pvsViewCells[j] == ray.viewCells[k]) 510 vcRays[j].push_back(ray); 511 } 512 } 460 ProcessBspViewCells(collectSamplesForBsp, 461 ray, 462 object, 463 faceIndex, 464 passContributingSamples, 465 passSampleContributions); 513 466 } 514 515 467 } 516 468 } else { … … 580 532 cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl; 581 533 534 // merge or subdivide view cells 535 if (mBspTree) 536 { 537 int merged = PostprocessViewCells(mSampleRays); 538 Debug << "merged " << merged << " view cells" << endl; 539 540 ViewCellContainer vc; 541 mBspTree->CollectViewCells(vc); 542 543 ViewCellContainer::const_iterator it, it_end = vc.end(); 544 545 int mergedPvs = 0; 546 for (it = vc.begin(); it != it_end; ++ it) 547 mergedPvs += (*it)->GetPvs().GetSize(); 548 549 Debug << "merged pvs size: " << mergedPvs << endl; 550 551 } 552 582 553 // HoleSamplingPass(); 583 if (0) { 584 Exporter *exporter = Exporter::GetExporter("ray-density.x3d"); 585 exporter->SetExportRayDensity(true); 586 exporter->ExportKdTree(*mKdTree); 587 554 if (0) { 555 Exporter *exporter = Exporter::GetExporter("ray-density.x3d"); 556 exporter->SetExportRayDensity(true); 557 exporter->ExportKdTree(*mKdTree); 558 559 if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS)) 560 exporter->ExportBspTree(*mBspTree); 561 562 delete exporter; 563 } 564 565 bool exportRays = false; 566 if (exportRays) { 567 Exporter *exporter = NULL; 568 exporter = Exporter::GetExporter("sample-rays.x3d"); 569 exporter->SetWireframe(); 570 exporter->ExportKdTree(*mKdTree); 571 exporter->ExportBspTree(*mBspTree); 572 573 for (i=0; i < pvsOut; i++) 574 exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0)); 575 exporter->SetFilled(); 576 577 delete exporter; 578 } 579 580 //-- several visualizations and statistics 581 if (1) { 588 582 if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS)) 589 exporter->ExportBspTree(*mBspTree); 590 591 delete exporter; 592 } 593 594 bool exportRays = false; 595 if (exportRays) { 596 Exporter *exporter = NULL; 597 exporter = Exporter::GetExporter("sample-rays.x3d"); 598 exporter->SetWireframe(); 599 exporter->ExportKdTree(*mKdTree); 600 exporter->ExportBspTree(*mBspTree); 601 602 for (i=0; i < pvsOut; i++) 603 exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0)); 604 exporter->SetFilled(); 605 606 delete exporter; 607 } 608 609 //-- several visualizations and statistics 610 if (1) { 611 if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS)) 612 { 613 bool exportSplits = false; 614 environment->GetBoolValue("BspTree.exportSplits", exportSplits); 615 616 // export the bsp splits 617 if (exportSplits) 618 ExportSplits(objects); 619 620 Exporter *exporter = Exporter::GetExporter("viewCells.x3d"); 621 622 // export leaves 623 if (0 && exporter) 624 { 625 vector<BspLeaf *> leaves; 626 mBspTree->CollectLeaves(leaves); 627 vector<BspLeaf *> randLeaves; 628 vector<BspLeaf *> neighbors; 629 630 for (int k = 0; k < 1; ++ k) 631 { 632 BspLeaf *leaf = leaves[Random((int)leaves.size())]; 633 randLeaves.push_back(leaf); 634 mBspTree->FindNeighbors(leaf, neighbors, false); 635 } 636 637 exporter->ExportLeavesGeometry(*mBspTree, randLeaves); 638 exporter->SetWireframe(); 639 exporter->ExportLeavesGeometry(*mBspTree, neighbors); 640 641 delete exporter; 642 } 643 644 vector<BspLeaf *> leaves; 645 mBspTree->CollectLeaves(leaves); 646 647 for (int k = 0; k < 100; ++ k) 648 { 649 vector<BspLeaf *> randLeaves; 650 vector<BspLeaf *> neighbors; 651 652 char s[64]; sprintf(s, "bsp-vc%04d.x3d", k); 653 Exporter *exporter = Exporter::GetExporter(s); 654 655 BspLeaf *leaf = leaves[Random((int)leaves.size())]; 656 Debug << "\noutput leaf " << k << endl; 657 randLeaves.push_back(leaf); 658 mBspTree->FindNeighbors(leaf, neighbors, false); 659 660 exporter->ExportLeavesGeometry(*mBspTree, randLeaves); 661 exporter->SetWireframe(); 662 exporter->ExportLeavesGeometry(*mBspTree, neighbors); 663 664 delete exporter; 665 } 666 667 for (int j = 0; j < pvsViewCells.size(); ++ j) 668 { 669 ViewCell *vc = pvsViewCells[j]; 670 671 Intersectable::NewMail(); 672 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", j); 673 674 Exporter *exporter = Exporter::GetExporter(s); 675 exporter->SetFilled(); 676 677 ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 678 679 Material m;//= RandomMaterial(); 680 m.mDiffuseColor = RgbColor(0, 1, 0); 681 exporter->SetForcedMaterial(m); 682 683 exporter->ExportViewCell(vc); 684 685 Debug << j << ": pvs size=" << (int)vc->GetPvs().GetSize() 686 << ", piercing rays=" << (int)vcRays[j].size() << endl; 687 688 exporter->SetWireframe(); 689 690 // export view cells 691 m.mDiffuseColor = RgbColor(1, 0, 1); 692 exporter->SetForcedMaterial(m); 693 exporter->ExportViewCells(mViewCells); 694 695 // export rays piercing this view cell 696 exporter->ExportRays(vcRays[j], 1000, RgbColor(0, 1, 0)); 697 698 m.mDiffuseColor = RgbColor(1, 0, 0); 699 exporter->SetForcedMaterial(m); 700 701 // output PVS of view cell 702 for (; it != vc->GetPvs().mEntries.end(); ++ it) 703 { 704 Intersectable *intersect = (*it).first; 705 if (!intersect->Mailed()) 706 { 707 exporter->ExportIntersectable(intersect); 708 intersect->Mail(); 709 } 710 } 711 712 // output rest of the objects 713 if (0) 714 { 715 Material m;//= RandomMaterial(); 716 m.mDiffuseColor = RgbColor(0, 0, 1); 717 exporter->SetForcedMaterial(m); 718 719 for (int j = 0; j < objects.size(); ++ j) 720 if (!objects[j]->Mailed()) 721 { 722 //if (j == 2198)m.mDiffuseColor = RgbColor(1, 0, 1); 723 //else m.mDiffuseColor = RgbColor(1, 1, 0); 724 exporter->SetForcedMaterial(m); 725 exporter->ExportIntersectable(objects[j]); 726 objects[j]->Mail(); 727 } 728 } 729 DEL_PTR(exporter); 730 } 731 } 732 583 { 584 bool exportSplits = false; 585 environment->GetBoolValue("BspTree.exportSplits", exportSplits); 586 587 // export the bsp splits 588 if (exportSplits) 589 ExportSplits(objects); 590 591 ExportBspPvs(objects); 592 } 733 593 for (int k=0; k < pvsOut; k++) { 734 594 Intersectable *object = objects[k]; … … 772 632 } 773 633 634 bool SamplingPreprocessor::ProcessBspViewCells(bool collectSamplesForBsp, 635 Ray &ray, 636 Intersectable *object, 637 int faceIndex, 638 int &contributingSamples, 639 int &sampleContributions) 640 { 641 // save rays for bsp tree construction 642 if (collectSamplesForBsp) 643 { 644 // also add origin to sample in order to extract it as input polygons 645 MeshInstance *mi = dynamic_cast<MeshInstance *>(object); 646 ray.sourceObject = Ray::Intersection(0.0, mi, faceIndex); 647 648 mSampleRays.push_back(new Ray(ray)); 649 650 return false; 651 } 652 653 // construct BSP tree using the samples 654 if (!mBspTree) 655 { 656 BuildBspTree(); 657 658 contributingSamples += mBspTree->GetStat().contributingSamples; 659 sampleContributions += mBspTree->GetStat().sampleContributions; 660 661 BspTreeStatistics(Debug); 662 if (0) Export("vc_bsptree.x3d", false, false, true); 663 } 664 665 return true; 666 } 667 668 // merge or subdivide view cells 669 int SamplingPreprocessor::PostprocessViewCells(const RayContainer &rays) 670 { 671 int merged = 0; 672 RayContainer::const_iterator rit, rit_end = rays.end(); 673 vector<BspLeaf *>::const_iterator lit; 674 if (0) 675 for (rit = rays.begin(); rit != rays.end(); ++ rit) 676 { 677 // traverse leaves stored in the rays and compare and merge consecutive 678 // leaves (i.e., the neighbors in the tree) 679 lit = (*rit)->bspLeaves.begin(); 680 681 BspLeaf *previousLeaf = *lit; 682 ++ lit; 683 684 for (; lit != (*rit)->bspLeaves.end(); ++ lit) 685 { 686 BspLeaf *leaf = *lit; 687 if (mBspTree->ShouldMerge(leaf, previousLeaf)) 688 { 689 mBspTree->MergeViewCells(leaf, previousLeaf); 690 ++ merged; 691 } 692 previousLeaf = leaf; 693 } 694 } 695 return merged; 696 } 774 697 775 698 void SamplingPreprocessor::ExportSplits(const ObjectContainer &objects) … … 829 752 } 830 753 } 754 755 void SamplingPreprocessor::ExportBspPvs(const ObjectContainer &objects) 756 { 757 //-- some random view cells and rays for output 758 const int leafOut = 10; 759 760 vector<Ray> vcRays[leafOut]; 761 vector<BspLeaf *> bspLeaves; 762 763 for (int i = 0; i < leafOut; ++ i) 764 bspLeaves.push_back(mBspTree->GetRandomLeaf()); 765 766 const int raysOut = min((int)mSampleRays.size(), 20000); 767 768 // check whether we can add the current ray to the output rays 769 for (int k = 0; k < raysOut; ++ k) 770 { 771 Ray *ray = mSampleRays[k]; 772 773 for (int j = 0; j < (int)ray->bspLeaves.size(); ++ j) 774 { 775 for (int i = 0; i < (int)bspLeaves.size(); ++ i) 776 { 777 if (bspLeaves[i] == ray->bspLeaves[j]) 778 { 779 vcRays[i].push_back(*ray); 780 } 781 } 782 } 783 } 784 785 ViewCell::NewMail(); 786 787 for (int i = 0; i < bspLeaves.size(); ++ i) 788 { 789 Intersectable::NewMail(); 790 791 ViewCell *vc = bspLeaves[i]->GetViewCell(); 792 793 //bspLeaves[j]->Mail(); 794 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 795 796 Exporter *exporter = Exporter::GetExporter(s); 797 exporter->SetFilled(); 798 799 ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); 800 801 Material m;//= RandomMaterial(); 802 m.mDiffuseColor = RgbColor(0, 1, 0); 803 exporter->SetForcedMaterial(m); 804 805 exporter->SetWireframe(); 806 807 if (vc->GetMesh()) 808 exporter->ExportViewCell(vc); 809 else 810 { 811 PolygonContainer cell; 812 813 mBspTree->ConstructGeometry(bspLeaves[i], cell); 814 exporter->ExportPolygons(cell); 815 CLEAR_CONTAINER(cell); 816 817 /*vector<BspLeaf *> neighbors; 818 mBspTree->FindNeighbors(bspLeaves[j], neighbors); 819 for (int j = 0; j < (int)neighbors.size(); ++ j) 820 { if (neighbors[j]->mViewCell == bspLeaves[j]->mViewCell) 821 {}}*/ 822 } 823 824 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 825 << ", piercing rays=" << (int)vcRays[i].size() << endl; 826 827 // export view cells 828 if (0) 829 { 830 m.mDiffuseColor = RgbColor(1, 0, 1); 831 exporter->SetForcedMaterial(m); 832 exporter->ExportViewCells(mViewCells); 833 } 834 835 // export rays piercing this view cell 836 exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0)); 837 838 m.mDiffuseColor = RgbColor(1, 0, 0); 839 exporter->SetForcedMaterial(m); 840 841 // output PVS of view cell 842 for (; it != vc->GetPvs().mEntries.end(); ++ it) 843 { 844 Intersectable *intersect = (*it).first; 845 if (!intersect->Mailed()) 846 { 847 exporter->ExportIntersectable(intersect); 848 intersect->Mail(); 849 } 850 } 851 852 // output rest of the objects 853 if (0) 854 { 855 Material m;//= RandomMaterial(); 856 m.mDiffuseColor = RgbColor(0, 0, 1); 857 exporter->SetForcedMaterial(m); 858 859 for (int j = 0; j < objects.size(); ++ j) 860 if (!objects[j]->Mailed()) 861 { 862 //if (j == 2198)m.mDiffuseColor = RgbColor(1, 0, 1); 863 //else m.mDiffuseColor = RgbColor(1, 1, 0); 864 exporter->SetForcedMaterial(m); 865 exporter->ExportIntersectable(objects[j]); 866 objects[j]->Mail(); 867 } 868 } 869 DEL_PTR(exporter); 870 } 871 } -
trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
r354 r362 64 64 ); 65 65 66 /** Adds objects samples to view cells. 66 /** Processes the BSP based view cells during a pass. 67 @param collectSamplesForBps if still in sample collection phase 68 @param ray the current ray 69 @param object the currently processed object 70 @param faceIndex the sampled face of the object 71 @param contributingSamples samples contributing to pvs 72 @param sampleContributions contribution of the samples 73 74 @returns true if BSP tree has been constructed, false if not yet 75 76 */ 77 bool ProcessBspViewCells(bool collectSamplesForBsp, 78 Ray &ray, 79 Intersectable *object, 80 int faceIndex, 81 int &contributingSamples, 82 int &sampleContributions); 83 84 /** Adds objects samples to bsp view cells. 67 85 */ 68 86 int AddObjectSamples(Intersectable *obj, const Ray &ray); … … 71 89 72 90 void ExportSplits(const ObjectContainer &objects); 91 92 void ExportBspPvs(const ObjectContainer &objects); 93 94 /** Post processes view cells (i.e., merges or subdivides view cells based 95 on the PVS and the ray sets. 96 @returns number of merged view cells. 97 */ 98 int PostprocessViewCells(const RayContainer &rays); 99 73 100 }; 74 101 -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
r359 r362 81 81 } 82 82 83 ViewCell *ViewCell::Merge ViewCells(const ViewCell &front, constViewCell &back)83 ViewCell *ViewCell::Merge(ViewCell &front, ViewCell &back) 84 84 { 85 /*stable_sort(front.mPiercingRays.begin(), front.mPiercingRays.end()); 85 ViewCell *vc = new ViewCell(); 86 // merge pvs 87 vc->mPvs.Merge(front.mPvs, back.mPvs); 88 89 // merge ray sets 90 stable_sort(front.mPiercingRays.begin(), front.mPiercingRays.end()); 86 91 stable_sort(back.mPiercingRays.begin(), back.mPiercingRays.end()); 87 92 88 ViewCell *vc = front.Merge(back); 93 std::merge(front.mPiercingRays.begin(), front.mPiercingRays.end(), 94 back.mPiercingRays.begin(), back.mPiercingRays.end(), 95 vc->mPiercingRays.begin()); 89 96 90 if (vc) 91 return vc; 92 93 return back.Merge(front);*/return NULL; 97 return vc; 94 98 } 95 96 ViewCell *ViewCell::Merge(const ViewCell &other) const97 {98 //-- compute set differences99 const float minDif = 10;100 101 RayContainer diff;102 103 set_difference(mPiercingRays.begin(), mPiercingRays.end(),104 other.mPiercingRays.begin(), other.mPiercingRays.end(),105 diff.begin());106 107 if (diff.size() < minDif)108 {109 ViewCell *vc = new ViewCell();110 111 RayContainer::const_iterator it, it_end = other.mPiercingRays.end();112 113 for (it = other.mPiercingRays.begin(); it != it_end; ++ it)114 vc->mPiercingRays.push_back(*it);115 116 while (!diff.empty())117 {118 vc->mPiercingRays.push_back(diff.back());119 diff.pop_back();120 }121 122 return vc;123 }124 125 return NULL;126 }127 128 99 129 100 void ViewCell::AddPassingRay(const Ray &ray, const int contributions) -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
r352 r362 48 48 static ViewCell *ExtrudeViewCell(const Triangle3 &baseTri, const float height); 49 49 50 /** Merges two view cells based on some criteria 51 @returns new view cell if merge was success. NULL if merge failed. 50 /** Merges two view cells. 51 @note the piercing rays of the front and back will be ordered 52 @returns new view cell based on the merging. 52 53 */ 53 static ViewCell *Merge ViewCells(const ViewCell &front, constViewCell &back);54 static ViewCell *Merge(ViewCell &front, ViewCell &back); 54 55 55 56 … … 61 62 62 63 protected: 63 64 /** Merges view cell with other view cell if certain criteria are met.65 @note because of performance issues the precondition is that the piercing rays are ordered.66 */67 ViewCell *Merge(const ViewCell &other) const;68 64 69 65 /// the potentially visible objects -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r361 r362 20 20 int BspTree::sConstructionMethod = FROM_INPUT_VIEW_CELLS; 21 21 int BspTree::sTermMaxPolysForAxisAligned = 50; 22 int BspTree::sTermMaxObjectsForAxisAligned = 50; 23 int BspTree::sTermMaxRaysForAxisAligned = -1; 22 24 int BspTree::sTermMaxRays = -1; 25 int BspTree::sMinPvsDif = 10; 23 26 24 27 float BspTree::sCt_div_ci = 1.0f; … … 31 34 float BspTree::sBalancedPolysFactor = 1.0f; 32 35 float BspTree::sBalancedViewCellsFactor = 1.0f; 36 33 37 // NOTE: very important criterium for 2.5d scenes 34 38 float BspTree::sVerticalSplitsFactor = 1.0f; … … 285 289 } 286 290 287 void BspLeaf::GenerateViewCell(const RayContainer &rays,291 void BspLeaf::GenerateViewCell(const BoundedRayContainer &rays, 288 292 int &sampleContributions, 289 293 int &contributingSamples, … … 295 299 mViewCell = new ViewCell(); 296 300 297 RayContainer::const_iterator it, it_end = rays.end();301 BoundedRayContainer::const_iterator it, it_end = rays.end(); 298 302 299 303 // add contributions from samples to the PVS … … 301 305 { 302 306 int contribution = 0; 303 304 if (!(*it)->intersections.empty()) 307 Ray *ray = (*it)->mRay; 308 309 if (!ray->intersections.empty()) 305 310 { 306 contribution += mViewCell->GetPvs().AddSample((*it)->intersections[0].mObject);307 } 308 309 contribution += mViewCell->GetPvs().AddSample((*it)->sourceObject.mObject);311 contribution += mViewCell->GetPvs().AddSample(ray->intersections[0].mObject); 312 } 313 314 contribution += mViewCell->GetPvs().AddSample(ray->sourceObject.mObject); 310 315 311 316 if (contribution > 0) … … 315 320 } 316 321 322 ray->bspLeaves.push_back(this); 323 317 324 if (storeRays) 318 mViewCell->mPiercingRays.push_back( *it);325 mViewCell->mPiercingRays.push_back(ray); 319 326 } 320 327 } … … 414 421 mRoot = new BspLeaf(); 415 422 416 tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new RayContainer()));423 tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new BoundedRayContainer())); 417 424 418 425 while (!tStack.empty()) … … 472 479 tData.mDepth + 1, 473 480 backViewCell, 474 new RayContainer()));481 new BoundedRayContainer())); 475 482 } 476 483 … … 570 577 571 578 // construct tree from the view cell polygons 572 Construct(polys, new RayContainer());579 Construct(polys, new BoundedRayContainer()); 573 580 } 574 581 … … 585 592 586 593 // construct tree from polygon soup 587 Construct(polys, new RayContainer());594 Construct(polys, new BoundedRayContainer()); 588 595 } 589 596 … … 591 598 { 592 599 mStat.nodes = 1; 593 mBox.Initialize(); // initialise bsptree bounding box600 mBox.Initialize(); // initialise BSP tree bounding box 594 601 595 602 PolygonContainer *polys = new PolygonContainer(); 596 RayContainer *rays = newRayContainer();603 BoundedRayContainer *rays = new BoundedRayContainer(); 597 604 598 605 RayContainer::const_iterator rit, rit_end = sampleRays.end(); … … 608 615 { 609 616 Ray *ray = *rit; 610 ray->SetId(-1); // reset id 611 rays->push_back(ray); 612 613 //Debug << "extracting ray with intersections" << ray->intersections.size() << endl; 614 617 615 618 // get ray-face intersection. Store polygon representing the rays together 616 619 // with rays intersecting the face. … … 629 632 { 630 633 Polygon3 *poly = new Polygon3(face, obj->GetMesh()); 634 poly->mParent = obj; 631 635 polys->push_back(poly); 632 636 poly->mPiercingRays.push_back(ray); … … 638 642 639 643 Polygon3::IncludeInBox(*polys, mBox); 644 645 //-- store rays 646 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 647 { 648 Ray *ray = *rit; 649 ray->SetId(-1); // reset id 650 651 float minT, maxT; 652 if (BoundRay(*ray, minT, maxT)) 653 rays->push_back(new BoundedRay(ray, minT, maxT)); 654 } 655 640 656 mStat.polys = (int)polys->size(); 641 657 … … 647 663 } 648 664 649 void BspTree::Construct(PolygonContainer *polys, RayContainer *rays)665 void BspTree::Construct(PolygonContainer *polys, BoundedRayContainer *rays) 650 666 { 651 667 std::stack<BspTraversalData> tStack; … … 705 721 leaf->ProcessPolygons(tData.mPolygons, sStoreSplitPolys); 706 722 DEL_PTR(tData.mPolygons); 723 // discard rays 724 CLEAR_CONTAINER(*tData.mRays); 707 725 DEL_PTR(tData.mRays); 708 726 … … 717 735 PolygonContainer *backPolys = new PolygonContainer(); 718 736 719 RayContainer *frontRays = newRayContainer();720 RayContainer *backRays = newRayContainer();737 BoundedRayContainer *frontRays = new BoundedRayContainer(); 738 BoundedRayContainer *backRays = new BoundedRayContainer(); 721 739 722 740 // create new interior node and two leaf nodes … … 810 828 PolygonContainer &backPolys, 811 829 PolygonContainer &coincident, 812 RayContainer &rays,813 RayContainer &frontRays,814 RayContainer &backRays)830 BoundedRayContainer &rays, 831 BoundedRayContainer &frontRays, 832 BoundedRayContainer &backRays) 815 833 { 816 834 mStat.nodes += 2; … … 827 845 SplitRays(interior->mPlane, rays, frontRays, backRays); 828 846 829 // split polygons with split plane 830 mStat.splits +=interior->SplitPolygons(polys, 831 frontPolys, 832 backPolys, 833 coincident, 834 sStoreSplitPolys); 847 // subdivide polygons with plane 848 mStat.splits += 849 interior->SplitPolygons(polys, frontPolys, backPolys, 850 coincident, sStoreSplitPolys); 835 851 836 852 BspInterior *parent = leaf->GetParent(); … … 995 1011 Plane3 BspTree::SelectPlane(BspLeaf *leaf, 996 1012 PolygonContainer &polys, 997 const RayContainer &rays)1013 const BoundedRayContainer &rays) 998 1014 { 999 1015 if (polys.empty()) … … 1014 1030 return Plane3(norm, position); 1015 1031 } 1016 1032 1017 1033 if ((sSplitPlaneStrategy & AXIS_ALIGNED) && 1018 ((int)polys.size() > sTermMaxPolysForAxisAligned)) 1034 ((int)polys.size() > sTermMaxPolysForAxisAligned) && 1035 ((int)rays.size() > sTermMaxRaysForAxisAligned) && 1036 ((sTermMaxObjectsForAxisAligned < 0) || 1037 (Polygon3::CountIntersectables(polys) > sTermMaxObjectsForAxisAligned))) 1019 1038 { 1020 1039 Plane3 plane; … … 1034 1053 1035 1054 Plane3 BspTree::SelectPlaneHeuristics(PolygonContainer &polys, 1036 const RayContainer &rays,1055 const BoundedRayContainer &rays, 1037 1056 const int maxTests) 1038 1057 { … … 1093 1112 int totalViewCells = 0; 1094 1113 1095 // needed for balanced view cells criterium 1114 // need three unique ids for each type of view cell 1115 // for balanced view cells criterium 1096 1116 ViewCell::NewMail(); 1097 1117 const int backId = ViewCell::sMailId; … … 1206 1226 minT = 0; 1207 1227 1208 //Debug << "ray intersections " << ray.intersections.size() << endl;1209 1228 // bound ray or line segment 1210 1229 if ((ray.GetType() == Ray::LOCAL_RAY) && … … 1219 1238 1220 1239 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 1221 const RayContainer &rays) const1240 const BoundedRayContainer &rays) const 1222 1241 { 1223 1242 float val = 0; … … 1226 1245 float sumRaySplits = 0; 1227 1246 1228 RayContainer::const_iterator rit, rit_end = rays.end();1247 BoundedRayContainer::const_iterator rit, rit_end = rays.end(); 1229 1248 1230 1249 for (rit = rays.begin(); rit != rays.end(); ++ rit) 1231 1250 { 1232 Ray *ray = *rit; 1233 1234 float minT, maxT; 1235 if (!BoundRay(*ray, minT, maxT)) 1236 continue; 1251 Ray *ray = (*rit)->mRay; 1252 const float minT = (*rit)->mMinT; 1253 const float maxT = (*rit)->mMaxT; 1237 1254 1238 1255 const int classification = … … 1263 1280 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 1264 1281 const PolygonContainer &polys, 1265 const RayContainer &rays) const1282 const BoundedRayContainer &rays) const 1266 1283 { 1267 1284 float val = 0; … … 1326 1343 1327 1344 //-- termination criteria for axis aligned split 1328 environment->GetFloatValue("BspTree.Termination. ct_div_ci", sCt_div_ci);1329 environment->GetFloatValue("BspTree.Termination. maxCostRatio", sMaxCostRatio);1330 environment->GetIntValue("BspTree.Termination. maxPolysForAxisAligned",1345 environment->GetFloatValue("BspTree.Termination.AxisAligned.ct_div_ci", sCt_div_ci); 1346 environment->GetFloatValue("BspTree.Termination.AxisAligned.maxCostRatio", sMaxCostRatio); 1347 environment->GetIntValue("BspTree.Termination.AxisAligned.maxPolys", 1331 1348 sTermMaxPolysForAxisAligned); 1332 1349 environment->GetIntValue("BspTree.Termination.AxisAligned.maxRays", 1350 sTermMaxRaysForAxisAligned); 1351 environment->GetIntValue("BspTree.Termination.AxisAligned.maxObjects", 1352 sTermMaxObjectsForAxisAligned); 1333 1353 //-- partition criteria 1334 1354 environment->GetIntValue("BspTree.maxCandidates", sMaxCandidates); 1335 1355 environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy); 1336 environment->GetFloatValue("BspTree. splitBorder", sSplitBorder);1356 environment->GetFloatValue("BspTree.AxisAligned.splitBorder", sSplitBorder); 1337 1357 1338 1358 environment->GetBoolValue("BspTree.storeSplitPolys", sStoreSplitPolys); … … 1340 1360 environment->GetFloatValue("BspTree.Construction.sideTolerance", Vector3::sDistTolerance); 1341 1361 Vector3::sDistToleranceSqrt = Vector3::sDistTolerance * Vector3::sDistTolerance; 1362 1363 environment->GetIntValue("ViewCells.minPvsDif", sMinPvsDif); 1342 1364 1343 1365 Debug << "BSP max depth: " << sTermMaxDepth << endl; … … 1440 1462 float maxt, mint; 1441 1463 1464 if (!BoundRay(ray, mint, maxt)) 1465 return 0; 1466 1442 1467 Intersectable::NewMail(); 1443 1468 1444 BoundRay(ray, mint, maxt);1445 1446 1469 Vector3 entp = ray.Extrap(mint); 1447 1470 Vector3 extp = ray.Extrap(maxt); … … 1458 1481 Plane3 *splitPlane = in->GetPlane(); 1459 1482 1460 float t = 0;1461 bool coplanar = false;1462 1463 1483 int entSide = splitPlane->Side(entp); 1464 1484 int extSide = splitPlane->Side(extp); … … 1494 1514 1495 1515 // find intersection of ray segment with plane 1496 extp = splitPlane->FindIntersection(ray.GetLoc(), extp, &maxt); 1516 float t; 1517 extp = splitPlane->FindIntersection(ray.GetLoc(), extp, &t); 1518 maxt *= t; 1497 1519 1498 1520 } else // reached leaf => intersection with view cell … … 1502 1524 if (!leaf->mViewCell->Mailed()) 1503 1525 { 1504 ray. viewCells.push_back(leaf->mViewCell);1526 ray.bspLeaves.push_back(leaf); 1505 1527 leaf->mViewCell->Mail(); 1506 1528 ++ hits; … … 1514 1536 mint = maxt; // NOTE: need this? 1515 1537 1516 1538 if (ray.GetType() == Ray::LINE_SEGMENT && mint > 1.0f) 1517 1539 break; 1518 1540 … … 1522 1544 extp = s.mExitPoint; 1523 1545 maxt = s.mMaxT; 1524 1525 //Debug << "leaf: new entrypt: " << entp << " new extp: " << extp << endl;1526 1546 1527 1547 tStack.pop(); … … 1577 1597 } 1578 1598 1579 int BspTree::MergeViewCells() 1580 { 1581 stack<BspNode *> nodeStack; 1582 nodeStack.push(mRoot); 1583 1584 BspLeaf *storedLeaf = NULL; 1585 1586 while (!nodeStack.empty()) 1587 { 1588 BspNode *node = nodeStack.top(); 1589 nodeStack.pop(); 1590 1591 if (node->IsLeaf()) 1592 { 1593 BspLeaf *leaf = dynamic_cast<BspLeaf *>(node); 1594 1595 if (storedLeaf) 1596 MergeLeafs(leaf, storedLeaf); 1597 1598 // store current leaf 1599 storedLeaf = leaf; 1600 } 1601 else 1602 { 1603 BspInterior *interior = dynamic_cast<BspInterior *>(node); 1604 1605 nodeStack.push(interior->mFront); 1606 nodeStack.push(interior->mBack); 1607 } 1608 } 1609 return 0; 1610 } 1611 1612 void BspTree::MergeLeafs(BspLeaf *front, BspLeaf *back) const 1613 { 1614 //std::merge(front->mPvs.mEntries.begin(), back->mPvs.mEntries.begin()); 1615 ViewCell *viewCell = ViewCell::MergeViewCells(*front->mViewCell, *back->mViewCell); 1616 //viewCell->GetPvs().Merge(front->mViewCell->GetPvs(), back->mViewCell->GetPvs()); 1617 1618 if (viewCell) 1619 { 1620 DEL_PTR(front->mViewCell); 1621 DEL_PTR(back->mViewCell); 1622 1623 front->SetViewCell(viewCell); 1624 back->SetViewCell(viewCell); 1625 } 1599 1600 bool BspTree::MergeViewCells(BspLeaf *front, BspLeaf *back) const 1601 { 1602 ViewCell *viewCell = ViewCell::Merge(*front->mViewCell, *back->mViewCell); 1603 1604 if (!viewCell) 1605 return false; 1606 1607 DEL_PTR(front->mViewCell); 1608 DEL_PTR(back->mViewCell); 1609 1610 front->SetViewCell(viewCell); 1611 back->SetViewCell(viewCell); 1612 1613 return true; 1614 } 1615 1616 bool BspTree::ShouldMerge(BspLeaf *front, BspLeaf *back) const 1617 { 1618 if (front->mViewCell->GetPvs().Diff(back->mViewCell->GetPvs()) < 1619 sMinPvsDif) 1620 return true; 1621 1622 if (back->mViewCell->GetPvs().Diff(front->mViewCell->GetPvs()) < 1623 sMinPvsDif) 1624 return true; 1625 1626 return false; 1626 1627 } 1627 1628 … … 1637 1638 1638 1639 int BspTree::SplitRays(const Plane3 &plane, 1639 RayContainer &rays,1640 RayContainer &frontRays,1641 RayContainer &backRays)1640 BoundedRayContainer &rays, 1641 BoundedRayContainer &frontRays, 1642 BoundedRayContainer &backRays) 1642 1643 { 1643 1644 int splits = 0; … … 1645 1646 while (!rays.empty()) 1646 1647 { 1647 Ray *ray = rays.back(); 1648 BoundedRay *bRay = rays.back(); 1649 Ray *ray = bRay->mRay; 1648 1650 rays.pop_back(); 1649 1650 //-- ray-plane intersection1651 float maxT, minT;1652 1653 if (!BoundRay(*ray, minT, maxT))1654 continue;1655 1656 const int classification = ray->ClassifyPlane(plane, minT, maxT);1657 1651 1658 ray->SetId(classification); 1659 1660 switch (classification) 1652 const int cf = 1653 ray->ClassifyPlane(plane, bRay->mMinT, bRay->mMaxT); 1654 1655 ray->SetId(cf); 1656 1657 switch (cf) 1661 1658 { 1662 1659 case Ray::COINCIDENT: 1660 frontRays.push_back(bRay); 1663 1661 break; 1664 1662 case Ray::BACK: 1665 backRays.push_back( ray);1663 backRays.push_back(bRay); 1666 1664 break; 1667 1665 case Ray::FRONT: 1668 frontRays.push_back( ray);1666 frontRays.push_back(bRay); 1669 1667 break; 1670 1668 case Ray::FRONT_BACK: 1671 ray->SetId(Ray::FRONT_BACK); 1672 backRays.push_back(ray); 1673 ++ splits; 1669 { 1670 // find intersection of ray segment with plane 1671 const Vector3 extp = ray->Extrap(bRay->mMaxT); 1672 const float t = plane.FindT(ray->GetLoc(), extp); 1673 1674 const float newT = t * bRay->mMaxT; 1675 1676 frontRays.push_back(new BoundedRay(ray, bRay->mMinT, newT)); 1677 backRays.push_back(new BoundedRay(ray, newT, bRay->mMaxT)); 1678 1679 DEL_PTR(bRay); 1680 1681 ++ splits; 1682 } 1674 1683 break; 1675 1684 case Ray::BACK_FRONT: 1676 frontRays.push_back(ray); 1677 ++ splits; 1685 { 1686 // find intersection of ray segment with plane 1687 const Vector3 extp = ray->Extrap(bRay->mMaxT); 1688 const float t = plane.FindT(ray->GetLoc(), extp); 1689 const float newT = t * bRay->mMaxT; 1690 1691 backRays.push_back(new BoundedRay(ray, bRay->mMinT, newT)); 1692 frontRays.push_back(new BoundedRay(ray, newT, bRay->mMaxT)); 1693 1694 DEL_PTR(bRay); 1695 1696 ++ splits; 1697 } 1678 1698 break; 1679 1699 default: … … 1686 1706 } 1687 1707 1688 void BspTree::ExtractSplitPlanes(BspNode *n, vector<Plane3 *> &planes, vector<bool> &sides) const 1708 void BspTree::ExtractSplitPlanes(BspNode *n, 1709 vector<Plane3 *> &planes, 1710 vector<bool> &sides) const 1689 1711 { 1690 1712 BspNode *lastNode; … … 1692 1714 { 1693 1715 lastNode = n; 1716 1717 // want to get planes defining geometry of this node => don't take 1718 // split plane of node itself 1694 1719 n = n->GetParent(); 1695 1720 … … 1705 1730 } 1706 1731 1732 struct Candidate 1733 { 1734 Polygon3 *mPoly; 1735 Plane3 mPlane; 1736 bool mSide; 1737 1738 Candidate(Polygon3 *poly, const Plane3 &plane, const bool &side): 1739 mPoly(poly), mPlane(plane), mSide(side) 1740 {} 1741 }; 1742 1743 void BspTree::AddHalfspace(PolygonContainer &cell, 1744 vector<Plane3> &planes, 1745 vector<bool> &sides, 1746 const Plane3 &halfspace, 1747 const bool side) const 1748 { 1749 Polygon3 *poly = GetBoundingBox().CrossSection(halfspace); 1750 1751 bool inside = true; 1752 1753 // polygon is split by all other planes 1754 for (int i = 0; (i < planes.size()) && inside; ++ i) 1755 { 1756 VertexContainer splitPts; 1757 Polygon3 *frontPoly, *backPoly; 1758 1759 const int cf = poly->ClassifyPlane(planes[i]); 1760 1761 // split new polygon with all previous planes 1762 switch (cf) 1763 { 1764 case Polygon3::SPLIT: 1765 frontPoly = new Polygon3(); 1766 backPoly = new Polygon3(); 1767 1768 poly->Split(planes[i], *frontPoly, *backPoly, splitPts); 1769 DEL_PTR(poly); 1770 1771 if(sides[i] == true) 1772 { 1773 poly = frontPoly; 1774 DEL_PTR(backPoly); 1775 } 1776 else 1777 { 1778 poly = backPoly; 1779 DEL_PTR(frontPoly); 1780 } 1781 inside = true; 1782 break; 1783 case Polygon3::BACK_SIDE: 1784 if (sides[i]) 1785 inside = false; 1786 break; 1787 case Polygon3::FRONT_SIDE: 1788 if (!sides[i]) 1789 inside = false; 1790 break; 1791 default: 1792 break; 1793 } 1794 } 1795 1796 //-- plane poly splits all other candidates 1797 1798 // some polygons may fall out => rebuild cell 1799 vector<Candidate> candidates; 1800 1801 for (int i = 0; i < (int)cell.size(); ++ i) 1802 { 1803 candidates.push_back(Candidate(cell[i], planes[i], sides[i])); 1804 } 1805 1806 cell.clear(); 1807 planes.clear(); 1808 sides.clear(); 1809 1810 for (int i = 0; i < (int)candidates.size(); ++ i) 1811 { 1812 bool candidateInside = true; 1813 1814 VertexContainer splitPts; 1815 Polygon3 *frontPoly, *backPoly; 1816 1817 const int cf = poly->ClassifyPlane(halfspace); 1818 1819 // split new polygon with all previous planes 1820 switch (cf) 1821 { 1822 case Polygon3::SPLIT: 1823 frontPoly = new Polygon3(); 1824 backPoly = new Polygon3(); 1825 1826 poly->Split(halfspace, *frontPoly, *backPoly, splitPts); 1827 DEL_PTR(candidates[i].mPoly); 1828 1829 if (sides[i] == true) 1830 { 1831 candidates[i].mPoly = frontPoly; 1832 DEL_PTR(backPoly); 1833 } 1834 else 1835 { 1836 candidates[i].mPoly = backPoly; 1837 DEL_PTR(frontPoly); 1838 } 1839 inside = true; 1840 break; 1841 case Polygon3::BACK_SIDE: 1842 if (candidates[i].mSide) 1843 candidateInside = false; 1844 break; 1845 case Polygon3::FRONT_SIDE: 1846 if (!candidates[i].mSide) 1847 candidateInside = false; 1848 break; 1849 default: 1850 break; 1851 } 1852 1853 if (candidateInside) 1854 { 1855 cell.push_back(candidates[i].mPoly); 1856 sides.push_back(candidates[i].mSide); 1857 planes.push_back(candidates[i].mPlane); 1858 } 1859 else 1860 { 1861 DEL_PTR(candidates[i].mPoly); 1862 } 1863 } 1864 1865 //-- finally add polygon 1866 if (inside) 1867 { 1868 cell.push_back(poly); 1869 planes.push_back(halfspace); 1870 sides.push_back(side); 1871 } 1872 else 1873 { 1874 DEL_PTR(poly); 1875 } 1876 } 1877 1878 1707 1879 void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const 1708 1880 { … … 1716 1888 PolygonContainer candidatePolys; 1717 1889 1718 // bounded plane isadded to the polygons1890 // bounded planes are added to the polygons 1719 1891 for (int i = 0; i < (int)planes.size(); ++ i) 1720 1892 { … … 1722 1894 } 1723 1895 1896 // add faces of bounding box (also could be faces of the cell) 1724 1897 for (int i = 0; i < 6; ++ i) 1725 1898 { … … 1736 1909 bool inside = true; 1737 1910 1738 // polygon is split withall other planes1911 // polygon is split by all other planes 1739 1912 for (int j = 0; (j < planes.size()) && inside; ++ j) 1740 1913 { … … 1747 1920 Polygon3 *frontPoly, *backPoly; 1748 1921 1749 int cf = candidatePolys[i]->ClassifyPlane(*plane);1922 const int cf = candidatePolys[i]->ClassifyPlane(*plane); 1750 1923 1751 // split new polygon with all previous planes 1752 switch(cf) 1924 switch (cf) 1753 1925 { 1754 1926 case Polygon3::SPLIT: … … 1756 1928 backPoly = new Polygon3(); 1757 1929 1758 candidatePolys[i]->Split(*plane, *frontPoly, *backPoly, splitPts); 1930 candidatePolys[i]->Split(*plane, *frontPoly, 1931 *backPoly, splitPts); 1759 1932 DEL_PTR(candidatePolys[i]); 1760 1933 … … 1835 2008 if (isAdjacent) 1836 2009 neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 2010 2011 CLEAR_CONTAINER(neighborCandidate); 1837 2012 } 1838 2013 } … … 1857 2032 } 1858 2033 2034 CLEAR_CONTAINER(cell); 1859 2035 return (int)neighbors.size(); 1860 2036 } 2037 2038 BspLeaf *BspTree::GetRandomLeaf(const Plane3 &halfspace) 2039 { 2040 stack<BspNode *> nodeStack; 2041 nodeStack.push(mRoot); 2042 2043 int mask = rand(); 2044 2045 while (!nodeStack.empty()) 2046 { 2047 BspNode *node = nodeStack.top(); 2048 nodeStack.pop(); 2049 2050 if (node->IsLeaf()) 2051 { 2052 return dynamic_cast<BspLeaf *>(node); 2053 } 2054 else 2055 { 2056 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2057 2058 BspNode *next; 2059 2060 PolygonContainer cell; 2061 2062 // todo: not very efficient: constructs full cell everytime 2063 ConstructGeometry(interior, cell); 2064 2065 const int cf = Polygon3::ClassifyPlane(cell, halfspace); 2066 2067 if (cf == Polygon3::BACK_SIDE) 2068 next = interior->mFront; 2069 else 2070 if (cf == Polygon3::FRONT_SIDE) 2071 next = interior->mFront; 2072 else 2073 { 2074 // random decision 2075 if (mask & 1) 2076 next = interior->mBack; 2077 else 2078 next = interior->mFront; 2079 mask = mask >> 1; 2080 } 2081 2082 nodeStack.push(next); 2083 } 2084 } 2085 2086 return NULL; 2087 } 2088 2089 BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 2090 { 2091 stack<BspNode *> nodeStack; 2092 2093 nodeStack.push(mRoot); 2094 2095 int mask = rand(); 2096 2097 while (!nodeStack.empty()) 2098 { 2099 BspNode *node = nodeStack.top(); 2100 nodeStack.pop(); 2101 2102 if (node->IsLeaf()) 2103 { 2104 if ( (!onlyUnmailed || !node->Mailed()) ) 2105 return dynamic_cast<BspLeaf *>(node); 2106 } 2107 else 2108 { 2109 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2110 2111 // random decision 2112 if (mask & 1) 2113 nodeStack.push(interior->mBack); 2114 else 2115 nodeStack.push(interior->mFront); 2116 2117 mask = mask >> 1; 2118 } 2119 } 2120 2121 return NULL; 2122 } -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
r361 r362 14 14 class Ray; 15 15 16 /** Data structure used for optimized ray casting. 17 */ 16 18 struct BspRayTraversalData 17 19 { … … 26 28 {} 27 29 }; 30 31 /** Data used for passing ray data down the tree. 32 */ 33 struct BoundedRay 34 { 35 Ray *mRay; 36 float mMinT; 37 float mMaxT; 38 39 BoundedRay(): mMinT(0), mMaxT(1e6), mRay(NULL) 40 {} 41 BoundedRay(Ray *r, float minT, float maxT): 42 mRay(r), mMinT(minT), mMaxT(maxT) 43 {} 44 }; 45 46 typedef vector<BoundedRay *> BoundedRayContainer; 28 47 29 48 class BspTreeStatistics … … 230 249 @param storeRays if ray set should be stored in view cell 231 250 */ 232 void BspLeaf::GenerateViewCell(constRayContainer &rays,233 234 235 251 void GenerateViewCell(const BoundedRayContainer &rays, 252 int &sampleContributions, 253 int &contributingSamples, 254 const bool storeRays = false); 236 255 237 256 protected: … … 246 265 { 247 266 public: 248 267 249 268 /** Additional data which is passed down the BSP tree during traversal. 250 269 */ … … 260 279 ViewCell *mViewCell; 261 280 /// rays piercing this node 262 RayContainer *mRays;281 BoundedRayContainer *mRays; 263 282 264 283 BspTraversalData(): … … 274 293 const int depth, 275 294 ViewCell *viewCell, 276 RayContainer *rays):295 BoundedRayContainer *rays): 277 296 mNode(node), 278 297 mPolygons(polys), … … 344 363 int CastRay(Ray &ray); 345 364 365 /** Set to true if new view cells shall be generated in each leaf. 366 */ 367 void SetGenerateViewCells(int generateViewCells); 368 369 /// bsp tree construction types 370 enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_RAYS}; 371 372 /** Returns statistics. 373 */ 374 BspTreeStatistics &GetStat(); 375 376 /** finds neighbouring leaves of this tree node. 377 */ 378 int FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 379 const bool onlyUnmailed) const; 380 381 /** Extracts geometry associated with the split plane leading to this node. 382 */ 383 void ConstructGeometry(BspNode *n, PolygonContainer &polys) const; 384 385 /** Returns random leaf of BSP tree. 386 @param halfspace defines the halfspace from which the leaf is taken. 387 */ 388 BspLeaf *GetRandomLeaf(const Plane3 &halfspace); 389 390 /** Returns random leaf of BSP tree. 391 @param onlyUnmailed if only unmailed leaves should be returned. 392 */ 393 BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false); 394 395 /** Adds halfspace to cell definition. 396 @param side indicates which side of halfspace is added 397 */ 398 void AddHalfspace(PolygonContainer &cell, 399 vector<Plane3> &planes, 400 vector<bool> &sides, 401 const Plane3 &halfspace, 402 const bool side) const; 403 404 /** Returns true if merge criteria are reached. 405 */ 406 bool ShouldMerge(BspLeaf *front, BspLeaf *back) const; 407 346 408 /** Merges view cells based on some criteria 347 409 E.g., empty view cells can pe purged, view cells which have 348 a very similar PVS can be merged to one larger view cell farther up 349 in the BSP tree. 350 @returns the number of merged view cells 351 */ 352 int MergeViewCells(); 353 354 /** Set to true if new view cells shall be generated in each leaf. 355 */ 356 void SetGenerateViewCells(int generateViewCells); 357 358 /// bsp tree construction types 359 enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_RAYS}; 360 361 /** Returns statistics. 362 */ 363 BspTreeStatistics &GetStat(); 364 365 /** finds neighbouring leaves of this tree node. 366 */ 367 int FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 368 const bool onlyUnmailed) const; 369 370 /** Extracts geometry associated with the split plane leading to this node. 371 */ 372 void ConstructGeometry(BspNode *n, PolygonContainer &polys) const; 410 a very similar PVS can be merged to one larger view cell. 411 412 @returns true if merge was successful. 413 */ 414 bool MergeViewCells(BspLeaf *front, BspLeaf *back) const; 373 415 374 416 protected: … … 394 436 }; 395 437 396 /** Merges view cells of leafs.397 */398 void MergeLeafs(BspLeaf *front, BspLeaf *back) const;399 400 438 /** Evaluates tree stats in the BSP tree leafs. 401 439 */ … … 413 451 @param rays storesset of rays on which subdivision may be based 414 452 */ 415 void Construct(PolygonContainer *polys, RayContainer *rays);453 void Construct(PolygonContainer *polys, BoundedRayContainer *rays); 416 454 417 455 /** Selects the best possible splitting plane. … … 424 462 Plane3 SelectPlane(BspLeaf *leaf, 425 463 PolygonContainer &polys, 426 const RayContainer &ray);464 const BoundedRayContainer &ray); 427 465 428 466 /** Evaluates the contribution of the candidate split plane. … … 435 473 float SplitPlaneCost(const Plane3 &candidatePlane, 436 474 const PolygonContainer &polys, 437 const RayContainer &rays) const;475 const BoundedRayContainer &rays) const; 438 476 439 477 /** Strategies where the effect of the split plane is tested … … 449 487 */ 450 488 float SplitPlaneCost(const Plane3 &candidatePlane, 451 const RayContainer &polys) const;489 const BoundedRayContainer &polys) const; 452 490 453 491 /** Filters next view cell down the tree and inserts it into the appropriate leaves … … 478 516 PolygonContainer &backPolys, 479 517 PolygonContainer &coincident, 480 RayContainer &rays,481 RayContainer &frontRays,482 518 BoundedRayContainer &rays, 519 BoundedRayContainer &frontRays, 520 BoundedRayContainer &backRays); 483 521 484 522 /** Filters polygons down the tree. … … 501 539 */ 502 540 Plane3 SelectPlaneHeuristics(PolygonContainer &polys, 503 const RayContainer &rays,541 const BoundedRayContainer &rays, 504 542 const int maxTests); 505 543 … … 597 635 */ 598 636 int SplitRays(const Plane3 &plane, 599 RayContainer &rays,600 RayContainer &frontRays,601 RayContainer &backRays);637 BoundedRayContainer &rays, 638 BoundedRayContainer &frontRays, 639 BoundedRayContainer &backRays); 602 640 603 641 … … 656 694 /// BSP tree construction method 657 695 static int sConstructionMethod; 658 /// maximal number of polygons where we do axis aligned splits696 /// maximal number of polygons for axis aligned split 659 697 static int sTermMaxPolysForAxisAligned; 698 /// maximal number of rays for axis aligned split 699 static int sTermMaxRaysForAxisAligned; 700 /// maximal number of objects for axis aligned split 701 static int sTermMaxObjectsForAxisAligned; 660 702 661 703 /// axis aligned split criteria … … 677 719 static bool sStoreSplitPolys; 678 720 721 /// threshold where view cells are merged 722 static int sMinPvsDif; 723 679 724 private: 680 725 /** Evaluates split plane classification with respect to the plane's -
trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.h
r360 r362 50 50 ExportPolygon(Polygon3 *poly); 51 51 52 virtual void ExportPolygons(const PolygonContainer &polys); 52 virtual void 53 ExportPolygons(const PolygonContainer &polys); 53 54 54 55 virtual bool
Note: See TracChangeset
for help on using the changeset viewer.