Changeset 600 for trunk/VUT/GtpVisibilityPreprocessor/src
- Timestamp:
- 02/06/06 19:09:53 (18 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor/src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
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.