#include "VisibilitySolutionLoader.h" #include "ViewCellsTree.h" #include "Bvh.h" #include using namespace std; namespace CHCDemoEngine { typedef vector ViewCellsContainer; ViewCellsTree *VisibilitySolutionLoader::Load(const std::string &filename, Bvh *bvh) { FILE *fr = fopen(filename.c_str(), "rb"); cout << "Info: Loading visibility solution from file '" + filename + "'" << endl; if (fr == NULL) { cerr << "Error: Cannot open file for reading" << endl; return NULL; } float totalSamples; float totalTime; fread(&totalSamples, sizeof(float), 1, fr); fread(&totalTime, sizeof(float), 1, fr); ViewCellsTree *viewCellsTree = new ViewCellsTree(); bool ok = viewCellsTree->_LoadFromFile(fr); if (ok) { // skip bvh loading int buffer[6]; fread(buffer, sizeof(int), 6, fr); const size_t numNodes = buffer[5]; for (int i = 0; i < numNodes; ++ i) fread(buffer, sizeof(int), 4, fr); AllocateLeafViewCells(viewCellsTree); ok = LoadPvs(fr, bvh); } fclose(fr); if (ok) cerr << "Info: visibility solution loaded" << endl; else cerr << "Info: loading visibility solution failed." << endl; return viewCellsTree; } bool VisibilitySolutionLoader::CreateIdSortedList(Bvh *bvh, BvhNodeContainer &nodes) { std::stack tStack; tStack.push(bvh->GetRoot()); while (!tStack.empty()) { BvhNode *node = tStack.top(); tStack.pop(); nodes.push_back(node); if (!node->IsLeaf()) { BvhInterior *interior = static_cast(node); BvhNode *front = interior->GetFront(); BvhNode *back = interior->GetBack(); tStack.push(front); tStack.push(back); } } return true; } bool VisibilitySolutionLoader::LoadPvs(FILE *fw, Bvh *bvh) { int number, entries; fread(&number, sizeof(int), 1, fw); if (number == 0) { cerr << "Info: Warning empty PVSs in visibility solution" << endl; return true; } if (number != mViewCells.size()) { cerr << "Info: Number of view cells does not match when loading PVSs!" << endl; return false; } BvhNodeContainer nodes; CreateIdSortedList(bvh, nodes); for (int i = 0; i < number; ++ i) { fread(&entries, sizeof(int), 1, fw); for (int j=0; j < entries; ++ j) { int objectId; float time; fread(&objectId, sizeof(int), 1, fw); fread(&time, sizeof(float), 1, fw); BvhNode *node = nodes[objectId]; int geometrySize; SceneEntity **entities; entities = bvh->GetGeometry(node, geometrySize); for (int k = 0; k < geometrySize; ++ k) { mViewCells[i]->mPvs.AddEntry(entities[k]); } } } return true; } void VisibilitySolutionLoader::AllocateLeafViewCells(ViewCellsTree *viewCellsTree) { stack< pair > nodeStack; nodeStack.push(pair (viewCellsTree->mRoot, viewCellsTree->mBox)); int id = 0; mViewCells.clear(); while (!nodeStack.empty()) { ViewCellsTreeNode *node = nodeStack.top().first; if (node->IsLeaf()) { if (node->mViewCell == NULL) { node->mViewCell = new ViewCell(); node->mViewCell->SetId(id ++); node->mViewCell->SetBox(nodeStack.top().second); } mViewCells.push_back(node->mViewCell); nodeStack.pop(); } else { AxisAlignedBox3 box = nodeStack.top().second; nodeStack.pop(); AxisAlignedBox3 newBox = box; newBox.SetMin(node->mAxis, node->mPosition); nodeStack.push( pair(node->mFront, newBox) ); newBox = box; newBox.SetMax(node->mAxis, node->mPosition); nodeStack.push( pair(node->mBack, newBox) ); } } cout << "#of viewcells = " << id << endl; } }