- Timestamp:
- 02/06/06 19:09:53 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
r598 r600 13 13 #;../data/vienna/vienna-plane.x3d 14 14 # filename ../data/vienna/viewcells-25-sel.x3d 15 #filename ../data/atlanta/atlanta2.x3d15 filename ../data/atlanta/atlanta2.x3d 16 16 # filename ../data/soda/soda.dat 17 filename ../data/soda/soda5.dat17 # filename ../data/soda/soda5.dat 18 18 } 19 19 … … 25 25 type vss 26 26 # type rss 27 detectEmptyViewSpace true27 detectEmptyViewSpace false 28 28 } 29 29 … … 36 36 loadInitialSamples false 37 37 storeInitialSamples false 38 useViewSpaceBox true38 useViewSpaceBox false 39 39 # testBeamSampling true 40 40 } … … 176 176 # samples used for view cell construction 177 177 Construction { 178 samples 600000179 samplesPerPass 200000178 samples 2000000 179 samplesPerPass 500000 180 180 } 181 181 182 182 #number of active view cells 183 active 2 56183 active 2048 184 184 maxStaticMemory 40 185 185 186 exportToFile false186 exportToFile true 187 187 loadFromFile false 188 188 189 189 #type kdTree 190 type vspKdTree190 #type vspKdTree 191 191 #type bspTree 192 192 type vspBspTree … … 209 209 maxCostRatio 0.1 210 210 minViewCells 1 211 avgCostMaxDeviation 0. 8212 maxMergesPerPass 500 211 avgCostMaxDeviation 0.01 212 maxMergesPerPass 500 213 213 useRaysForMerge false 214 214 refine false 215 215 compress false 216 merge false216 merge true 217 217 } 218 218 … … 288 288 VspBspTree { 289 289 Construction { 290 samples 300000290 samples 1000000 291 291 epsilon 0.005 292 292 randomize false … … 301 301 # pvs = 1024 302 302 303 splitPlaneStrategy 102 4303 splitPlaneStrategy 1026 304 304 305 305 # maximal candidates for split planes 306 maxPolyCandidates 0306 maxPolyCandidates 200 307 307 308 308 … … 322 322 Termination { 323 323 # parameters used for autopartition 324 minRays -150324 minRays 500 325 325 minPolygons -1 326 maxDepth 30 327 minPvs -10 328 #minProbability 0.0001 329 minProbability -1 330 # maxRayContribution 0.3 331 maxRayContribution 2.3 332 # maxCostRatio 0.9 333 maxCostRatio 3.9 326 maxDepth 25 327 minPvs -1 328 minProbability 0.0000001 329 maxRayContribution 0.3 330 maxCostRatio 0.9 334 331 missTolerance 3 335 336 337 maxViewCells 512 332 333 maxViewCells 30000 338 334 339 335 # used for pvs criterium … … 341 337 342 338 AxisAligned { 343 minRays 1339 minRays 20000 344 340 maxRayContribution 9.9 345 341 } 346 342 } 347 343 348 splitUseOnlyDrivingAxis true344 splitUseOnlyDrivingAxis false 349 345 350 346 Visualization { 351 347 # x3d visualization of the split planes 352 exportSplits true348 exportSplits false 353 349 } 354 350 } -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
r590 r600 22 22 bool operator() (T v1, T v2) const 23 23 { 24 return (v1->Get TimeStamp() < v2->GetTimeStamp());24 return (v1->GetMergeCost() < v2->GetMergeCost()); 25 25 } 26 26 }; … … 107 107 mValid(true), 108 108 mParent(NULL), 109 m TimeStamp(0),109 mMergeCost(0), 110 110 mIsActive(false) 111 111 { … … 119 119 mValid(true), 120 120 mParent(NULL), 121 m TimeStamp(0),121 mMergeCost(0), 122 122 mIsActive(false) 123 123 { … … 230 230 231 231 232 void ViewCell::Set TimeStamp(const int timeStamp)233 { 234 m TimeStamp = timeStamp;235 } 236 237 238 int ViewCell::GetTimeStamp() const239 { 240 return m TimeStamp;232 void ViewCell::SetMergeCost(const float mergeCost) 233 { 234 mMergeCost = mergeCost; 235 } 236 237 238 float ViewCell::GetMergeCost() const 239 { 240 return mMergeCost; 241 241 } 242 242 … … 445 445 float variance = 0; 446 446 int totalPvs = 0; 447 float total Cost = 0;447 float totalRenderCost = 0; 448 448 449 449 //-- compute statistics values of initial view cells 450 mViewCellsManager->EvaluateRenderStatistics(total Cost,450 mViewCellsManager->EvaluateRenderStatistics(totalRenderCost, 451 451 mExpectedCost, 452 452 mDeviation, … … 471 471 Debug << "deviation: " << mDeviation << endl; 472 472 Debug << "avg render cost: " << mAvgRenderCost << endl; 473 Debug << "expected cost: " << mExpectedCost << endl;473 Debug << "expected cost: " << mExpectedCost << endl; 474 474 475 475 … … 498 498 499 499 // frequency stats are updated 500 const int statsOut = 1 00;500 const int statsOut = 1; 501 501 502 502 // passes are needed for statistics, because we don't want to record … … 521 521 522 522 //-- use priority queue to merge leaf pairs 523 524 while (!mMergeQueue.empty())// && (realNumActiveViewCells > mMergeMinViewCells)) 523 // HACK 524 //const float maxAvgCost = 350; 525 while (!mMergeQueue.empty())//NumActiveViewCells > mMergeMinViewCells)) 525 526 { 526 527 //-- reset merge queue if the ratio of current expected cost / real expected cost … … 588 589 { 589 590 ViewCell::NewMail(); 590 591 592 //-- update statistical values 591 593 -- realNumActiveViewCells; 592 594 ++ mergeStats.merged; 593 595 ++ mergedPerPass; 594 596 595 596 //-- update statistical values 597 const float renderCostIncr = mc.GetRenderCost(); 598 const float mergeCostIncr = mc.GetMergeCost(); 599 600 totalRenderCost += renderCostIncr; 601 mDeviation += mc.GetDeviationIncr(); 602 603 604 // merge the view cells of leaf1 and leaf2 605 int pvsDiff; 606 ViewCellInterior *mergedVc = 607 MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff); 608 597 609 598 610 // total render cost and deviation has changed … … 600 612 // cost heuristics, but cannot recompute costs on each increase of the 601 613 // expected cost 602 603 totalCost += mc.GetRenderCost();604 mDeviation += mc.GetDeviationIncr();605 606 realExpectedCost = totalCost / (float)realNumActiveViewCells;607 608 const float currentMergeCost = mc.GetMergeCost();609 610 // merge the view cells of leaf1 and leaf2611 int pvsDiff;612 ViewCellInterior *mergedVc =613 MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff);614 615 614 totalPvs += pvsDiff; 616 617 // set timestamp 618 mergedVc->SetTimeStamp(mergeStats.merged); 619 615 realExpectedCost = totalRenderCost / (float)realNumActiveViewCells; 620 616 realAvgRenderCost = (float)totalPvs / (float)realNumActiveViewCells; 617 618 // set merge cost to this node 619 mergedVc->SetMergeCost(totalRenderCost); 620 621 621 #if VC_HISTORY 622 622 if (mc.mLeftViewCell->IsSibling(mc.mRightViewCell)) … … 632 632 << "#Merged\n" << mergeStats.merged << endl 633 633 << "#Viewcells\n" << realNumActiveViewCells << endl 634 << "#CurrentCost\n" << currentMergeCost << endl 635 << "#RelativeCost\n" << currentMergeCost / mOverallCost << endl 636 << "#CurrentPvs\n" << mc.GetLeftViewCell()->GetPvs().GetSize() << endl 637 << "#MergedSiblings\n" << mergeStats.siblings << endl 638 << "#AvgTreeDist\n" << mergeStats.AvgTreeDist() << endl 639 << "#UsedExpectedCost\n" << mExpectedCost << endl 640 << "#RealExpectedCost\n" << realExpectedCost << endl 641 << "#RealAvgRenderCost\n" << realAvgRenderCost << endl 642 << "#AvgRenderCost\n" << mAvgRenderCost << endl 643 << "#expectedCostRatio\n" << mExpectedCost / realExpectedCost << endl 644 << "#Deviation\n" << mDeviation / (float)realNumActiveViewCells << endl 645 << "#TotalDeviation\n" << mDeviation<< endl; 634 << "#RenderCostIncrease\n" << renderCostIncr << endl 635 << "#TotalRenderCost\n" << totalRenderCost << endl 636 << "#CurrentPvs\n" << mergedVc->GetPvs().GetSize() << endl 637 << "#ExpectedCost\n" << realExpectedCost << endl 638 << "#AvgRenderCost\n" << realAvgRenderCost << endl 639 << "#Deviation\n" << mDeviation << endl 640 << "#TotalPvs\n" << totalPvs << endl 641 << "#PvsSizeDecrease\n" << -pvsDiff << endl; 646 642 } 647 643 } … … 682 678 }*/ 683 679 ViewCellInterior *root = mViewCellsManager->MergeViewCells(activeViewCells); 684 685 root->SetTimeStamp(mergeStats.merged + 1); 680 root->SetMergeCost(totalRenderCost); 686 681 mRoot = root; 687 682 } … … 692 687 } 693 688 689 690 while (!mMergeQueue.empty()) 691 { 692 mMergeQueue.pop(); 693 } 694 695 694 696 // TODO delete because makes no sense here 695 697 mergeStats.expectedRenderCost = realExpectedCost; -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
r590 r600 169 169 170 170 171 void Set TimeStamp(const int timeStamp);172 int GetTimeStamp() const;171 void SetMergeCost(const float mergeCost); 172 float GetMergeCost() const; 173 173 static void NewMail(const int reserve = 1) { 174 174 sMailId += sReservedMailboxes; … … 201 201 float mArea; 202 202 203 int mTimeStamp;203 float mMergeCost; 204 204 205 205 bool mValid; … … 265 265 class ViewCellsTree 266 266 { 267 friend class ViewCellsManager; 267 268 public: 268 269 ViewCellsTree(ViewCellsManager *vcm); -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r590 r600 414 414 << maxCostNodes * 100 / (double)Leaves() << endl; 415 415 416 app << "#N_PMINPROBABILITY AREALEAVES ( Percentage of leaves with mininum probability )\n"416 app << "#N_PMINPROBABILITYLEAVES ( Percentage of leaves with mininum probability )\n" 417 417 << minProbabilityNodes * 100 / (double)Leaves() << endl; 418 418 … … 864 864 } 865 865 866 866 867 bool BspTree::TerminationCriteriaMet(const BspTraversalData &data) const 867 868 { … … 875 876 (data.GetAvgRayContribution() > mTermMaxRayContribution)); 876 877 } 878 877 879 878 880 BspNode *BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData) … … 1986 1988 1987 1989 Intersectable::NewMail(); 1990 ViewCell::NewMail(); 1988 1991 1989 1992 Vector3 entp = origin; … … 2229 2232 { 2230 2233 ViewCellContainer leaves; 2231 mViewCells Manager->GetViewCellsTree()->CollectLeaves(vc, leaves);2234 mViewCellsTree->CollectLeaves(vc, leaves); 2232 2235 2233 2236 ViewCellContainer::const_iterator it, it_end = leaves.end(); -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
r598 r600 58 58 59 59 60 environment->GetIntValue("ViewCells.active", mNum MergedViewCells);60 environment->GetIntValue("ViewCells.active", mNumActiveViewCells); 61 61 environment->GetBoolValue("ViewCells.PostProcess.compress", mCompressViewCells); 62 62 environment->GetBoolValue("ViewCells.Visualization.useCuttingPlane", mUseCuttingPlaneForViz); … … 178 178 Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION; 179 179 180 if (0) 180 181 dirSamples = !dirSamples; // toggle sampling method 181 182 numSamples += CastPassSamples(mSamplesPerPass, … … 692 693 int axis = 0; 693 694 694 const float factor = 0. 55;695 const float factor = 0.35; 695 696 Vector3 point = mViewSpaceBox.Min() + mViewSpaceBox.Size() * factor; 696 697 … … 1032 1033 if (exporter) 1033 1034 { 1035 1036 if (0 && mExportRays) 1037 exporter->ExportRays(rays, RgbColor(1, 1, 1)); 1038 1039 1040 if (mExportGeometry) 1041 exporter->ExportGeometry(objects); 1042 1034 1043 //exporter->SetWireframe(); 1035 1044 exporter->SetFilled(); 1036 1045 ExportViewCellsForViz(exporter); 1037 1046 1038 if (0 && mExportRays)1039 exporter->ExportRays(rays, RgbColor(1, 1, 1));1040 1041 if (mExportGeometry)1042 exporter->ExportGeometry(objects);1043 1047 1044 1048 delete exporter; … … 1063 1067 // we can use the view cells tree hierarchy to get the right set 1064 1068 mViewCellsTree->CollectBestViewCellSet(mViewCells, 1065 mNum MergedViewCells);1069 mNumActiveViewCells); 1066 1070 } 1067 1071 } … … 1113 1117 1114 1118 //-- post processing of bsp view cells 1119 1115 1120 int vcSize = 0; 1116 1121 int pvsSize = 0; … … 1124 1129 1125 1130 Debug << ss << endl; 1126 1127 if (1) // export view cells1128 {1129 cout << "exporting initial view cells (=leaves) ... ";1130 Exporter *exporter = Exporter::GetExporter("view_cells.x3d");1131 1132 if (exporter)1133 {1134 //exporter->SetWireframe();1135 exporter->SetFilled();1136 ExportViewCellsForViz(exporter);1137 1138 if (mExportGeometry)1139 {1140 Material m;1141 m.mDiffuseColor = RgbColor(0, 1, 0);1142 exporter->SetForcedMaterial(m);1143 1144 exporter->SetWireframe();1145 1146 exporter->ExportGeometry(objects);1147 }1148 1149 delete exporter;1150 }1151 cout << "finished" << endl;1152 }1153 1131 1154 1132 … … 1177 1155 } 1178 1156 1179 1157 // reset view cells and stats 1180 1158 ResetViewCells(); 1159 1160 int savedColorCode = mColorCode; 1161 1162 //BspLeaf::NewMail(); 1163 if (1) // export merged view cells 1164 { 1165 mColorCode = 0; 1166 cout << "reseting view cells ... "; 1167 ResetViewCells(); 1168 cout << "finished" << endl; 1169 1170 Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 1171 Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 1172 1173 cout << "exporting view cells after merge ... "; 1174 1175 if (exporter) 1176 { 1177 if (mExportGeometry) 1178 exporter->ExportGeometry(objects); 1179 1180 //exporter->SetWireframe(); 1181 exporter->SetFilled(); 1182 ExportViewCellsForViz(exporter); 1183 1184 1185 delete exporter; 1186 } 1187 cout << "finished" << endl; 1188 } 1189 1190 if (1) // export merged view cells 1191 { 1192 mColorCode = 1; 1193 1194 Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d"); 1195 1196 cout << "exporting view cells after merge (pvs size) ... "; 1197 1198 if (exporter) 1199 { 1200 //exporter->SetWireframe(); 1201 1202 if (mExportGeometry) 1203 exporter->ExportGeometry(objects); 1204 1205 //exporter->SetWireframe(); 1206 exporter->SetFilled(); 1207 ExportViewCellsForViz(exporter); 1208 1209 delete exporter; 1210 } 1211 cout << "finished" << endl; 1212 } 1213 1214 mColorCode = savedColorCode; 1215 1181 1216 FinalizeViewCells(true); 1182 1217 1183 // HACK: removes view cells in bsp leaves with active ones1184 if (0)1185 AddCurrentViewCellsToHierarchy();1186 1187 1218 // write view cells to disc 1188 1219 if (mExportViewCells) … … 1216 1247 return; 1217 1248 1218 //BspLeaf::NewMail(); 1219 if (1) // export merged view cells 1220 { 1221 1222 cout << "reseting view cells ... "; 1223 ResetViewCells(); 1224 1249 int savedColorCode = mColorCode; 1250 1251 1252 1253 if (1) // export final view cells 1254 { 1255 mColorCode = 1; 1256 1257 Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 1258 1259 cout << "exporting view cells after merge (pvs size) ... "; 1260 1261 if (exporter) 1262 { 1263 //exporter->SetWireframe(); 1264 1265 if (mExportGeometry) 1266 exporter->ExportGeometry(objects); 1267 1268 //exporter->SetWireframe(); 1269 exporter->SetFilled(); 1270 ExportViewCellsForViz(exporter); 1271 1272 delete exporter; 1273 } 1225 1274 cout << "finished" << endl; 1226 1227 Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 1228 Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 1229 1230 cout << "exporting view cells after merge ... "; 1231 1232 if (exporter) 1233 { 1234 if (0) 1235 exporter->SetWireframe(); 1236 else 1237 exporter->SetFilled(); 1238 1239 ExportViewCellsForViz(exporter); 1240 1241 if (mExportGeometry) 1242 { 1243 Material m; 1244 m.mDiffuseColor = RgbColor(0, 1, 0); 1245 exporter->SetForcedMaterial(m); 1246 exporter->SetFilled(); 1247 1248 exporter->ExportGeometry(objects); 1249 } 1250 1251 delete exporter; 1252 } 1253 cout << "finished" << endl; 1254 } 1275 } 1276 1277 mColorCode = savedColorCode; 1255 1278 1256 1279 //-- visualization of the BSP splits … … 1265 1288 } 1266 1289 1290 // export single view cells 1267 1291 ExportBspPvs(objects); 1268 1292 } … … 1406 1430 ViewCell *vc) const 1407 1431 { 1408 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 1432 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 1433 1434 float importance = 0; 1435 static Material m; 1436 1437 switch (mColorCode) 1438 { 1439 case 0: // Random 1440 { 1441 if (vcValid) 1442 { 1443 m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f); 1444 m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f); 1445 m.mDiffuseColor.b = 0.5f + RandomValue(0.0f, 0.5f); 1446 } 1447 else 1448 { 1449 m.mDiffuseColor.r = 0.0f; 1450 m.mDiffuseColor.g = 1.0f; 1451 m.mDiffuseColor.b = 0.0f; 1452 } 1453 1454 exporter->SetForcedMaterial(m); 1455 return; 1456 } 1457 1458 case 1: // pvs 1459 { 1460 importance = (float)vc->GetPvs().GetSize() / 1461 (float)mViewCellsStats.maxPvs; 1462 1463 } 1464 break; 1465 case 2: // merges 1466 { 1467 int lSize = mViewCellsTree->GetSize(vc); 1468 importance = (float)lSize / (float)mViewCellsStats.maxLeaves; 1469 } 1470 //break; 1471 case 3: // merge tree differene 1472 { 1473 // TODO 1474 //importance = (float)GetMaxTreeDiff(vc) / 1475 // (float)(mVspBspTree->GetStatistics().maxDepth * 2); 1476 1477 } 1478 break; 1479 default: 1480 break; 1481 } 1482 1483 // special color code for invalid view cells 1484 m.mDiffuseColor.r = importance; 1485 m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 1486 m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f; 1487 1488 //Debug << "importance: " << importance << endl; 1489 exporter->SetForcedMaterial(m); 1490 } 1491 1492 1493 void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 1494 ViewCell *vc, 1495 const Plane3 *cuttingPlane) const 1496 { 1497 if (vc->GetMesh()) 1498 { 1499 exporter->ExportMesh(vc->GetMesh()); 1500 return; 1501 } 1502 1503 BspNodeGeometry geom; 1504 mBspTree->ConstructGeometry(vc, geom); 1505 1506 1507 if (cuttingPlane) 1508 { 1509 BspNodeGeometry front; 1510 BspNodeGeometry back; 1511 1512 geom.SplitGeometry(front, 1513 back, 1514 *cuttingPlane, 1515 mViewSpaceBox, 1516 0.0001f); 1517 1518 if ((int)back.mPolys.size() >= 3) 1519 exporter->ExportPolygons(back.mPolys); 1520 } 1521 else 1522 { 1523 1524 exporter->ExportPolygons(geom.mPolys); 1525 } 1526 } 1527 1528 1529 void BspViewCellsManager::CreateMesh(ViewCell *vc) 1530 { 1531 if (vc->GetMesh()) 1532 delete vc->GetMesh(); 1533 1534 BspNodeGeometry geom; 1535 1536 mBspTree->ConstructGeometry(vc, geom); 1537 1538 Mesh *mesh = new Mesh(); 1539 geom.AddToMesh(*mesh); 1540 vc->SetMesh(mesh); 1541 mMeshContainer.push_back(mesh); 1542 } 1543 1544 1545 void BspViewCellsManager::Finalize(ViewCell *viewCell, 1546 const bool createMesh) 1547 { 1548 CreateMesh(viewCell); 1549 1550 float area = 0; 1551 float volume = 0; 1552 1553 ViewCellContainer leaves; 1554 mViewCellsTree->CollectLeaves(viewCell, leaves); 1555 1556 ViewCellContainer::const_iterator it, it_end = leaves.end(); 1557 1558 for (it = leaves.begin(); it != it_end; ++ it) 1559 { 1560 BspNodeGeometry geom; 1561 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 1562 mBspTree->ConstructGeometry(leaf, geom); 1563 1564 area += geom.GetArea(); 1565 volume += geom.GetVolume(); 1566 } 1567 1568 viewCell->SetVolume(volume); 1569 viewCell->SetArea(area); 1570 } 1571 1572 1573 ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point) const 1574 { 1575 if (!mBspTree) 1576 return NULL; 1577 1578 if (!mViewSpaceBox.IsInside(point)) 1579 return NULL; 1580 1581 return mBspTree->GetViewCell(point); 1582 } 1583 1584 1585 void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 1586 vector<MergeCandidate> &candidates) 1587 { 1588 cout << "collecting merge candidates ... " << endl; 1589 1590 if (mUseRaysForMerge) 1591 { 1592 mBspTree->CollectMergeCandidates(rays, candidates); 1593 } 1594 else 1595 { 1596 vector<BspLeaf *> leaves; 1597 mBspTree->CollectLeaves(leaves); 1598 mBspTree->CollectMergeCandidates(leaves, candidates); 1599 } 1600 1601 cout << "fininshed collecting candidates" << endl; 1602 } 1603 1604 1605 1606 bool BspViewCellsManager::ExportViewCells(const string filename) 1607 { 1608 cout << "exporting view cells to xml ... "; 1609 std::ofstream stream; 1610 1611 // for output we need unique ids for each view cell 1612 CreateUniqueViewCellIds(); 1613 1614 1615 stream.open(filename.c_str()); 1616 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl; 1617 stream << "<Visibility_Solution>" << endl; 1618 1619 //-- the view space bounding box 1620 stream << "<ViewSpaceBox" 1621 << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\"" 1622 << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl; 1623 1624 //-- the type of the view cells hierarchy 1625 //stream << "<Hierarchy name=\"bspTree\" />" << endl; 1626 stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free 1627 //-- load the view cells itself, i.e., the ids and the pvs 1628 stream << "<ViewCells>" << endl; 1629 ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 1630 for (it = mViewCells.begin(); it != it_end; ++ it) 1631 ExportViewCell(*it, stream); 1632 1633 stream << "</ViewCells>" << endl; 1634 1635 //-- load the hierarchy 1636 stream << "<Hierarchy>" << endl; 1637 mBspTree->Export(stream); 1638 stream << endl << "</Hierarchy>" << endl; 1639 1640 stream << "</Visibility_Solution>" << endl; 1641 stream.close(); 1642 1643 cout << "finished" << endl; 1644 1645 return true; 1646 } 1647 1648 1649 void BspViewCellsManager::AddCurrentViewCellsToHierarchy() 1650 { 1651 ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 1652 for (it = mViewCells.begin(); it != it_end; ++ it) 1653 { 1654 ViewCell *vc = *it; 1655 ViewCellContainer leaves; 1656 mViewCellsTree->CollectLeaves(vc, leaves); 1657 1658 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 1659 1660 for (lit = leaves.begin(); lit != lit_end; ++ lit) 1661 { 1662 BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit); 1663 bspVc->mLeaf->SetViewCell(vc); 1664 } 1665 } 1666 } 1667 1668 /************************************************************************/ 1669 /* KdViewCellsManager implementation */ 1670 /************************************************************************/ 1671 1672 1673 1674 KdViewCellsManager::KdViewCellsManager(KdTree *kdTree): 1675 ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100) 1676 { 1677 } 1678 1679 float KdViewCellsManager::GetProbability(ViewCell *viewCell) 1680 { 1681 // compute view cell area / volume as subsititute for probability 1682 #if 0 1683 return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 1684 #endif 1685 #if 1 1686 return GetArea(viewCell) / GetAccVcArea(); 1687 #endif 1688 #if 0 1689 return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 1690 #endif 1691 } 1692 1693 1694 float KdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const 1695 { 1696 return viewCell->GetPvs().GetSize() * objRendercost; 1697 } 1698 1699 1700 void KdViewCellsManager::CollectViewCells() 1701 { 1702 //mKdTree->CollectViewCells(mViewCells); TODO 1703 } 1704 1705 1706 int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 1707 const VssRayContainer &rays) 1708 { 1709 // if view cells already constructed 1710 if (ViewCellsConstructed()) 1711 return 0; 1712 1713 mKdTree->Construct(); 1714 1715 mTotalAreaValid = false; 1716 // create the view cells 1717 mKdTree->CreateAndCollectViewCells(mViewCells); 1718 1719 // cast rays 1720 ComputeSampleContributions(rays, true, false); 1721 1722 EvaluateViewCellsStats(); 1723 Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 1724 1725 return 0; 1726 } 1727 1728 1729 bool KdViewCellsManager::ViewCellsConstructed() const 1730 { 1731 return mKdTree->GetRoot() != NULL; 1732 } 1733 1734 int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 1735 const VssRayContainer &rays) 1736 { 1737 return 0; 1738 } 1739 1740 void KdViewCellsManager::Visualize(const ObjectContainer &objects, 1741 const VssRayContainer &sampleRays) 1742 { 1743 if (!ViewCellsConstructed()) 1744 return; 1745 1746 // using view cells instead of the kd PVS of objects 1747 const bool useViewCells = true; 1748 bool exportRays = false; 1749 1750 int limit = min(mVisualizationSamples, (int)sampleRays.size()); 1751 const int pvsOut = min((int)objects.size(), 10); 1752 VssRayContainer *rays = new VssRayContainer[pvsOut]; 1753 1754 if (useViewCells) 1755 { 1756 const int leafOut = 10; 1757 1758 ViewCell::NewMail(); 1759 1760 //-- some rays for output 1761 const int raysOut = min((int)sampleRays.size(), mVisualizationSamples); 1762 Debug << "visualization using " << raysOut << " samples" << endl; 1763 1764 //-- some random view cells and rays for output 1765 vector<KdLeaf *> kdLeaves; 1766 1767 for (int i = 0; i < leafOut; ++ i) 1768 kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf())); 1769 1770 for (int i = 0; i < kdLeaves.size(); ++ i) 1771 { 1772 KdLeaf *leaf = kdLeaves[i]; 1773 RayContainer vcRays; 1774 1775 cout << "creating output for view cell " << i << " ... "; 1776 #if 0 1777 // check whether we can add the current ray to the output rays 1778 for (int k = 0; k < raysOut; ++ k) 1779 { 1780 Ray *ray = sampleRays[k]; 1781 1782 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 1783 { 1784 BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf; 1785 1786 if (leaf->GetViewCell() == leaf2->GetViewCell()) 1787 { 1788 vcRays.push_back(ray); 1789 } 1790 } 1791 } 1792 #endif 1793 Intersectable::NewMail(); 1794 1795 ViewCell *vc = leaf->mViewCell; 1796 1797 //bspLeaves[j]->Mail(); 1798 char s[64]; sprintf(s, "kd-pvs%04d.x3d", i); 1799 1800 Exporter *exporter = Exporter::GetExporter(s); 1801 exporter->SetFilled(); 1802 1803 exporter->SetWireframe(); 1804 //exporter->SetFilled(); 1805 1806 Material m;//= RandomMaterial(); 1807 m.mDiffuseColor = RgbColor(1, 1, 0); 1808 exporter->SetForcedMaterial(m); 1809 1810 AxisAlignedBox3 box = mKdTree->GetBox(leaf); 1811 exporter->ExportBox(box); 1812 1813 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 1814 << ", piercing rays=" << (int)vcRays.size() << endl; 1815 1816 // export rays piercing this view cell 1817 exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0)); 1818 1819 m.mDiffuseColor = RgbColor(1, 0, 0); 1820 exporter->SetForcedMaterial(m); 1821 1822 // exporter->SetWireframe(); 1823 exporter->SetFilled(); 1824 1825 ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end(); 1826 // output PVS of view cell 1827 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 1828 { 1829 Intersectable *intersect = (*it).first; 1830 if (!intersect->Mailed()) 1831 { 1832 exporter->ExportIntersectable(intersect); 1833 intersect->Mail(); 1834 } 1835 } 1836 1837 DEL_PTR(exporter); 1838 cout << "finished" << endl; 1839 } 1840 1841 DEL_PTR(rays); 1842 } 1843 else // using kd PVS of objects 1844 { 1845 for (int i = 0; i < limit; ++ i) 1846 { 1847 VssRay *ray = sampleRays[i]; 1848 1849 // check whether we can add this to the rays 1850 for (int j = 0; j < pvsOut; j++) 1851 { 1852 if (objects[j] == ray->mTerminationObject) 1853 { 1854 rays[j].push_back(ray); 1855 } 1856 } 1857 } 1858 1859 if (exportRays) 1860 { 1861 Exporter *exporter = NULL; 1862 exporter = Exporter::GetExporter("sample-rays.x3d"); 1863 exporter->SetWireframe(); 1864 exporter->ExportKdTree(*mKdTree); 1865 1866 for (i=0; i < pvsOut; i++) 1867 exporter->ExportRays(rays[i], RgbColor(1, 0, 0)); 1868 1869 exporter->SetFilled(); 1870 1871 delete exporter; 1872 } 1873 1874 for (int k=0; k < pvsOut; k++) 1875 { 1876 Intersectable *object = objects[k]; 1877 char s[64]; 1878 sprintf(s, "sample-pvs%04d.x3d", k); 1879 1880 Exporter *exporter = Exporter::GetExporter(s); 1881 exporter->SetWireframe(); 1882 1883 KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); 1884 Intersectable::NewMail(); 1885 1886 // avoid adding the object to the list 1887 object->Mail(); 1888 ObjectContainer visibleObjects; 1889 1890 for (; i != object->mKdPvs.mEntries.end(); i++) 1891 { 1892 KdNode *node = (*i).first; 1893 exporter->ExportBox(mKdTree->GetBox(node)); 1894 1895 mKdTree->CollectObjects(node, visibleObjects); 1896 } 1897 1898 exporter->ExportRays(rays[k], RgbColor(0, 1, 0)); 1899 exporter->SetFilled(); 1900 1901 for (int j = 0; j < visibleObjects.size(); j++) 1902 exporter->ExportIntersectable(visibleObjects[j]); 1903 1904 Material m; 1905 m.mDiffuseColor = RgbColor(1, 0, 0); 1906 exporter->SetForcedMaterial(m); 1907 exporter->ExportIntersectable(object); 1908 1909 delete exporter; 1910 } 1911 } 1912 } 1913 1914 1915 void KdViewCellsManager::ExportColor(Exporter *exporter, 1916 ViewCell *vc) const 1917 { 1918 // TODO 1919 } 1920 1921 ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const 1922 { 1923 return new KdViewCell(mesh); 1924 } 1925 1926 1927 void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 1928 ViewCell *vc, 1929 const Plane3 *cuttingPlane) const 1930 { 1931 ViewCellContainer leaves; 1932 1933 mViewCellsTree->CollectLeaves(vc, leaves); 1934 ViewCellContainer::const_iterator it, it_end = leaves.end(); 1935 1936 for (it = leaves.begin(); it != it_end; ++ it) 1937 { 1938 KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it); 1939 1940 exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf)); 1941 } 1942 } 1943 1944 1945 int KdViewCellsManager::GetType() const 1946 { 1947 return ViewCellsManager::KD; 1948 } 1949 1950 1951 1952 KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf) 1953 { 1954 KdNode *node = leaf; 1955 1956 while (node->mParent && node->mDepth > mKdPvsDepth) 1957 node = node->mParent; 1958 return node; 1959 } 1960 1961 int KdViewCellsManager::CastLineSegment(const Vector3 &origin, 1962 const Vector3 &termination, 1963 ViewCellContainer &viewcells) 1964 { 1965 return mKdTree->CastLineSegment(origin, termination, viewcells); 1966 } 1967 1968 1969 void KdViewCellsManager::CreateMesh(ViewCell *vc) 1970 { 1971 // TODO 1972 } 1973 1974 1975 1976 void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 1977 vector<MergeCandidate> &candidates) 1978 { 1979 // TODO 1980 } 1981 1982 1983 /**********************************************************************/ 1984 /* VspKdViewCellsManager implementation */ 1985 /**********************************************************************/ 1986 1987 1988 VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree): 1989 ViewCellsManager(), mVspKdTree(vspKdTree) 1990 { 1991 environment->GetIntValue("VspKdTree.Construction.samples", mInitialSamples); 1992 mVspKdTree->SetViewCellsManager(this); 1993 } 1994 1995 float VspKdViewCellsManager::GetProbability(ViewCell *viewCell) 1996 { 1997 // volume or area substitutes for view point probability 1998 #if 0 1999 return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 2000 #else 2001 return GetArea(viewCell) / GetAccVcArea(); 2002 #endif 2003 } 2004 2005 2006 float VspKdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const 2007 { 2008 return viewCell->GetPvs().GetSize() * objRendercost; 2009 } 2010 2011 2012 void VspKdViewCellsManager::CollectViewCells() 2013 { 2014 mVspKdTree->CollectViewCells(mViewCells); 2015 } 2016 2017 2018 int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 2019 const VssRayContainer &rays) 2020 { 2021 // if view cells already constructed 2022 if (ViewCellsConstructed()) 2023 return 0; 2024 2025 VssRayContainer constructionRays; 2026 VssRayContainer savedRays; 2027 2028 GetRaySets(rays, 2029 mInitialSamples, 2030 constructionRays, 2031 &savedRays); 2032 2033 Debug << "constructing vsp kd tree using " 2034 << (int)constructionRays.size() << " samples" << endl; 2035 2036 mVspKdTree->Construct(constructionRays, &mViewSpaceBox); 2037 Debug << mVspKdTree->GetStatistics() << endl; 2038 2039 // export leaf building blocks 2040 ExportLeaves(objects, rays); 2041 2042 // finally merge kd leaf building blocks to view cells 2043 const int merged = mVspKdTree->MergeViewCells(rays); 2044 2045 // collapse siblings belonging to the same view cell 2046 mVspKdTree->RefineViewCells(rays); 2047 2048 // collapse siblings belonging to the same view cell 2049 mVspKdTree->CollapseTree(); 2050 2051 // evaluale view cell stats 2052 ResetViewCells(); 2053 2054 Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 2055 2056 long startTime = GetTime(); 2057 // recast rest of rays 2058 ComputeSampleContributions(savedRays, true, false); 2059 2060 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 2061 << " secs" << endl; 2062 2063 return merged; 2064 } 2065 2066 bool VspKdViewCellsManager::ViewCellsConstructed() const 2067 { 2068 return mVspKdTree->GetRoot() != NULL; 2069 } 2070 2071 2072 ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const 2073 { 2074 return new VspKdViewCell(mesh); 2075 } 2076 2077 int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects, 2078 const VssRayContainer &rays) 2079 { 2080 if (!ViewCellsConstructed()) 2081 return 0; 2082 2083 // recalculate stats 2084 EvaluateViewCellsStats(); 2085 2086 return 0; 2087 } 2088 2089 2090 void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects, 2091 const VssRayContainer &sampleRays) 2092 { 2093 if (!ViewCellsConstructed()) 2094 return; 2095 2096 //-- export leaf building blocks 2097 Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d"); 2098 if (!exporter) 2099 return; 2100 2101 if (mExportGeometry) 2102 exporter->ExportGeometry(objects); 2103 2104 //exporter->SetWireframe(); 2105 //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize); 2106 exporter->ExportVspKdTree(*mVspKdTree); 2107 2108 if (mExportRays) 2109 { 2110 const float prob = (float)mVisualizationSamples 2111 / ((float)sampleRays.size() + Limits::Small); 2112 2113 exporter->SetWireframe(); 2114 2115 //-- collect uniformly distributed rays 2116 VssRayContainer rays; 2117 2118 for (int i = 0; i < sampleRays.size(); ++ i) 2119 { 2120 if (RandomValue(0,1) < prob) 2121 rays.push_back(sampleRays[i]); 2122 } 2123 exporter->ExportRays(rays, RgbColor(1, 0, 0)); 2124 } 2125 2126 delete exporter; 2127 } 2128 2129 void VspKdViewCellsManager::Visualize(const ObjectContainer &objects, 2130 const VssRayContainer &sampleRays) 2131 { 2132 if (!ViewCellsConstructed()) 2133 return; 2134 2135 //-- export single view cells 2136 for (int i = 0; i < 10; ++ i) 2137 { 2138 char s[64]; 2139 sprintf(s, "vsp_viewcell%04d.x3d", i); 2140 Exporter *exporter = Exporter::GetExporter(s); 2141 const int idx = 2142 (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1)); 2143 2144 VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]); 2145 2146 cout << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl; 2147 Debug << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl; 2148 //-- export geometry 2149 Material m; 2150 m.mDiffuseColor = RgbColor(0, 1, 1); 2151 2152 exporter->SetForcedMaterial(m); 2153 exporter->SetWireframe(); 2154 2155 ExportViewCellGeometry(exporter, vc); 2156 2157 //-- export stored rays 2158 2159 if (mExportRays) 2160 { 2161 ViewCellContainer leaves; 2162 mViewCellsTree->CollectLeaves(vc, leaves); 2163 2164 ViewCellContainer::const_iterator it, 2165 it_end = leaves.end(); 2166 2167 for (it = leaves.begin(); it != it_end; ++ it) 2168 { 2169 VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it); 2170 VspKdLeaf *leaf = vspKdVc->mLeaf; 2171 AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf); 2172 2173 VssRayContainer vssRays; 2174 2175 VssRayContainer castRays; 2176 VssRayContainer initRays; 2177 2178 leaf->GetRays(vssRays); 2179 2180 VssRayContainer::const_iterator it, it_end = vssRays.end(); 2181 const float prop = 200.0f / (float)vssRays.size(); 2182 2183 for (it = vssRays.begin(); it != it_end; ++ it) 2184 { 2185 if (Random(1) < prop) 2186 if ((*it)->mTerminationObject == NULL) 2187 castRays.push_back(*it); 2188 else 2189 initRays.push_back(*it); 2190 } 2191 2192 exporter->ExportRays(castRays, RgbColor(1, 0, 0)); 2193 exporter->ExportRays(initRays, RgbColor(0, 1, 0)); 2194 } 2195 } 2196 2197 //-- output PVS of view cell 2198 m.mDiffuseColor = RgbColor(1, 0, 0); 2199 exporter->SetForcedMaterial(m); 2200 2201 Intersectable::NewMail(); 2202 2203 ObjectPvsMap::const_iterator it, 2204 it_end = vc->GetPvs().mEntries.end(); 2205 2206 exporter->SetFilled(); 2207 2208 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 2209 { 2210 Intersectable *intersect = (*it).first; 2211 2212 if (!intersect->Mailed()) 2213 { 2214 Material m = RandomMaterial(); 2215 exporter->SetForcedMaterial(m); 2216 2217 exporter->ExportIntersectable(intersect); 2218 intersect->Mail(); 2219 } 2220 } 2221 2222 delete exporter; 2223 } 2224 2225 //-- export final view cells 2226 Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d"); 2227 2228 //if (exportGeometry) exporter->SetWireframe(); 2229 //else exporter->SetFilled(); 2230 2231 ExportViewCellsForViz(exporter); 2232 2233 if (mExportGeometry) 2234 { 2235 exporter->SetFilled(); 2236 exporter->ExportGeometry(objects); 2237 } 2238 2239 if (mExportRays) 2240 { 2241 const float prob = (float)mVisualizationSamples 2242 / ((float)sampleRays.size() + Limits::Small); 2243 2244 exporter->SetWireframe(); 2245 2246 VssRayContainer rays; 2247 2248 for (int i = 0; i < sampleRays.size(); ++ i) 2249 { 2250 if (RandomValue(0,1) < prob) 2251 rays.push_back(sampleRays[i]); 2252 } 2253 exporter->ExportRays(rays, RgbColor(1, 0, 0)); 2254 } 2255 2256 delete exporter; 2257 } 2258 2259 int VspKdViewCellsManager::GetType() const 2260 { 2261 return VSP_KD; 2262 } 2263 2264 2265 int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin, 2266 const Vector3 &termination, 2267 ViewCellContainer &viewcells) 2268 { 2269 return mVspKdTree->CastLineSegment(origin, termination, viewcells); 2270 } 2271 2272 2273 void VspKdViewCellsManager::ExportColor(Exporter *exporter, 2274 ViewCell *vc) const 2275 { 2276 if (mColorCode == 0) // Random color 2277 return; 2278 2279 float importance = 0; 2280 2281 switch (mColorCode) 2282 { 2283 case 1: // pvs 2284 { 2285 importance = (float)vc->GetPvs().GetSize() / 2286 (float)mViewCellsStats.maxPvs; 2287 } 2288 break; 2289 case 2: // merged leaves 2290 { 2291 int lSize = mViewCellsTree->GetSize(vc); 2292 importance = (float)lSize / 2293 (float)mViewCellsStats.maxLeaves; 2294 } 2295 break; 2296 case 3: // merged tree depth difference 2297 { 2298 //importance = (float)GetMaxTreeDiff(vc) / 2299 // (float)(mVspBspTree->GetStatistics().maxDepth * 2); 2300 } 2301 break; 2302 default: 2303 break; 2304 } 2305 2306 Material m; 2307 m.mDiffuseColor.b = 1.0f; 2308 m.mDiffuseColor.r = importance; 2309 m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 2310 //Debug << "importance: " << importance << endl; 2311 exporter->SetForcedMaterial(m); 2312 } 2313 2314 2315 void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 2316 ViewCell *vc, 2317 const Plane3 *cuttingPlane) const 2318 { 2319 VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc); 2320 2321 Mesh m; 2322 2323 ViewCellContainer leaves; 2324 mViewCellsTree->CollectLeaves(vc, leaves); 2325 2326 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2327 2328 for (it = leaves.begin(); it != it_end; ++ it) 2329 { 2330 VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf; 2331 mVspKdTree->GetBBox(l).AddBoxToMesh(&m); 2332 } 2333 2334 exporter->ExportMesh(&m); 2335 } 2336 2337 2338 void VspKdViewCellsManager::CreateMesh(ViewCell *vc) 2339 { 2340 //TODO 2341 } 2342 2343 2344 void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 2345 vector<MergeCandidate> &candidates) 2346 { 2347 // TODO 2348 } 2349 2350 2351 /**************************************************************************/ 2352 /* VspBspViewCellsManager implementation */ 2353 /**************************************************************************/ 2354 2355 2356 VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree): 2357 ViewCellsManager(), mVspBspTree(vspBspTree) 2358 { 2359 environment->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 2360 mVspBspTree->SetViewCellsManager(this); 2361 mVspBspTree->mViewCellsTree = mViewCellsTree; 2362 } 2363 2364 2365 VspBspViewCellsManager::~VspBspViewCellsManager() 2366 { 2367 } 2368 2369 2370 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell) 2371 { 2372 if (0 && mVspBspTree->mUseAreaForPvs) 2373 return GetArea(viewCell) / GetAccVcArea(); 2374 else 2375 return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 2376 } 2377 2378 2379 void VspBspViewCellsManager::CollectViewCells() 2380 { 2381 // view cells tree constructed 2382 if (!ViewCellsTreeConstructed()) 2383 { 2384 mVspBspTree->CollectViewCells(mViewCells, false); 2385 } 2386 else 2387 { 2388 // we can use the view cells tree hierarchy to get the right set 2389 mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells); 2390 } 2391 2392 } 2393 2394 2395 float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell, 2396 float objRendercost) const 2397 { 2398 return viewCell->GetPvs().GetSize() * objRendercost; 2399 } 2400 2401 2402 bool VspBspViewCellsManager::ViewCellsConstructed() const 2403 { 2404 return mVspBspTree->GetRoot() != NULL; 2405 } 2406 2407 2408 ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const 2409 { 2410 return new BspViewCell(mesh); 2411 } 2412 2413 2414 /*void VspBspViewCellsManager::CollectNodes(ViewCell *vc, vector<BspNode *>nodes) 2415 { 2416 void ViewCellsTree::CollectLeaves(ViewCell *vc, vector<BspNode *> &nodes) const 2417 2418 if (vc->IsLeaf()) 2419 { 2420 BspViewCell *bvc = dynamic_cast<BspViewCell *>(vc); 2421 nodes->push_back(bvc->mLeaf); 2422 } 2423 else 2424 { 2425 ViewCellContainer::const_iterator it, it_end = interior->mChildren.end(); 2426 2427 for (it = interior->mChildren.begin; it != it_end; ++ it) 2428 { 2429 vector<BspNode *> mynodes; 2430 CollectNodes(*it, mynodes); 2431 2432 if (mynodes[0]->GetParent() && (mynodes[0]->GetParent() == mynodes[1]->GetParent())) 2433 { 2434 nodes.push_back(nodes[0]->GetParent()); 2435 } 2436 2437 } 2438 } 2439 }*/ 2440 2441 2442 int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 2443 const VssRayContainer &rays) 2444 { 2445 // if view cells were already constructed 2446 if (ViewCellsConstructed()) 2447 return 0; 2448 2449 Debug << "Constructing bsp view cells" << endl; 2450 2451 int sampleContributions = 0; 2452 2453 VssRayContainer sampleRays; 2454 2455 int limit = min (mInitialSamples, (int)rays.size()); 2456 2457 VssRayContainer constructionRays; 2458 VssRayContainer savedRays; 2459 2460 Debug << "samples used for subdivision: " << mInitialSamples 2461 << " rays: " << (int)rays.size() << endl; 2462 2463 GetRaySets(rays, mInitialSamples, constructionRays, &savedRays); 2464 2465 Debug << "initial rays: " << (int)constructionRays.size() << endl; 2466 Debug << "saved rays: " << (int)savedRays.size() << endl; 2467 2468 mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size()); 2469 2470 mVspBspTree->Construct(constructionRays, &mViewSpaceBox); 2471 2472 Debug << mVspBspTree->GetStatistics() << endl; 2473 2474 // collapse invalid regions 2475 cout << "collapsing invalid tree regions ... "; 2476 long startTime = GetTime(); 2477 int collapsedLeaves = mVspBspTree->CollapseTree(); 2478 Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3 2479 << " seconds" << endl; 2480 2481 cout << "finished" << endl; 2482 2483 cout << "reseting view cell stats ... "; 2484 ResetViewCells(); 2485 cout << "finished" << endl; 2486 2487 Debug << "\nView cells after construction:\n" << mViewCellsStats << endl; 2488 2489 if (1) // export initial view cells 2490 { 2491 cout << "exporting initial view cells (=leaves) ... "; 2492 Exporter *exporter = Exporter::GetExporter("view_cells.x3d"); 2493 2494 if (exporter) 2495 { 2496 if (0 && mExportRays) 2497 exporter->ExportRays(rays, RgbColor(1, 1, 1)); 2498 2499 if (mExportGeometry) 2500 exporter->ExportGeometry(objects); 2501 2502 //exporter->SetWireframe(); 2503 exporter->SetFilled(); 2504 ExportViewCellsForViz(exporter); 2505 2506 delete exporter; 2507 } 2508 cout << "finished" << endl; 2509 } 2510 2511 startTime = GetTime(); 2512 2513 // reset view cells and stats 2514 ResetViewCells(); 2515 2516 cout << "Computing remaining ray contributions ... "; 2517 // recast rest of rays 2518 ComputeSampleContributions(savedRays, true, false); 2519 cout << "finished" << endl; 2520 2521 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 2522 << " secs" << endl; 2523 2524 cout << "construction finished" << endl; 2525 2526 return sampleContributions; 2527 } 2528 2529 2530 void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays, 2531 const ObjectContainer &objects) 2532 { 2533 //-- post processing of bsp view cells 2534 int vcSize = 0; 2535 int pvsSize = 0; 2536 2537 mRenderer->RenderScene(); 2538 SimulationStatistics ss; 2539 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 2540 Debug << ss << endl; 2541 2542 //-- merge or subdivide view cells 2543 int merged = 0; 2544 if (mMergeViewCells) 2545 { 2546 cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl; 2547 long startTime = GetTime(); 2548 2549 2550 // TODO: should be done BEFORE the ray casting 2551 merged = mViewCellsTree->ConstructMergeTree(rays, objects); 2552 2553 //-- stats and visualizations 2554 cout << "finished merging" << endl; 2555 cout << "merged " << merged << " view cells in " 2556 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 2557 2558 Debug << "Postprocessing: Merged " << merged << " view cells in " 2559 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 2560 } 2561 2562 int savedColorCode = mColorCode; 2563 2564 //BspLeaf::NewMail(); 2565 if (1) // export merged view cells 2566 { 2567 mColorCode = 0; 2568 cout << "reseting view cells ... "; 2569 ResetViewCells(); 2570 2571 cout << "finished" << endl; 2572 2573 Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d"); 2574 Debug << "\nView cells after merge:\n" << mViewCellsStats << endl; 2575 2576 cout << "exporting view cells after merge ... "; 2577 2578 if (exporter) 2579 { 2580 if (0) 2581 exporter->SetWireframe(); 2582 else 2583 exporter->SetFilled(); 2584 2585 ExportViewCellsForViz(exporter); 2586 2587 if (mExportGeometry) 2588 { 2589 Material m; 2590 m.mDiffuseColor = RgbColor(0, 1, 0); 2591 exporter->SetForcedMaterial(m); 2592 exporter->SetFilled(); 2593 2594 exporter->ExportGeometry(objects); 2595 } 2596 2597 delete exporter; 2598 } 2599 cout << "finished" << endl; 2600 } 2601 2602 if (1) // export merged view cells 2603 { 2604 mColorCode = 1; 2605 2606 Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d"); 2607 2608 cout << "exporting view cells after merge (pvs size) ... "; 2609 2610 if (exporter) 2611 { 2612 if (0) 2613 exporter->SetWireframe(); 2614 else 2615 exporter->SetFilled(); 2616 2617 ExportViewCellsForViz(exporter); 2618 2619 if (mExportGeometry) 2620 { 2621 Material m; 2622 m.mDiffuseColor = RgbColor(0, 1, 0); 2623 exporter->SetForcedMaterial(m); 2624 exporter->SetFilled(); 2625 2626 exporter->ExportGeometry(objects); 2627 } 2628 2629 delete exporter; 2630 } 2631 cout << "finished" << endl; 2632 } 2633 2634 mColorCode = savedColorCode; 2635 2636 } 2637 2638 2639 void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays, 2640 const ObjectContainer &objects) 2641 { 2642 Debug << "render time before refine:" << endl; 2643 mRenderer->RenderScene(); 2644 SimulationStatistics ss; 2645 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 2646 Debug << ss << endl; 2647 2648 cout << "Refining the merged view cells ... "; 2649 long startTime = GetTime(); 2650 2651 // refining the merged view cells 2652 const int refined = mViewCellsTree->RefineViewCells(rays, objects); 2653 2654 //-- stats and visualizations 2655 cout << "finished" << endl; 2656 cout << "refined " << refined << " view cells in " 2657 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 2658 2659 Debug << "Postprocessing: refined " << refined << " view cells in " 2660 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 2661 } 2662 2663 2664 int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects, 2665 const VssRayContainer &rays) 2666 { 2667 if (!ViewCellsConstructed()) 2668 { 2669 Debug << "postprocess error: no view cells constructed" << endl; 2670 return 0; 2671 } 2672 2673 2674 // view cells already finished before post processing step (i.e. because they were loaded) 2675 if (mViewCellsFinished) 2676 { 2677 FinalizeViewCells(true); 2678 EvaluateViewCellsStats(); 2679 2680 return 0; 2681 } 2682 2683 2684 // check if new view cells turned invalid 2685 SetValidity(mMinPvsSize, mMaxPvsSize); 2686 // update valid view space according to valid view cells 2687 mVspBspTree->ValidateTree(); 2688 2689 // recompute view cell statistics 2690 mViewCellsStats.Reset(); 2691 EvaluateViewCellsStats(); 2692 2693 // has to be recomputed 2694 mTotalAreaValid = false; 2695 2696 2697 VssRayContainer postProcessRays; 2698 GetRaySets(rays, mPostProcessSamples, postProcessRays); 2699 2700 Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl; 2701 2702 Debug << "\nview cell partition after sampling:\n" << mViewCellsStats << endl << endl; 2703 2704 // should maybe be done here to allow merge working with area or volume 2705 // and to correct the rendering statistics 2706 if (0) 2707 { 2708 FinalizeViewCells(false); 2709 } 2710 2711 //-- merge the individual view cells 2712 MergeViewCells(postProcessRays, objects); 2713 2714 2715 //-- refines the merged view cells 2716 if (0) 2717 RefineViewCells(postProcessRays, objects); 2718 2719 2720 if (1) 2721 { 2722 float totalCost, erc, var, dev, avg; 2723 int totalpvs; 2724 2725 mViewCellsStats.Reset(); 2726 2727 EvaluateRenderStatistics(totalCost, erc, dev, var, totalpvs, avg); 2728 2729 Debug << "statistics after merge " 2730 << " erc: " << erc 2731 << " dev: " << dev 2732 << " totalpvs: " << totalpvs 2733 << " avg: " << avg << endl; 2734 } 2735 2736 //-- render simulation after merge 2737 cout << "\nevaluating bsp view cells render time before compress ... "; 2738 dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene(); 2739 SimulationStatistics ss; 2740 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 2741 2742 cout << " finished" << endl; 2743 cout << ss << endl; 2744 Debug << ss << endl; 2745 2746 2747 2748 //-- compression 2749 2750 if (ViewCellsTreeConstructed() && mCompressViewCells) 2751 { 2752 int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 2753 Debug << "number of entries before compress: " << pvsEntries << endl; 2754 2755 mViewCellsTree->CompressViewCellsPvs(); 2756 2757 pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 2758 Debug << "number of entries after compress: " << pvsEntries << endl; 2759 } 2760 2761 2762 //-- export refined (shuffled) view cells 2763 if (0) 2764 { 2765 cout << "exporting shuffled view cells ... "; 2766 2767 Exporter *exporter = Exporter::GetExporter("shuffled_view_cells.x3d"); 2768 if (exporter) 2769 { 2770 if (1) 2771 { 2772 exporter->SetWireframe(); 2773 exporter->ExportBox(mViewSpaceBox); 2774 exporter->SetFilled(); 2775 } 2776 2777 if (mExportGeometry) 2778 { 2779 exporter->ExportGeometry(objects); 2780 } 2781 2782 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 2783 2784 Material vm, lm; 2785 2786 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 2787 { 2788 ViewCell *vc = *vit; 2789 2790 vm = RandomMaterial(); 2791 2792 lm = vm; 2793 2794 vm.mDiffuseColor.r -= 0.45f; 2795 vm.mDiffuseColor.g -= 0.45f; 2796 vm.mDiffuseColor.b -= 0.45f; 2797 2798 2799 ViewCellContainer leaves; 2800 mViewCellsTree->CollectLeaves(vc, leaves); 2801 2802 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 2803 2804 for (lit = leaves.begin(); lit != lit_end; ++ lit) 2805 { 2806 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 2807 2808 if (leaf->Mailed()) 2809 exporter->SetForcedMaterial(lm); 2810 else 2811 exporter->SetForcedMaterial(vm); 2812 2813 BspNodeGeometry geom; 2814 mVspBspTree->ConstructGeometry(leaf, geom); 2815 exporter->ExportPolygons(geom.mPolys); 2816 } 2817 } 2818 2819 delete exporter; 2820 } 2821 2822 2823 cout << "finished" << endl; 2824 } 2825 2826 // collapse sibling leaves that share the same view cell 2827 if (0) 2828 mVspBspTree->CollapseTree(); 2829 2830 // recompute view cell list and statistics 2831 ResetViewCells(); 2832 2833 // real meshes are only contructed only at this stage 2834 FinalizeViewCells(true); 2835 2836 // write view cells to disc 2837 if (mExportViewCells) 2838 { 2839 char buff[100]; 2840 environment->GetStringValue("ViewCells.filename", buff); 2841 string vcFilename(buff); 2842 2843 ExportViewCells(buff); 2844 } 2845 2846 return 0; 2847 } 2848 2849 2850 int VspBspViewCellsManager::GetType() const 2851 { 2852 return VSP_BSP; 2853 } 2854 2855 2856 bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const 2857 { 2858 if (!ViewCellsConstructed()) 2859 return ViewCellsManager::GetViewPoint(viewPoint); 2860 2861 // TODO: set reasonable limit 2862 const int limit = 20; 2863 2864 for (int i = 0; i < limit; ++ i) 2865 { 2866 viewPoint = mViewSpaceBox.GetRandomPoint(); 2867 if (mVspBspTree->ViewPointValid(viewPoint)) 2868 { 2869 return true; 2870 } 2871 } 2872 Debug << "failed to find valid view point, taking " << viewPoint << endl; 2873 return false; 2874 } 2875 2876 2877 bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const 2878 { 2879 // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic 2880 // validy update in preprocessor for all managers) 2881 return ViewCellsManager::ViewPointValid(viewPoint); 2882 2883 // return mViewSpaceBox.IsInside(viewPoint) && 2884 // mVspBspTree->ViewPointValid(viewPoint); 2885 } 2886 2887 2888 void VspBspViewCellsManager::Visualize(const ObjectContainer &objects, 2889 const VssRayContainer &sampleRays) 2890 { 2891 if (!ViewCellsConstructed()) 2892 return; 2893 2894 VssRayContainer visRays; 2895 GetRaySets(sampleRays, mVisualizationSamples, visRays); 2896 2897 2898 if (1) // export view cells 2899 {// hack pvs 2900 int savedColorCode = mColorCode; 2901 mColorCode = 1; 2902 Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 2903 2904 if (exporter) 2905 { 2906 cout << "exporting view cells after post process ... "; 2907 2908 if (0) 2909 { 2910 exporter->SetWireframe(); 2911 exporter->ExportBox(mViewSpaceBox); 2912 exporter->SetFilled(); 2913 } 2914 2915 if (mExportGeometry) 2916 { 2917 exporter->ExportGeometry(objects); 2918 } 2919 2920 // export rays 2921 if (mExportRays) 2922 { 2923 exporter->ExportRays(visRays, RgbColor(0, 1, 0)); 2924 } 2925 2926 ExportViewCellsForViz(exporter); 2927 delete exporter; 2928 cout << "finished" << endl; 2929 } 2930 2931 mColorCode = savedColorCode; 2932 } 2933 2934 if (0) 2935 { 2936 cout << "exporting depth map ... "; 2937 2938 Exporter *exporter = Exporter::GetExporter("depth_map.x3d"); 2939 if (exporter) 2940 { 2941 if (1) 2942 { 2943 exporter->SetWireframe(); 2944 exporter->ExportBox(mViewSpaceBox); 2945 exporter->SetFilled(); 2946 } 2947 2948 if (mExportGeometry) 2949 { 2950 exporter->ExportGeometry(objects); 2951 } 2952 2953 const int maxDepth = mVspBspTree->mBspStats.maxDepth; 2954 2955 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 2956 2957 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 2958 { 2959 ViewCell *vc = *vit; 2960 2961 ViewCellContainer leaves; 2962 mViewCellsTree->CollectLeaves(vc, leaves); 2963 2964 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 2965 2966 for (lit = leaves.begin(); lit != lit_end; ++ lit) 2967 { 2968 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 2969 2970 Material m; 2971 2972 float relDepth = (float)leaf->GetDepth() / (float)maxDepth; 2973 m.mDiffuseColor.r = relDepth; 2974 m.mDiffuseColor.g = 0.0f; 2975 m.mDiffuseColor.b = 1.0f - relDepth; 2976 2977 exporter->SetForcedMaterial(m); 2978 2979 2980 BspNodeGeometry geom; 2981 mVspBspTree->ConstructGeometry(leaf, geom); 2982 exporter->ExportPolygons(geom.mPolys); 2983 } 2984 } 2985 2986 delete exporter; 2987 } 2988 2989 2990 cout << "finished" << endl; 2991 } 2992 2993 //-- visualization of the BSP splits 2994 bool exportSplits = false; 2995 environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits); 2996 2997 if (exportSplits) 2998 { 2999 cout << "exporting splits ... "; 3000 ExportSplits(objects, visRays); 3001 cout << "finished" << endl; 3002 } 3003 3004 //-- export single view cells 3005 ExportBspPvs(objects, visRays); 3006 } 3007 3008 3009 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects, 3010 const VssRayContainer &rays) 3011 { 3012 Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 3013 3014 if (exporter) 3015 { 3016 Material m; 3017 m.mDiffuseColor = RgbColor(1, 0, 0); 3018 exporter->SetForcedMaterial(m); 3019 exporter->SetWireframe(); 3020 3021 exporter->ExportBspSplits(*mVspBspTree, true); 3022 3023 // take forced material, else big scenes cannot be viewed 3024 m.mDiffuseColor = RgbColor(0, 1, 0); 3025 exporter->SetForcedMaterial(m); 3026 exporter->SetFilled(); 3027 3028 exporter->ResetForcedMaterial(); 3029 3030 // export rays 3031 if (mExportRays) 3032 exporter->ExportRays(rays, RgbColor(1, 1, 0)); 3033 3034 if (mExportGeometry) 3035 exporter->ExportGeometry(objects); 3036 3037 delete exporter; 3038 } 3039 } 3040 3041 3042 void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects, 3043 const VssRayContainer &rays) 3044 { 3045 const int leafOut = 10; 3046 3047 ViewCell::NewMail(); 3048 3049 cout << "visualization using " << mVisualizationSamples << " samples" << endl; 3050 Debug << "\nOutput view cells: " << endl; 3051 3052 // sort view cells to visualize the largest view cells 3053 if (0) 3054 stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt); 3055 3056 int limit = min(leafOut, (int)mViewCells.size()); 3057 3058 int raysOut; 3059 3060 //-- some rays for output 3061 if (1) 3062 raysOut = min((int)rays.size(), mVisualizationSamples); 3063 3064 for (int i = 0; i < limit; ++ i) 3065 { 3066 cout << "creating output for view cell " << i << " ... "; 3067 3068 VssRayContainer vcRays; 3069 Intersectable::NewMail(); 3070 ViewCell *vc; 3071 3072 if (0) // largest view cell pvs first 3073 vc = mViewCells[i]; 3074 else 3075 vc = mViewCells[Random((int)mViewCells.size())]; 3076 3077 vector<ViewCell *> leaves; 3078 mViewCellsTree->CollectLeaves(vc, leaves); 3079 3080 if (1) 3081 { 3082 // check whether we can add the current ray to the output rays 3083 for (int k = 0; k < raysOut; ++ k) 3084 { 3085 VssRay *ray = rays[k]; 3086 for (int j = 0; j < (int)ray->mViewCells.size(); ++ j) 3087 { 3088 ViewCell *rayvc = ray->mViewCells[j]; 3089 3090 if (leaves[0] == rayvc) 3091 vcRays.push_back(ray); 3092 } 3093 } 3094 } 3095 3096 //bspLeaves[j]->Mail(); 3097 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 3098 Exporter *exporter = Exporter::GetExporter(s); 3099 exporter->SetWireframe(); 3100 3101 Material m;//= RandomMaterial(); 3102 m.mDiffuseColor = RgbColor(0, 1, 0); 3103 exporter->SetForcedMaterial(m); 3104 3105 ExportViewCellGeometry(exporter, vc); 3106 3107 3108 Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) 3109 << ", piercing rays=" << (int)vcRays.size() << endl; 3110 // << ", leaves=" << (int)vc->mLeaves.size() << endl; 3111 3112 3113 //-- export rays piercing this view cell 3114 if (1) 3115 { 3116 exporter->ExportRays(vcRays, RgbColor(1, 1, 1)); 3117 } 3118 else 3119 { 3120 3121 ViewCellContainer leaves; 3122 mViewCellsTree->CollectLeaves(vc, leaves); 3123 3124 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 3125 3126 for (lit = leaves.begin(); lit != lit_end; ++ lit) 3127 { 3128 BspLeaf *l = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 3129 exporter->ExportRays(l->mVssRays); 3130 } 3131 } 3132 3133 3134 m.mDiffuseColor = RgbColor(1, 0, 0); 3135 exporter->SetForcedMaterial(m); 3136 3137 ObjectPvsMap::const_iterator it, 3138 it_end = vc->GetPvs().mEntries.end(); 3139 3140 exporter->SetFilled(); 3141 3142 3143 // output PVS of view cell 3144 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 3145 { 3146 3147 Intersectable *intersect = (*it).first; 3148 3149 if (!intersect->Mailed()) 3150 { 3151 Material m = RandomMaterial(); 3152 exporter->SetForcedMaterial(m); 3153 3154 exporter->ExportIntersectable(intersect); 3155 intersect->Mail(); 3156 } 3157 } 3158 3159 3160 DEL_PTR(exporter); 3161 cout << "finished" << endl; 3162 } 3163 3164 Debug << endl; 3165 } 3166 3167 3168 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin, 3169 const Vector3 &termination, 3170 ViewCellContainer &viewcells) 3171 { 3172 return mVspBspTree->CastLineSegment(origin, termination, viewcells); 3173 } 3174 3175 3176 void VspBspViewCellsManager::ExportColor(Exporter *exporter, 3177 ViewCell *vc) const 3178 { 3179 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 1409 3180 1410 3181 float importance = 0; … … 1442 3213 { 1443 3214 int lSize = mViewCellsTree->GetSize(vc); 1444 1445 importance = (float)lSize / (float)mViewCellsStats.maxLeaves;1446 }1447 //break;1448 case 3: // merge tree differene1449 {1450 // TODO1451 //importance = (float)GetMaxTreeDiff(vc) /1452 // (float)(mVspBspTree->GetStatistics().maxDepth * 2);1453 1454 }1455 break;1456 default:1457 break;1458 }1459 1460 // special color code for invalid view cells1461 m.mDiffuseColor.r = importance;1462 m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;1463 m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f;1464 1465 //Debug << "importance: " << importance << endl;1466 exporter->SetForcedMaterial(m);1467 }1468 1469 1470 void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter,1471 ViewCell *vc,1472 const Plane3 *cuttingPlane) const1473 {1474 if (vc->GetMesh())1475 {1476 exporter->ExportMesh(vc->GetMesh());1477 1478 return;1479 }1480 1481 BspNodeGeometry geom;1482 mBspTree->ConstructGeometry(vc, geom);1483 1484 1485 if (cuttingPlane)1486 {1487 BspNodeGeometry front;1488 BspNodeGeometry back;1489 1490 geom.SplitGeometry(front,1491 back,1492 *cuttingPlane,1493 mViewSpaceBox,1494 0.0001);1495 1496 exporter->ExportPolygons(back.mPolys);1497 }1498 else1499 {1500 exporter->ExportPolygons(geom.mPolys);1501 }1502 }1503 1504 1505 void BspViewCellsManager::CreateMesh(ViewCell *vc)1506 {1507 if (vc->GetMesh())1508 delete vc->GetMesh();1509 1510 BspNodeGeometry geom;1511 1512 mBspTree->ConstructGeometry(vc, geom);1513 1514 Mesh *mesh = new Mesh();1515 geom.AddToMesh(*mesh);1516 vc->SetMesh(mesh);1517 mMeshContainer.push_back(mesh);1518 }1519 1520 1521 void BspViewCellsManager::Finalize(ViewCell *viewCell,1522 const bool createMesh)1523 {1524 CreateMesh(viewCell);1525 1526 float area = 0;1527 float volume = 0;1528 1529 ViewCellContainer leaves;1530 mViewCellsTree->CollectLeaves(viewCell, leaves);1531 1532 ViewCellContainer::const_iterator it, it_end = leaves.end();1533 1534 for (it = leaves.begin(); it != it_end; ++ it)1535 {1536 BspNodeGeometry geom;1537 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;1538 mBspTree->ConstructGeometry(leaf, geom);1539 1540 area += geom.GetArea();1541 volume += geom.GetVolume();1542 }1543 1544 viewCell->SetVolume(volume);1545 viewCell->SetArea(area);1546 }1547 1548 1549 ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point) const1550 {1551 if (!mBspTree)1552 return NULL;1553 1554 if (!mViewSpaceBox.IsInside(point))1555 return NULL;1556 1557 return mBspTree->GetViewCell(point);1558 }1559 1560 1561 void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,1562 vector<MergeCandidate> &candidates)1563 {1564 cout << "collecting merge candidates ... " << endl;1565 1566 if (mUseRaysForMerge)1567 {1568 mBspTree->CollectMergeCandidates(rays, candidates);1569 }1570 else1571 {1572 vector<BspLeaf *> leaves;1573 mBspTree->CollectLeaves(leaves);1574 mBspTree->CollectMergeCandidates(leaves, candidates);1575 }1576 1577 cout << "fininshed collecting candidates" << endl;1578 }1579 1580 1581 1582 bool BspViewCellsManager::ExportViewCells(const string filename)1583 {1584 cout << "exporting view cells to xml ... ";1585 std::ofstream stream;1586 1587 // for output we need unique ids for each view cell1588 CreateUniqueViewCellIds();1589 1590 1591 stream.open(filename.c_str());1592 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;1593 stream << "<Visibility_Solution>" << endl;1594 1595 //-- the view space bounding box1596 stream << "<ViewSpaceBox"1597 << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\""1598 << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;1599 1600 //-- the type of the view cells hierarchy1601 //stream << "<Hierarchy name=\"bspTree\" />" << endl;1602 stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free1603 //-- load the view cells itself, i.e., the ids and the pvs1604 stream << "<ViewCells>" << endl;1605 ViewCellContainer::const_iterator it, it_end = mViewCells.end();1606 for (it = mViewCells.begin(); it != it_end; ++ it)1607 ExportViewCell(*it, stream);1608 1609 stream << "</ViewCells>" << endl;1610 1611 //-- load the hierarchy1612 stream << "<Hierarchy>" << endl;1613 mBspTree->Export(stream);1614 stream << endl << "</Hierarchy>" << endl;1615 1616 stream << "</Visibility_Solution>" << endl;1617 stream.close();1618 1619 cout << "finished" << endl;1620 1621 return true;1622 }1623 1624 1625 void BspViewCellsManager::AddCurrentViewCellsToHierarchy()1626 {1627 ViewCellContainer::const_iterator it, it_end = mViewCells.end();1628 for (it = mViewCells.begin(); it != it_end; ++ it)1629 {1630 ViewCell *vc = *it;1631 ViewCellContainer leaves;1632 mViewCellsTree->CollectLeaves(vc, leaves);1633 1634 ViewCellContainer::const_iterator lit, lit_end = leaves.end();1635 1636 for (lit = leaves.begin(); lit != lit_end; ++ lit)1637 {1638 BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit);1639 bspVc->mLeaf->SetViewCell(vc);1640 }1641 }1642 }1643 1644 /************************************************************************/1645 /* KdViewCellsManager implementation */1646 /************************************************************************/1647 1648 1649 1650 KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):1651 ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100)1652 {1653 }1654 1655 float KdViewCellsManager::GetProbability(ViewCell *viewCell)1656 {1657 // compute view cell area / volume as subsititute for probability1658 #if 01659 return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();1660 #endif1661 #if 11662 return GetArea(viewCell) / GetAccVcArea();1663 #endif1664 #if 01665 return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();1666 #endif1667 }1668 1669 1670 float KdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const1671 {1672 return viewCell->GetPvs().GetSize() * objRendercost;1673 }1674 1675 1676 void KdViewCellsManager::CollectViewCells()1677 {1678 //mKdTree->CollectViewCells(mViewCells); TODO1679 }1680 1681 1682 int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,1683 const VssRayContainer &rays)1684 {1685 // if view cells already constructed1686 if (ViewCellsConstructed())1687 return 0;1688 1689 mKdTree->Construct();1690 1691 mTotalAreaValid = false;1692 // create the view cells1693 mKdTree->CreateAndCollectViewCells(mViewCells);1694 1695 // cast rays1696 ComputeSampleContributions(rays, true, false);1697 1698 EvaluateViewCellsStats();1699 Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;1700 1701 return 0;1702 }1703 1704 1705 bool KdViewCellsManager::ViewCellsConstructed() const1706 {1707 return mKdTree->GetRoot() != NULL;1708 }1709 1710 int KdViewCellsManager::PostProcess(const ObjectContainer &objects,1711 const VssRayContainer &rays)1712 {1713 return 0;1714 }1715 1716 void KdViewCellsManager::Visualize(const ObjectContainer &objects,1717 const VssRayContainer &sampleRays)1718 {1719 if (!ViewCellsConstructed())1720 return;1721 1722 // using view cells instead of the kd PVS of objects1723 const bool useViewCells = true;1724 bool exportRays = false;1725 1726 int limit = min(mVisualizationSamples, (int)sampleRays.size());1727 const int pvsOut = min((int)objects.size(), 10);1728 VssRayContainer *rays = new VssRayContainer[pvsOut];1729 1730 if (useViewCells)1731 {1732 const int leafOut = 10;1733 1734 ViewCell::NewMail();1735 1736 //-- some rays for output1737 const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);1738 Debug << "visualization using " << raysOut << " samples" << endl;1739 1740 //-- some random view cells and rays for output1741 vector<KdLeaf *> kdLeaves;1742 1743 for (int i = 0; i < leafOut; ++ i)1744 kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf()));1745 1746 for (int i = 0; i < kdLeaves.size(); ++ i)1747 {1748 KdLeaf *leaf = kdLeaves[i];1749 RayContainer vcRays;1750 1751 cout << "creating output for view cell " << i << " ... ";1752 #if 01753 // check whether we can add the current ray to the output rays1754 for (int k = 0; k < raysOut; ++ k)1755 {1756 Ray *ray = sampleRays[k];1757 1758 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)1759 {1760 BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;1761 1762 if (leaf->GetViewCell() == leaf2->GetViewCell())1763 {1764 vcRays.push_back(ray);1765 }1766 }1767 }1768 #endif1769 Intersectable::NewMail();1770 1771 ViewCell *vc = leaf->mViewCell;1772 1773 //bspLeaves[j]->Mail();1774 char s[64]; sprintf(s, "kd-pvs%04d.x3d", i);1775 1776 Exporter *exporter = Exporter::GetExporter(s);1777 exporter->SetFilled();1778 1779 exporter->SetWireframe();1780 //exporter->SetFilled();1781 1782 Material m;//= RandomMaterial();1783 m.mDiffuseColor = RgbColor(1, 1, 0);1784 exporter->SetForcedMaterial(m);1785 1786 AxisAlignedBox3 box = mKdTree->GetBox(leaf);1787 exporter->ExportBox(box);1788 1789 Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()1790 << ", piercing rays=" << (int)vcRays.size() << endl;1791 1792 // export rays piercing this view cell1793 exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));1794 1795 m.mDiffuseColor = RgbColor(1, 0, 0);1796 exporter->SetForcedMaterial(m);1797 1798 // exporter->SetWireframe();1799 exporter->SetFilled();1800 1801 ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();1802 // output PVS of view cell1803 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)1804 {1805 Intersectable *intersect = (*it).first;1806 if (!intersect->Mailed())1807 {1808 exporter->ExportIntersectable(intersect);1809 intersect->Mail();1810 }1811 }1812 1813 DEL_PTR(exporter);1814 cout << "finished" << endl;1815 }1816 1817 DEL_PTR(rays);1818 }1819 else // using kd PVS of objects1820 {1821 for (int i = 0; i < limit; ++ i)1822 {1823 VssRay *ray = sampleRays[i];1824 1825 // check whether we can add this to the rays1826 for (int j = 0; j < pvsOut; j++)1827 {1828 if (objects[j] == ray->mTerminationObject)1829 {1830 rays[j].push_back(ray);1831 }1832 }1833 }1834 1835 if (exportRays)1836 {1837 Exporter *exporter = NULL;1838 exporter = Exporter::GetExporter("sample-rays.x3d");1839 exporter->SetWireframe();1840 exporter->ExportKdTree(*mKdTree);1841 1842 for (i=0; i < pvsOut; i++)1843 exporter->ExportRays(rays[i], RgbColor(1, 0, 0));1844 1845 exporter->SetFilled();1846 1847 delete exporter;1848 }1849 1850 for (int k=0; k < pvsOut; k++)1851 {1852 Intersectable *object = objects[k];1853 char s[64];1854 sprintf(s, "sample-pvs%04d.x3d", k);1855 1856 Exporter *exporter = Exporter::GetExporter(s);1857 exporter->SetWireframe();1858 1859 KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();1860 Intersectable::NewMail();1861 1862 // avoid adding the object to the list1863 object->Mail();1864 ObjectContainer visibleObjects;1865 1866 for (; i != object->mKdPvs.mEntries.end(); i++)1867 {1868 KdNode *node = (*i).first;1869 exporter->ExportBox(mKdTree->GetBox(node));1870 1871 mKdTree->CollectObjects(node, visibleObjects);1872 }1873 1874 exporter->ExportRays(rays[k], RgbColor(0, 1, 0));1875 exporter->SetFilled();1876 1877 for (int j = 0; j < visibleObjects.size(); j++)1878 exporter->ExportIntersectable(visibleObjects[j]);1879 1880 Material m;1881 m.mDiffuseColor = RgbColor(1, 0, 0);1882 exporter->SetForcedMaterial(m);1883 exporter->ExportIntersectable(object);1884 1885 delete exporter;1886 }1887 }1888 }1889 1890 1891 void KdViewCellsManager::ExportColor(Exporter *exporter,1892 ViewCell *vc) const1893 {1894 // TODO1895 }1896 1897 ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const1898 {1899 return new KdViewCell(mesh);1900 }1901 1902 1903 void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,1904 ViewCell *vc,1905 const Plane3 *cuttingPlane) const1906 {1907 ViewCellContainer leaves;1908 1909 mViewCellsTree->CollectLeaves(vc, leaves);1910 ViewCellContainer::const_iterator it, it_end = leaves.end();1911 1912 for (it = leaves.begin(); it != it_end; ++ it)1913 {1914 KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it);1915 1916 exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf));1917 }1918 }1919 1920 1921 int KdViewCellsManager::GetType() const1922 {1923 return ViewCellsManager::KD;1924 }1925 1926 1927 1928 KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)1929 {1930 KdNode *node = leaf;1931 1932 while (node->mParent && node->mDepth > mKdPvsDepth)1933 node = node->mParent;1934 return node;1935 }1936 1937 int KdViewCellsManager::CastLineSegment(const Vector3 &origin,1938 const Vector3 &termination,1939 ViewCellContainer &viewcells)1940 {1941 return mKdTree->CastLineSegment(origin, termination, viewcells);1942 }1943 1944 1945 void KdViewCellsManager::CreateMesh(ViewCell *vc)1946 {1947 // TODO1948 }1949 1950 1951 1952 void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,1953 vector<MergeCandidate> &candidates)1954 {1955 // TODO1956 }1957 1958 1959 /**********************************************************************/1960 /* VspKdViewCellsManager implementation */1961 /**********************************************************************/1962 1963 1964 VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree):1965 ViewCellsManager(), mVspKdTree(vspKdTree)1966 {1967 environment->GetIntValue("VspKdTree.Construction.samples", mInitialSamples);1968 mVspKdTree->SetViewCellsManager(this);1969 }1970 1971 float VspKdViewCellsManager::GetProbability(ViewCell *viewCell)1972 {1973 // volume or area substitutes for view point probability1974 #if 01975 return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();1976 #else1977 return GetArea(viewCell) / GetAccVcArea();1978 #endif1979 }1980 1981 1982 float VspKdViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const1983 {1984 return viewCell->GetPvs().GetSize() * objRendercost;1985 }1986 1987 1988 void VspKdViewCellsManager::CollectViewCells()1989 {1990 mVspKdTree->CollectViewCells(mViewCells);1991 }1992 1993 1994 int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,1995 const VssRayContainer &rays)1996 {1997 // if view cells already constructed1998 if (ViewCellsConstructed())1999 return 0;2000 2001 VssRayContainer constructionRays;2002 VssRayContainer savedRays;2003 2004 GetRaySets(rays,2005 mInitialSamples,2006 constructionRays,2007 &savedRays);2008 2009 Debug << "constructing vsp kd tree using "2010 << (int)constructionRays.size() << " samples" << endl;2011 2012 mVspKdTree->Construct(constructionRays, &mViewSpaceBox);2013 Debug << mVspKdTree->GetStatistics() << endl;2014 2015 // export leaf building blocks2016 ExportLeaves(objects, rays);2017 2018 // finally merge kd leaf building blocks to view cells2019 const int merged = mVspKdTree->MergeViewCells(rays);2020 2021 // collapse siblings belonging to the same view cell2022 mVspKdTree->RefineViewCells(rays);2023 2024 // collapse siblings belonging to the same view cell2025 mVspKdTree->CollapseTree();2026 2027 // evaluale view cell stats2028 ResetViewCells();2029 2030 Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;2031 2032 long startTime = GetTime();2033 // recast rest of rays2034 ComputeSampleContributions(savedRays, true, false);2035 2036 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-32037 << " secs" << endl;2038 2039 return merged;2040 }2041 2042 bool VspKdViewCellsManager::ViewCellsConstructed() const2043 {2044 return mVspKdTree->GetRoot() != NULL;2045 }2046 2047 2048 ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const2049 {2050 return new VspKdViewCell(mesh);2051 }2052 2053 int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,2054 const VssRayContainer &rays)2055 {2056 if (!ViewCellsConstructed())2057 return 0;2058 2059 // recalculate stats2060 EvaluateViewCellsStats();2061 2062 return 0;2063 }2064 2065 2066 void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects,2067 const VssRayContainer &sampleRays)2068 {2069 if (!ViewCellsConstructed())2070 return;2071 2072 //-- export leaf building blocks2073 Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");2074 if (!exporter)2075 return;2076 2077 if (mExportGeometry)2078 exporter->ExportGeometry(objects);2079 2080 //exporter->SetWireframe();2081 //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);2082 exporter->ExportVspKdTree(*mVspKdTree);2083 2084 if (mExportRays)2085 {2086 const float prob = (float)mVisualizationSamples2087 / ((float)sampleRays.size() + Limits::Small);2088 2089 exporter->SetWireframe();2090 2091 //-- collect uniformly distributed rays2092 VssRayContainer rays;2093 2094 for (int i = 0; i < sampleRays.size(); ++ i)2095 {2096 if (RandomValue(0,1) < prob)2097 rays.push_back(sampleRays[i]);2098 }2099 exporter->ExportRays(rays, RgbColor(1, 0, 0));2100 }2101 2102 delete exporter;2103 }2104 2105 void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,2106 const VssRayContainer &sampleRays)2107 {2108 if (!ViewCellsConstructed())2109 return;2110 2111 //-- export single view cells2112 for (int i = 0; i < 10; ++ i)2113 {2114 char s[64];2115 sprintf(s, "vsp_viewcell%04d.x3d", i);2116 Exporter *exporter = Exporter::GetExporter(s);2117 const int idx =2118 (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1));2119 2120 VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]);2121 2122 cout << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl;2123 Debug << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl;2124 //-- export geometry2125 Material m;2126 m.mDiffuseColor = RgbColor(0, 1, 1);2127 2128 exporter->SetForcedMaterial(m);2129 exporter->SetWireframe();2130 2131 ExportViewCellGeometry(exporter, vc);2132 2133 //-- export stored rays2134 2135 if (mExportRays)2136 {2137 ViewCellContainer leaves;2138 mViewCellsTree->CollectLeaves(vc, leaves);2139 2140 ViewCellContainer::const_iterator it,2141 it_end = leaves.end();2142 2143 for (it = leaves.begin(); it != it_end; ++ it)2144 {2145 VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it);2146 VspKdLeaf *leaf = vspKdVc->mLeaf;2147 AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);2148 2149 VssRayContainer vssRays;2150 2151 VssRayContainer castRays;2152 VssRayContainer initRays;2153 2154 leaf->GetRays(vssRays);2155 2156 VssRayContainer::const_iterator it, it_end = vssRays.end();2157 const float prop = 200.0f / (float)vssRays.size();2158 2159 for (it = vssRays.begin(); it != it_end; ++ it)2160 {2161 if (Random(1) < prop)2162 if ((*it)->mTerminationObject == NULL)2163 castRays.push_back(*it);2164 else2165 initRays.push_back(*it);2166 }2167 2168 exporter->ExportRays(castRays, RgbColor(1, 0, 0));2169 exporter->ExportRays(initRays, RgbColor(0, 1, 0));2170 }2171 }2172 2173 //-- output PVS of view cell2174 m.mDiffuseColor = RgbColor(1, 0, 0);2175 exporter->SetForcedMaterial(m);2176 2177 Intersectable::NewMail();2178 2179 ObjectPvsMap::const_iterator it,2180 it_end = vc->GetPvs().mEntries.end();2181 2182 exporter->SetFilled();2183 2184 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)2185 {2186 Intersectable *intersect = (*it).first;2187 2188 if (!intersect->Mailed())2189 {2190 Material m = RandomMaterial();2191 exporter->SetForcedMaterial(m);2192 2193 exporter->ExportIntersectable(intersect);2194 intersect->Mail();2195 }2196 }2197 2198 delete exporter;2199 }2200 2201 //-- export final view cells2202 Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");2203 2204 //if (exportGeometry) exporter->SetWireframe();2205 //else exporter->SetFilled();2206 2207 ExportViewCellsForViz(exporter);2208 2209 if (mExportGeometry)2210 {2211 exporter->SetFilled();2212 exporter->ExportGeometry(objects);2213 }2214 2215 if (mExportRays)2216 {2217 const float prob = (float)mVisualizationSamples2218 / ((float)sampleRays.size() + Limits::Small);2219 2220 exporter->SetWireframe();2221 2222 VssRayContainer rays;2223 2224 for (int i = 0; i < sampleRays.size(); ++ i)2225 {2226 if (RandomValue(0,1) < prob)2227 rays.push_back(sampleRays[i]);2228 }2229 exporter->ExportRays(rays, RgbColor(1, 0, 0));2230 }2231 2232 delete exporter;2233 }2234 2235 int VspKdViewCellsManager::GetType() const2236 {2237 return VSP_KD;2238 }2239 2240 2241 int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin,2242 const Vector3 &termination,2243 ViewCellContainer &viewcells)2244 {2245 return mVspKdTree->CastLineSegment(origin, termination, viewcells);2246 }2247 2248 2249 void VspKdViewCellsManager::ExportColor(Exporter *exporter,2250 ViewCell *vc) const2251 {2252 if (mColorCode == 0) // Random color2253 return;2254 2255 float importance = 0;2256 2257 switch (mColorCode)2258 {2259 case 1: // pvs2260 {2261 importance = (float)vc->GetPvs().GetSize() /2262 (float)mViewCellsStats.maxPvs;2263 }2264 break;2265 case 2: // merged leaves2266 {2267 int lSize = mViewCellsTree->GetSize(vc);2268 importance = (float)lSize /2269 (float)mViewCellsStats.maxLeaves;2270 }2271 break;2272 case 3: // merged tree depth difference2273 {2274 //importance = (float)GetMaxTreeDiff(vc) /2275 // (float)(mVspBspTree->GetStatistics().maxDepth * 2);2276 }2277 break;2278 default:2279 break;2280 }2281 2282 Material m;2283 m.mDiffuseColor.b = 1.0f;2284 m.mDiffuseColor.r = importance;2285 m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;2286 //Debug << "importance: " << importance << endl;2287 exporter->SetForcedMaterial(m);2288 }2289 2290 2291 void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,2292 ViewCell *vc,2293 const Plane3 *cuttingPlane) const2294 {2295 VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc);2296 2297 Mesh m;2298 2299 ViewCellContainer leaves;2300 mViewCellsTree->CollectLeaves(vc, leaves);2301 2302 ViewCellContainer::const_iterator it, it_end = leaves.end();2303 2304 for (it = leaves.begin(); it != it_end; ++ it)2305 {2306 VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf;2307 mVspKdTree->GetBBox(l).AddBoxToMesh(&m);2308 }2309 2310 exporter->ExportMesh(&m);2311 }2312 2313 2314 void VspKdViewCellsManager::CreateMesh(ViewCell *vc)2315 {2316 //TODO2317 }2318 2319 2320 void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,2321 vector<MergeCandidate> &candidates)2322 {2323 // TODO2324 }2325 2326 2327 /**************************************************************************/2328 /* VspBspViewCellsManager implementation */2329 /**************************************************************************/2330 2331 2332 VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree):2333 ViewCellsManager(), mVspBspTree(vspBspTree)2334 {2335 environment->GetIntValue("VspBspTree.Construction.samples", mInitialSamples);2336 mVspBspTree->SetViewCellsManager(this);2337 mVspBspTree->mViewCellsTree = mViewCellsTree;2338 }2339 2340 2341 VspBspViewCellsManager::~VspBspViewCellsManager()2342 {2343 }2344 2345 2346 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell)2347 {2348 if (0 && mVspBspTree->mUseAreaForPvs)2349 return GetArea(viewCell) / GetAccVcArea();2350 else2351 return GetVolume(viewCell) / mViewSpaceBox.GetVolume();2352 }2353 2354 2355 void VspBspViewCellsManager::CollectViewCells()2356 {2357 // view cells tree constructed2358 if (!ViewCellsTreeConstructed())2359 {2360 mVspBspTree->CollectViewCells(mViewCells, false);2361 }2362 else2363 {2364 // we can use the view cells tree hierarchy to get the right set2365 mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumMergedViewCells);2366 }2367 2368 }2369 2370 2371 float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell,2372 float objRendercost) const2373 {2374 return viewCell->GetPvs().GetSize() * objRendercost;2375 }2376 2377 2378 bool VspBspViewCellsManager::ViewCellsConstructed() const2379 {2380 return mVspBspTree->GetRoot() != NULL;2381 }2382 2383 2384 ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const2385 {2386 return new BspViewCell(mesh);2387 }2388 2389 2390 int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,2391 const VssRayContainer &rays)2392 {2393 // if view cells were already constructed2394 if (ViewCellsConstructed())2395 return 0;2396 2397 Debug << "Constructing bsp view cells" << endl;2398 2399 int sampleContributions = 0;2400 2401 VssRayContainer sampleRays;2402 2403 int limit = min (mInitialSamples, (int)rays.size());2404 2405 VssRayContainer constructionRays;2406 VssRayContainer savedRays;2407 2408 Debug << "samples used for subdivision: " << mInitialSamples2409 << " rays: " << (int)rays.size() << endl;2410 2411 GetRaySets(rays, mInitialSamples, constructionRays, &savedRays);2412 2413 Debug << "initial rays: " << (int)constructionRays.size() << endl;2414 Debug << "saved rays: " << (int)savedRays.size() << endl;2415 2416 mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size());2417 2418 mVspBspTree->Construct(constructionRays, &mViewSpaceBox);2419 2420 Debug << mVspBspTree->GetStatistics() << endl;2421 2422 // collapse invalid regions2423 cout << "collapsing invalid tree regions ... ";2424 long startTime = GetTime();2425 int collapsedLeaves = mVspBspTree->CollapseTree();2426 Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-32427 << " seconds" << endl;2428 2429 cout << "finished" << endl;2430 2431 cout << "reseting view cell stats ... ";2432 ResetViewCells();2433 cout << "finished" << endl;2434 2435 Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;2436 2437 if (1) // export initial view cells2438 {2439 cout << "exporting initial view cells (=leaves) ... ";2440 Exporter *exporter = Exporter::GetExporter("view_cells.x3d");2441 2442 if (exporter)2443 {2444 if (0 && mExportRays)2445 exporter->ExportRays(rays, RgbColor(1, 1, 1));2446 2447 if (mExportGeometry)2448 exporter->ExportGeometry(objects);2449 2450 //exporter->SetWireframe();2451 exporter->SetFilled();2452 ExportViewCellsForViz(exporter);2453 2454 delete exporter;2455 }2456 cout << "finished" << endl;2457 }2458 2459 startTime = GetTime();2460 2461 // reset view cells and stats2462 ResetViewCells();2463 2464 cout << "Computing remaining ray contributions ... ";2465 // recast rest of rays2466 ComputeSampleContributions(savedRays, true, false);2467 cout << "finished" << endl;2468 2469 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-32470 << " secs" << endl;2471 2472 cout << "construction finished" << endl;2473 2474 return sampleContributions;2475 }2476 2477 2478 void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays,2479 const ObjectContainer &objects)2480 {2481 //-- post processing of bsp view cells2482 int vcSize = 0;2483 int pvsSize = 0;2484 2485 mRenderer->RenderScene();2486 SimulationStatistics ss;2487 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);2488 Debug << ss << endl;2489 2490 //-- merge or subdivide view cells2491 int merged = 0;2492 if (mMergeViewCells)2493 {2494 cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl;2495 long startTime = GetTime();2496 2497 2498 // TODO: should be done BEFORE the ray casting2499 merged = mViewCellsTree->ConstructMergeTree(rays, objects);2500 2501 //-- stats and visualizations2502 cout << "finished merging" << endl;2503 cout << "merged " << merged << " view cells in "2504 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;2505 2506 Debug << "Postprocessing: Merged " << merged << " view cells in "2507 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;2508 }2509 2510 //BspLeaf::NewMail();2511 if (1) // export merged view cells2512 {2513 cout << "reseting view cells ... ";2514 ResetViewCells();2515 2516 cout << "finished" << endl;2517 2518 Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");2519 Debug << "\nView cells after merge:\n" << mViewCellsStats << endl;2520 2521 cout << "exporting view cells after merge ... ";2522 2523 if (exporter)2524 {2525 if (mExportGeometry)2526 {2527 Material m;2528 m.mDiffuseColor = RgbColor(0, 1, 0);2529 exporter->SetForcedMaterial(m);2530 exporter->SetFilled();2531 2532 exporter->ExportGeometry(objects);2533 }2534 2535 if (0)2536 exporter->SetWireframe();2537 else2538 exporter->SetFilled();2539 2540 ExportViewCellsForViz(exporter);2541 2542 delete exporter;2543 }2544 cout << "finished" << endl;2545 }2546 }2547 2548 2549 void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays,2550 const ObjectContainer &objects)2551 {2552 Debug << "render time before refine:" << endl;2553 mRenderer->RenderScene();2554 SimulationStatistics ss;2555 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);2556 Debug << ss << endl;2557 2558 cout << "Refining the merged view cells ... ";2559 long startTime = GetTime();2560 2561 // refining the merged view cells2562 const int refined = mViewCellsTree->RefineViewCells(rays, objects);2563 2564 //-- stats and visualizations2565 cout << "finished" << endl;2566 cout << "refined " << refined << " view cells in "2567 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;2568 2569 Debug << "Postprocessing: refined " << refined << " view cells in "2570 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;2571 }2572 2573 2574 int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,2575 const VssRayContainer &rays)2576 {2577 if (!ViewCellsConstructed())2578 {2579 Debug << "postprocess error: no view cells constructed" << endl;2580 return 0;2581 }2582 2583 2584 // view cells already finished before post processing step (i.e. because they were loaded)2585 if (mViewCellsFinished)2586 {2587 FinalizeViewCells(true);2588 EvaluateViewCellsStats();2589 2590 return 0;2591 }2592 2593 2594 // check if new view cells turned invalid2595 SetValidity(mMinPvsSize, mMaxPvsSize);2596 // update valid view space according to valid view cells2597 mVspBspTree->ValidateTree();2598 2599 // recompute view cell statistics2600 mViewCellsStats.Reset();2601 EvaluateViewCellsStats();2602 2603 // has to be recomputed2604 mTotalAreaValid = false;2605 2606 2607 VssRayContainer postProcessRays;2608 GetRaySets(rays, mPostProcessSamples, postProcessRays);2609 2610 Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl;2611 2612 Debug << "\nview cell partition after sampling:\n" << mViewCellsStats << endl << endl;2613 2614 // should maybe be done here to allow merge working with area or volume2615 // and to correct the rendering statistics2616 if (0)2617 {2618 FinalizeViewCells(false);2619 }2620 2621 //-- merge the individual view cells2622 MergeViewCells(postProcessRays, objects);2623 2624 2625 //-- refines the merged view cells2626 if (0)2627 RefineViewCells(postProcessRays, objects);2628 2629 //-- compression2630 2631 if (ViewCellsTreeConstructed() && mCompressViewCells)2632 {2633 int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());2634 Debug << "number of entries before compress: " << pvsEntries << endl;2635 2636 mViewCellsTree->CompressViewCellsPvs();2637 2638 pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());2639 Debug << "number of entries after compress: " << pvsEntries << endl;2640 }2641 2642 if (1)2643 {2644 float totalCost, erc, var, dev, avg;2645 int totalpvs;2646 2647 mViewCellsStats.Reset();2648 2649 EvaluateRenderStatistics(totalCost, erc, dev, var, totalpvs, avg);2650 2651 Debug << "statistics after merge "2652 << " erc: " << erc2653 << " dev: " << dev2654 << " totalpvs: " << totalpvs2655 << " avg: " << avg << endl;2656 }2657 2658 2659 //-- export refined (shuffled) view cells2660 if (0)2661 {2662 cout << "exporting shuffled view cells ... ";2663 2664 Exporter *exporter = Exporter::GetExporter("shuffled_view_cells.x3d");2665 if (exporter)2666 {2667 if (1)2668 {2669 exporter->SetWireframe();2670 exporter->ExportBox(mViewSpaceBox);2671 exporter->SetFilled();2672 }2673 2674 if (mExportGeometry)2675 {2676 exporter->ExportGeometry(objects);2677 }2678 2679 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();2680 2681 Material vm, lm;2682 2683 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit)2684 {2685 ViewCell *vc = *vit;2686 2687 vm = RandomMaterial();2688 2689 lm = vm;2690 2691 vm.mDiffuseColor.r -= 0.45f;2692 vm.mDiffuseColor.g -= 0.45f;2693 vm.mDiffuseColor.b -= 0.45f;2694 2695 2696 ViewCellContainer leaves;2697 mViewCellsTree->CollectLeaves(vc, leaves);2698 2699 ViewCellContainer::const_iterator lit, lit_end = leaves.end();2700 2701 for (lit = leaves.begin(); lit != lit_end; ++ lit)2702 {2703 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf;2704 2705 if (leaf->Mailed())2706 exporter->SetForcedMaterial(lm);2707 else2708 exporter->SetForcedMaterial(vm);2709 2710 BspNodeGeometry geom;2711 mVspBspTree->ConstructGeometry(leaf, geom);2712 exporter->ExportPolygons(geom.mPolys);2713 }2714 }2715 2716 delete exporter;2717 }2718 2719 2720 cout << "finished" << endl;2721 }2722 2723 // collapse sibling leaves that share the same view cell2724 if (0)2725 mVspBspTree->CollapseTree();2726 2727 // recompute view cell list and statistics2728 ResetViewCells();2729 2730 // real meshes are only contructed only at this stage2731 FinalizeViewCells(true);2732 2733 // write view cells to disc2734 if (mExportViewCells)2735 {2736 char buff[100];2737 environment->GetStringValue("ViewCells.filename", buff);2738 string vcFilename(buff);2739 2740 ExportViewCells(buff);2741 }2742 2743 return 0;2744 }2745 2746 2747 int VspBspViewCellsManager::GetType() const2748 {2749 return VSP_BSP;2750 }2751 2752 2753 bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const2754 {2755 if (!ViewCellsConstructed())2756 return ViewCellsManager::GetViewPoint(viewPoint);2757 2758 // TODO: set reasonable limit2759 const int limit = 20;2760 2761 for (int i = 0; i < limit; ++ i)2762 {2763 viewPoint = mViewSpaceBox.GetRandomPoint();2764 if (mVspBspTree->ViewPointValid(viewPoint))2765 {2766 return true;2767 }2768 }2769 Debug << "failed to find valid view point, taking " << viewPoint << endl;2770 return false;2771 }2772 2773 2774 bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const2775 {2776 // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic2777 // validy update in preprocessor for all managers)2778 return ViewCellsManager::ViewPointValid(viewPoint);2779 2780 // return mViewSpaceBox.IsInside(viewPoint) &&2781 // mVspBspTree->ViewPointValid(viewPoint);2782 }2783 2784 2785 void VspBspViewCellsManager::Visualize(const ObjectContainer &objects,2786 const VssRayContainer &sampleRays)2787 {2788 if (!ViewCellsConstructed())2789 return;2790 2791 VssRayContainer visRays;2792 GetRaySets(sampleRays, mVisualizationSamples, visRays);2793 2794 if (1) // export view cells2795 {2796 Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");2797 2798 if (exporter)2799 {2800 cout << "exporting view cells after post process ... ";2801 2802 if (1)2803 {2804 exporter->SetWireframe();2805 exporter->ExportBox(mViewSpaceBox);2806 exporter->SetFilled();2807 }2808 2809 if (mExportGeometry)2810 {2811 exporter->ExportGeometry(objects);2812 }2813 2814 // export rays2815 if (mExportRays)2816 {2817 exporter->ExportRays(visRays, RgbColor(0, 1, 0));2818 }2819 2820 ExportViewCellsForViz(exporter);2821 delete exporter;2822 cout << "finished" << endl;2823 }2824 }2825 2826 if (1)2827 {2828 cout << "exporting depth map ... ";2829 2830 Exporter *exporter = Exporter::GetExporter("depth_map.x3d");2831 if (exporter)2832 {2833 if (1)2834 {2835 exporter->SetWireframe();2836 exporter->ExportBox(mViewSpaceBox);2837 exporter->SetFilled();2838 }2839 2840 if (mExportGeometry)2841 {2842 exporter->ExportGeometry(objects);2843 }2844 2845 const int maxDepth = mVspBspTree->mBspStats.maxDepth;2846 2847 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();2848 2849 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit)2850 {2851 ViewCell *vc = *vit;2852 2853 ViewCellContainer leaves;2854 mViewCellsTree->CollectLeaves(vc, leaves);2855 2856 ViewCellContainer::const_iterator lit, lit_end = leaves.end();2857 2858 for (lit = leaves.begin(); lit != lit_end; ++ lit)2859 {2860 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf;2861 2862 Material m;2863 2864 float relDepth = (float)leaf->GetDepth() / (float)maxDepth;2865 m.mDiffuseColor.r = relDepth;2866 m.mDiffuseColor.g = 0.0f;2867 m.mDiffuseColor.b = 1.0f - relDepth;2868 2869 exporter->SetForcedMaterial(m);2870 2871 2872 BspNodeGeometry geom;2873 mVspBspTree->ConstructGeometry(leaf, geom);2874 exporter->ExportPolygons(geom.mPolys);2875 }2876 }2877 2878 delete exporter;2879 }2880 2881 2882 cout << "finished" << endl;2883 }2884 2885 //-- visualization of the BSP splits2886 bool exportSplits = false;2887 environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits);2888 2889 if (exportSplits)2890 {2891 cout << "exporting splits ... ";2892 ExportSplits(objects, visRays);2893 cout << "finished" << endl;2894 }2895 2896 //-- export single view cells2897 ExportBspPvs(objects, visRays);2898 }2899 2900 2901 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,2902 const VssRayContainer &rays)2903 {2904 Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");2905 2906 if (exporter)2907 {2908 Material m;2909 m.mDiffuseColor = RgbColor(1, 0, 0);2910 exporter->SetForcedMaterial(m);2911 exporter->SetWireframe();2912 2913 exporter->ExportBspSplits(*mVspBspTree, true);2914 2915 // take forced material, else big scenes cannot be viewed2916 m.mDiffuseColor = RgbColor(0, 1, 0);2917 exporter->SetForcedMaterial(m);2918 exporter->SetFilled();2919 2920 exporter->ResetForcedMaterial();2921 2922 // export rays2923 if (mExportRays)2924 exporter->ExportRays(rays, RgbColor(1, 1, 0));2925 2926 if (mExportGeometry)2927 exporter->ExportGeometry(objects);2928 2929 delete exporter;2930 }2931 }2932 2933 2934 void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,2935 const VssRayContainer &rays)2936 {2937 const int leafOut = 10;2938 2939 ViewCell::NewMail();2940 2941 cout << "visualization using " << mVisualizationSamples << " samples" << endl;2942 Debug << "\nOutput view cells: " << endl;2943 2944 // sort view cells to visualize the largest view cells2945 if (0)2946 stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);2947 2948 int limit = min(leafOut, (int)mViewCells.size());2949 2950 int raysOut;2951 2952 //-- some rays for output2953 if (1)2954 raysOut = min((int)rays.size(), mVisualizationSamples);2955 2956 for (int i = 0; i < limit; ++ i)2957 {2958 cout << "creating output for view cell " << i << " ... ";2959 2960 VssRayContainer vcRays;2961 Intersectable::NewMail();2962 ViewCell *vc;2963 2964 if (0) // largest view cell pvs first2965 vc = mViewCells[i];2966 else2967 vc = mViewCells[Random((int)mViewCells.size())];2968 2969 vector<ViewCell *> leaves;2970 mViewCellsTree->CollectLeaves(vc, leaves);2971 2972 if (1)2973 {2974 // check whether we can add the current ray to the output rays2975 for (int k = 0; k < raysOut; ++ k)2976 {2977 VssRay *ray = rays[k];2978 for (int j = 0; j < (int)ray->mViewCells.size(); ++ j)2979 {2980 ViewCell *rayvc = ray->mViewCells[j];2981 2982 if (leaves[0] == rayvc)2983 vcRays.push_back(ray);2984 }2985 }2986 }2987 2988 //bspLeaves[j]->Mail();2989 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);2990 Exporter *exporter = Exporter::GetExporter(s);2991 exporter->SetWireframe();2992 2993 Material m;//= RandomMaterial();2994 m.mDiffuseColor = RgbColor(0, 1, 0);2995 exporter->SetForcedMaterial(m);2996 2997 ExportViewCellGeometry(exporter, vc);2998 2999 3000 Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc)3001 << ", piercing rays=" << (int)vcRays.size() << endl;3002 // << ", leaves=" << (int)vc->mLeaves.size() << endl;3003 3004 3005 //-- export rays piercing this view cell3006 if (1)3007 {3008 exporter->ExportRays(vcRays, RgbColor(1, 1, 1));3009 }3010 else3011 {3012 3013 ViewCellContainer leaves;3014 mViewCellsTree->CollectLeaves(vc, leaves);3015 3016 ViewCellContainer::const_iterator lit, lit_end = leaves.end();3017 3018 for (lit = leaves.begin(); lit != lit_end; ++ lit)3019 {3020 BspLeaf *l = dynamic_cast<BspViewCell *>(*lit)->mLeaf;3021 exporter->ExportRays(l->mVssRays);3022 }3023 }3024 3025 3026 m.mDiffuseColor = RgbColor(1, 0, 0);3027 exporter->SetForcedMaterial(m);3028 3029 ObjectPvsMap::const_iterator it,3030 it_end = vc->GetPvs().mEntries.end();3031 3032 exporter->SetFilled();3033 3034 3035 // output PVS of view cell3036 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)3037 {3038 3039 Intersectable *intersect = (*it).first;3040 3041 if (!intersect->Mailed())3042 {3043 Material m = RandomMaterial();3044 exporter->SetForcedMaterial(m);3045 3046 exporter->ExportIntersectable(intersect);3047 intersect->Mail();3048 }3049 }3050 3051 3052 DEL_PTR(exporter);3053 cout << "finished" << endl;3054 }3055 3056 Debug << endl;3057 }3058 3059 3060 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,3061 const Vector3 &termination,3062 ViewCellContainer &viewcells)3063 {3064 return mVspBspTree->CastLineSegment(origin, termination, viewcells);3065 }3066 3067 3068 void VspBspViewCellsManager::ExportColor(Exporter *exporter,3069 ViewCell *vc) const3070 {3071 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize);3072 3073 float importance = 0;3074 static Material m;3075 3076 switch (mColorCode)3077 {3078 case 0: // Random3079 {3080 if (vcValid)3081 {3082 m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f);3083 m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f);3084 m.mDiffuseColor.b = 0.5f + RandomValue(0.f, 0.5f);3085 }3086 else3087 {3088 m.mDiffuseColor.r = 0.0f;3089 m.mDiffuseColor.g = 1.0f;3090 m.mDiffuseColor.b = 0.0f;3091 }3092 3093 exporter->SetForcedMaterial(m);3094 return;3095 }3096 3097 case 1: // pvs3098 {3099 importance = (float)vc->GetPvs().GetSize() /3100 (float)mViewCellsStats.maxPvs;3101 3102 }3103 break;3104 case 2: // merges3105 {3106 int lSize = mViewCellsTree->GetSize(vc);3107 3108 3215 importance = (float)lSize / (float)mViewCellsStats.maxLeaves; 3109 3216 } … … 3164 3271 *cuttingPlane, 3165 3272 mViewSpaceBox, 3166 0.0001); 3167 3168 exporter->ExportPolygons(back.mPolys); 3273 0.0001f); 3274 3275 if ((int)back.mPolys.size() >= 3) 3276 exporter->ExportPolygons(back.mPolys); 3169 3277 } 3170 3278 } -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
r599 r600 355 355 356 356 void CollectViewCells(const int n) { 357 mNum MergedViewCells = n;357 mNumActiveViewCells = n; 358 358 mViewCells.clear(); 359 359 CollectViewCells(); … … 454 454 float mMaxPvsRatio; 455 455 456 int mNumMergedViewCells; 457 456 int mNumActiveViewCells; 458 457 bool mCompressViewCells; 459 458 -
trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
r590 r600 86 86 //-- max cost ratio for early tree termination 87 87 environment->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio); 88 88 mTermMinPolygons = 25; 89 89 //-- factors for bsp tree split plane heuristics 90 90 environment->GetFloatValue("VspBspTree.Factor.balancedRays", mBalancedRaysFactor); … … 116 116 117 117 118 mSubdivisionStats.open("subdivisionStats.log"); 118 119 119 120 … … 387 388 388 389 // return memory usage in MB 389 float VspBspTree::GetMemUsage(/*const VspBspTraversal Stack&tstack*/) const390 float VspBspTree::GetMemUsage(/*const VspBspTraversalQueue &tstack*/) const 390 391 { 391 392 return … … 402 403 void VspBspTree::Construct(const PolygonContainer &polys, RayInfoContainer *rays) 403 404 { 404 VspBspTraversal Stack tStack;405 VspBspTraversalQueue tQueue; 405 406 406 407 mRoot = new BspLeaf(); … … 426 427 tData.mIsKdNode = false; 427 428 428 tStack.push(tData); 429 429 tQueue.push(tData); 430 431 mTotalCost = tData.GetCost() / mBox.GetVolume(); 432 433 Debug << "total cost: " << mTotalCost << endl; 434 mSplits = 0; 435 430 436 mBspStats.Start(); 431 437 cout << "Contructing vsp bsp tree ... \n"; … … 440 446 int nleaves = 500; 441 447 442 while (!t Stack.empty())443 { 444 tData = t Stack.top();445 t Stack.pop();448 while (!tQueue.empty()) 449 { 450 tData = tQueue.top(); 451 tQueue.pop(); 446 452 447 453 if (0 && !mOutOfMemory) … … 457 463 458 464 // subdivide leaf node 459 BspNode *r = Subdivide(t Stack, tData);465 BspNode *r = Subdivide(tQueue, tData); 460 466 461 467 if (r == mRoot) … … 489 495 (data.mProbability <= mTermMinProbability) || 490 496 (mBspStats.Leaves() >= mMaxViewCells) || 497 #if 0 498 (((int)data.mPolygons->size() <= mTermMinPolygons) && !data.mPolygons->empty())|| 499 #endif 491 500 (data.GetAvgRayContribution() > mTermMaxRayContribution) || 492 501 (data.mDepth >= mTermMaxDepth)); … … 494 503 495 504 496 BspNode *VspBspTree::Subdivide(VspBspTraversal Stack &tStack,505 BspNode *VspBspTree::Subdivide(VspBspTraversalQueue &tQueue, 497 506 VspBspTraversalData &tData) 498 507 { … … 512 521 if (!newNode->IsLeaf()) //-- continue subdivision 513 522 { 523 if (1) 524 { 525 float costDecr = 526 (tFrontData.GetCost() + tBackData.GetCost() - tData.GetCost()) / mBox.GetVolume(); 527 mTotalCost += costDecr; 528 529 mSubdivisionStats 530 << "#Nodes\n" << ++ mSplits << endl 531 << "#RenderCostDecrease\n" << -costDecr << endl 532 << "#TotalRenderCost\n" << mTotalCost << endl; 533 } 534 514 535 // push the children on the stack 515 t Stack.push(tFrontData);516 t Stack.push(tBackData);536 tQueue.push(tFrontData); 537 tQueue.push(tBackData); 517 538 518 539 // delete old leaf node … … 1341 1362 float oldCost, newCost; 1342 1363 1364 // only render cost 1343 1365 if (1) 1344 1366 { … … 1346 1368 newCost = newRenderCost; 1347 1369 } 1348 else 1370 else // also considering standard deviation 1349 1371 { 1350 1372 // standard deviation is difference of back and front pvs … … 1361 1383 1362 1384 cost += mPvsFactor * newCost / oldCost; 1363 }1364 else1365 {1366 //-- compute weighted sum of expected render cost and standard deviation1367 1368 //-- first compute expected render cost1369 const float penaltyOld = EvalPvsPenalty(totalPvs, lowerPvsLimit, upperPvsLimit);1370 const float penaltyFront = EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit);1371 const float penaltyBack = EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit);1372 1373 const float renderCostFront = penaltyFront * pFront;1374 const float renderCostBack = penaltyBack * pBack;1375 1376 const float oldRenderCost = pOverall * (float)penaltyOld + Limits::Small;1377 const float newRenderCost = renderCostFront + renderCostBack;1378 1379 1380 //-- compute standard deviation1381 const float expectedCost = 0.5f * (renderCostBack + renderCostFront);1382 1383 const float devFront = fabs(renderCostFront - expectedCost);1384 1385 const float devBack = fabs(renderCostBack - expectedCost);1386 1387 const float newDev = 0.5f * (devFront + devBack);1388 const float oldDev = oldRenderCost * oldRenderCost;1389 1390 const float newCost = newRenderCost * mRenderCostWeight + newDev * (1.0f - mRenderCostWeight);1391 const float oldCost = oldRenderCost * mRenderCostWeight + oldDev * (1.0f - mRenderCostWeight);1392 1393 cost += mPvsFactor * newCost / oldCost;1394 1395 // also try to equalize render differences between front and back pvs1396 //const float oldCost = pOverall + Limits::Small;1397 //float newCost = (float)abs(pvsFront - pvsBack);1398 1399 1385 } 1400 1386 } … … 1404 1390 << " frontpvs: " << pvsFront << " pFront: " << pFront 1405 1391 << " backpvs: " << pvsBack << " pBack: " << pBack << endl << endl; 1392 Debug << "cost: " << cost << endl; 1406 1393 #endif 1407 1394 1395 1408 1396 // normalize cost by sum of linear factors 1409 1397 if(0) … … 1638 1626 int hits = 0; 1639 1627 1640 stack<BspRayTraversalData> t Stack;1628 stack<BspRayTraversalData> tQueue; 1641 1629 1642 1630 float maxt, mint; … … 1646 1634 1647 1635 Intersectable::NewMail(); 1648 1636 ViewCell::NewMail(); 1649 1637 Vector3 entp = ray.Extrap(mint); 1650 1638 Vector3 extp = ray.Extrap(maxt); … … 1690 1678 1691 1679 // push data for far child 1692 t Stack.push(BspRayTraversalData(farChild, extp, maxt));1680 tQueue.push(BspRayTraversalData(farChild, extp, maxt)); 1693 1681 1694 1682 // find intersection of ray segment with plane … … 1709 1697 1710 1698 //-- fetch the next far child from the stack 1711 if (t Stack.empty())1699 if (tQueue.empty()) 1712 1700 break; 1713 1701 … … 1718 1706 break; 1719 1707 1720 BspRayTraversalData &s = t Stack.top();1708 BspRayTraversalData &s = tQueue.top(); 1721 1709 1722 1710 node = s.mNode; … … 1724 1712 maxt = s.mMaxT; 1725 1713 1726 t Stack.pop();1714 tQueue.pop(); 1727 1715 } 1728 1716 } … … 2204 2192 return (int)neighbors.size(); 2205 2193 } 2194 2195 2196 2197 int VspBspTree::FindApproximateNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 2198 const bool onlyUnmailed) const 2199 { 2200 stack<bspNodePair> nodeStack; 2201 2202 BspNodeGeometry nodeGeom; 2203 ConstructGeometry(n, nodeGeom); 2204 2205 // split planes from the root to this node 2206 // needed to verify that we found neighbor leaf 2207 // TODO: really needed? 2208 vector<Plane3> halfSpaces; 2209 ExtractHalfSpaces(n, halfSpaces); 2210 2211 2212 BspNodeGeometry *rgeom = new BspNodeGeometry(); 2213 ConstructGeometry(mRoot, *rgeom); 2214 2215 nodeStack.push(bspNodePair(mRoot, rgeom)); 2216 2217 while (!nodeStack.empty()) 2218 { 2219 BspNode *node = nodeStack.top().first; 2220 BspNodeGeometry *geom = nodeStack.top().second; 2221 2222 nodeStack.pop(); 2223 2224 if (node->IsLeaf()) 2225 { 2226 // test if this leaf is in valid view space 2227 if (node->TreeValid() && 2228 (node != n) && 2229 (!onlyUnmailed || !node->Mailed())) 2230 { 2231 bool isAdjacent = true; 2232 2233 // neighbor was found 2234 if (isAdjacent) 2235 { 2236 neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 2237 } 2238 } 2239 } 2240 else 2241 { 2242 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2243 2244 const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys, 2245 interior->GetPlane(), 2246 mEpsilon); 2247 2248 BspNode *front = interior->GetFront(); 2249 BspNode *back = interior->GetBack(); 2250 2251 BspNodeGeometry *fGeom = new BspNodeGeometry(); 2252 BspNodeGeometry *bGeom = new BspNodeGeometry(); 2253 2254 geom->SplitGeometry(*fGeom, 2255 *bGeom, 2256 interior->GetPlane(), 2257 mBox, 2258 mEpsilon); 2259 2260 if (cf == Polygon3::FRONT_SIDE) 2261 { 2262 nodeStack.push(bspNodePair(interior->GetFront(), fGeom)); 2263 DEL_PTR(bGeom); 2264 } 2265 else 2266 { 2267 if (cf == Polygon3::BACK_SIDE) 2268 { 2269 nodeStack.push(bspNodePair(interior->GetBack(), bGeom)); 2270 DEL_PTR(fGeom); 2271 } 2272 else 2273 { // random decision 2274 nodeStack.push(bspNodePair(front, fGeom)); 2275 nodeStack.push(bspNodePair(back, bGeom)); 2276 } 2277 } 2278 } 2279 2280 DEL_PTR(geom); 2281 } 2282 2283 return (int)neighbors.size(); 2284 } 2285 2206 2286 2207 2287 … … 2378 2458 { 2379 2459 int hits = 0; 2380 stack<BspRayTraversalData> t Stack;2460 stack<BspRayTraversalData> tQueue; 2381 2461 2382 2462 float mint = 0.0f, maxt = 1.0f; 2383 2463 2384 2464 Intersectable::NewMail(); 2465 ViewCell::NewMail(); 2385 2466 2386 2467 Vector3 entp = origin; … … 2431 2512 2432 2513 // push data for far child 2433 t Stack.push(BspRayTraversalData(farChild, extp));2514 tQueue.push(BspRayTraversalData(farChild, extp)); 2434 2515 2435 2516 // find intersection of ray segment with plane … … 2450 2531 2451 2532 //-- fetch the next far child from the stack 2452 if (t Stack.empty())2533 if (tQueue.empty()) 2453 2534 break; 2454 2535 2455 2536 entp = extp; 2456 2537 2457 BspRayTraversalData &s = t Stack.top();2538 BspRayTraversalData &s = tQueue.top(); 2458 2539 2459 2540 node = s.mNode; 2460 2541 extp = s.mExitPoint; 2461 2542 2462 t Stack.pop();2543 tQueue.pop(); 2463 2544 } 2464 2545 } … … 2711 2792 vector<BspLeaf *> neighbors; 2712 2793 FindNeighbors(leaf, neighbors, true); 2713 2794 //FindApproximateNeighbors(leaf, neighbors, true); 2714 2795 vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end(); 2715 2796 -
trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
r591 r600 24 24 class Beam; 25 25 class ViewCellsTree; 26 26 27 27 28 struct BspRay; … … 123 124 float GetCost() const 124 125 { 125 #if 0126 #if 1 126 127 return mPvs * mProbability; 127 128 #endif 128 #if 1129 return - mDepth;129 #if 0 130 return (float) (-mDepth); // for regular grid 130 131 #endif 131 132 #if 0 … … 154 155 }; 155 156 156 typedef std::priority_queue<VspBspTraversalData> VspBspTraversal Stack;157 //typedef std::stack<VspBspTraversalData> VspBspTraversal Stack;157 typedef std::priority_queue<VspBspTraversalData> VspBspTraversalQueue; 158 //typedef std::stack<VspBspTraversalData> VspBspTraversalQueue; 158 159 159 160 /** Default constructor creating an empty tree. … … 292 293 293 294 295 int FindApproximateNeighbors(BspNode *n, 296 vector<BspLeaf *> &neighbors, 297 const bool onlyUnmailed) const; 298 294 299 /** Checks if tree validity-flags are right 295 300 with respect to view cell valitiy. … … 368 373 @returns new root of the subtree 369 374 */ 370 BspNode *Subdivide(VspBspTraversal Stack&tStack,375 BspNode *Subdivide(VspBspTraversalQueue &tStack, 371 376 VspBspTraversalData &tData); 372 377 … … 598 603 /** Returns estimated memory usage of tree. 599 604 */ 600 //float GetMemUsage(const VspBspTraversal Stack&tstack) const;605 //float GetMemUsage(const VspBspTraversalQueue &tstack) const; 601 606 float GetMemUsage() const; 602 607 … … 633 638 float mTermMinAccRayLength; 634 639 635 640 //HACK 641 int mTermMinPolygons; 636 642 637 643 //-- termination criteria for axis aligned split … … 677 683 int mMaxViewCells; 678 684 685 ofstream mSubdivisionStats; 679 686 680 687 // if rays should be stored in leaves … … 698 705 bool mOutOfMemory; 699 706 700 707 float mTotalCost; 708 int mSplits; 709 710 ofstream mSubdivsionStats; 711 701 712 private: 702 713 -
trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
r598 r600 77 77 int hits = 0; 78 78 static Ray ray; 79 AxisAlignedBox3 box = mKdTree->GetBox();79 AxisAlignedBox3 box = mViewSpaceBox ? *mViewSpaceBox : mKdTree->GetBox(); 80 80 81 81 AxisAlignedBox3 sbox = box; … … 203 203 { 204 204 Vector3 point; 205 if (!use2dSampling) { 206 if (0) { 207 Vector3 normal; 208 int i = Random((int)mObjects.size()); 209 Intersectable *object = mObjects[i]; 210 object->GetRandomSurfacePoint(point, normal); 211 } else 212 point = mKdTree->GetBox().GetRandomPoint(); 205 if (!use2dSampling) 206 { 207 if (0) 208 { 209 Vector3 normal; 210 int i = Random((int)mObjects.size()); 211 Intersectable *object = mObjects[i]; 212 object->GetRandomSurfacePoint(point, normal); 213 } 214 else 215 point = mKdTree->GetBox().GetRandomPoint(); 213 216 // point = viewpoint + UniformRandomVector(); 214 215 } else { 216 AxisAlignedBox3 box; 217 218 if (viewSpaceBox) 219 box =*viewSpaceBox; 220 else 221 box = mKdTree->GetBox(); 222 223 point = box.GetRandomPoint(); 224 point.y = viewpoint.y; 217 } 218 else 219 { 220 AxisAlignedBox3 box; 221 222 if (viewSpaceBox) 223 box =*viewSpaceBox; 224 else 225 box = mKdTree->GetBox(); 226 227 point = box.GetRandomPoint(); 228 point.y = viewpoint.y; 225 229 } 226 230 … … 528 532 { 529 533 if (0) 530 mViewSpaceBox = box;534 mViewSpaceBox = box; 531 535 else 532 536 { … … 536 540 Vector3 size = mViewSpaceBox->Size(); 537 541 //size[1] *= 1.25; 538 Vector3 enlarge(size[0] * 0. 1f, size[1] * 0.0f, size[2] * 0.1);542 Vector3 enlarge(size[0] * 0.25f, size[1] * 0.0f, size[2] * 0.25f); 539 543 540 544 mViewSpaceBox->Enlarge(enlarge);
Note: See TracChangeset
for help on using the changeset viewer.