#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, float viewCellsScaleFactor) { FILE *fr = fopen(filename.c_str(), "rb"); cout << "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); cout << "loading view cells" << endl; ViewCellsTree *viewCellsTree = new ViewCellsTree(); bool ok = viewCellsTree->_LoadFromFile(fr, viewCellsScaleFactor); cout << "finished loading view cells" << endl; if (ok) { // skip loading of bvh nodes int buffer[6]; fread(buffer, sizeof(int), 6, fr); const int numNodes = buffer[5]; const int numTriangleIds = buffer[2]; // skip triangle ids cout << "skipping " << numTriangleIds << " triangle ids" << endl; int tid; for (int i = 0; i < numTriangleIds; ++ i) fread(&tid, sizeof(int), 1, fr); cout << "skipping " << numNodes << " bvh nodes" << endl; for (int i = 0; i < numNodes; ++ i) fread(buffer, sizeof(int), 4, fr); cout << "allocating view cells" << endl; AllocateLeafViewCells(viewCellsTree); cout << "loading pvss" << endl; ok = LoadPvs(fr, bvh); cout << "finished loading pvss" << endl; } fclose(fr); if (ok) cout << "Visibility solution loaded" << endl; else cerr << "Error: loading visibility solution failed." << endl; return viewCellsTree; } bool VisibilitySolutionLoader::CreateIdSortedList(Bvh *bvh, BvhNodeContainer &nodes) { std::stack tStack; tStack.push(bvh->GetStaticRoot()); 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) { cerr << "Warning: empty PVSs in visibility solution" << endl; return true; } if (number != mViewCells.size()) { cerr << "Warning: Number of view cells (" << number << ", " << (int)mViewCells.size() << ") 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]; mViewCells[i]->mPvs.AddEntry(bvh, node); } } return true; } void VisibilitySolutionLoader::AllocateLeafViewCells(ViewCellsTree *viewCellsTree) { stack< pair > nodeStack; nodeStack.push(pair (viewCellsTree->mRoot, viewCellsTree->mBox)); int id = 0; mViewCells.clear(); int axes[] = {0, 0, 0}; while (!nodeStack.empty()) { ViewCellsTreeNode *node = nodeStack.top().first; if (node->IsLeaf()) { if (!node->mViewCell) { 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 newBox1 = box; AxisAlignedBox3 newBox2 = box; /*if (node->mPosition < newBox.Min(node->mAxis)) cout << "e: " << node->mPosition << " " << newBox.Min(node->mAxis) << endl; else if (node->mPosition > newBox.Min(node->mAxis)) cout << "o: " << node->mPosition << " " << newBox.Min(node->mAxis) << endl; */ newBox1.SetMin(node->mAxis, node->mPosition); newBox2.SetMax(node->mAxis, node->mPosition); ++ axes[node->mAxis]; if (node->mAxis == 1) { nodeStack.push(pair(node->mBack, newBox2)); nodeStack.push(pair(node->mFront, newBox1)); } else { nodeStack.push(pair(node->mFront, newBox1)); nodeStack.push(pair(node->mBack, newBox2)); } } } cout << "loaded " << id << " view cells" << endl; } }