#include "BvhExporter.h" using namespace std; // MAGIC of all bin exports #ifndef MAGIC #define MAGIC 0x827923 #endif #define BVH_VERSION 2.1 namespace CHCDemoEngine { static int currentIdx = 0; void BvhExporter::SaveNode(BvhNode *node, FILE *fw) { if (!node) return; int buffer[4]; buffer[3] = currentIdx ++; if (node->IsVirtualLeaf()) { BvhLeaf *leaf = (BvhLeaf*)node; buffer[0] = mTriangleRangeMap[leaf].first; buffer[1] = mTriangleRangeMap[leaf].second; buffer[2] = -1;//leaf->GetAxis(); fwrite(buffer, sizeof(int), 4, fw); } else { BvhInterior *interior = (BvhInterior *)node; buffer[0] = interior->mFirst; buffer[1] = interior->mLast; buffer[2] = 0;//interior->mAxis; fwrite(buffer, sizeof(int), 4, fw); SaveNode(interior->GetFront(), fw); SaveNode(interior->GetBack(), fw); } } void BvhExporter::ConstructTriangleRangeMap(Bvh *bvh, BvhNode *node, int &first, int &last) { if (!node->IsVirtualLeaf()) { int m; BvhInterior *interior = static_cast(node); ConstructTriangleRangeMap(bvh, interior->GetBack(), first, m); int newFirst = m + 1; ConstructTriangleRangeMap(bvh, interior->GetFront(), newFirst, last); mTriangleRangeMap[node] = pair(first, last); } else { //first = currentIdx; last = first + bvh->CountTriangles(node) - 1; //cout << "x " << node->GetFirstEntity() << " " << node->GetLastEntity() << " " << first << " " << last << endl; //currentIdx = last; mTriangleRangeMap[node] = pair(first, last); } } bool BvhExporter::Export(const string &filename, Bvh *bvh) { cout << "Exporting bvh to file '" << filename.c_str() << "'" << endl; FILE *fw = fopen(filename.c_str(), "wb"); if (fw == NULL) { cerr << "Error: Cannot open file for writing" << endl; return false; } int buffer[6]; buffer[0] = MAGIC; buffer[1] = BVH_VERSION * 1000; buffer[3] = 0; // construction method buffer[4] = 1; // termination leaves buffer[5] = bvh->CountNumVirtualNodes(bvh->GetStaticRoot()); int first = 0, last; ConstructTriangleRangeMap(bvh, bvh->GetStaticRoot(), first, last); BvhNodeContainer nodes; bvh->CollectVirtualLeaves(bvh->GetStaticRoot(), nodes); vector triangles; BvhNodeContainer::const_iterator it, it_end = nodes.end(); for (it = nodes.begin(); it != it_end; ++ it) { BvhNode *node = *it; const int f = mTriangleRangeMap[node].first; const int l = mTriangleRangeMap[node].second; for (int i = f; i <= l; ++ i) triangles.push_back(i); } buffer[2] = (int)triangles.size(); fwrite(buffer, sizeof(int), 6, fw); cout << "writing " << (int)triangles.size() << " triangle ids ..." << endl; // export sorted triangle IDs for (size_t i = 0; i < triangles.size(); ++ i) { fwrite(&triangles[i], sizeof(int), 1, fw); } cout << "writing bvh nodes ..." << endl; SaveNode(bvh->GetStaticRoot(), fw); cout << "successfully exported bvh" << endl; fclose(fw); return true; } }