#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]; if (node->IsLeaf()) { BvhLeaf *leaf = (BvhLeaf*)node; buffer[0] = mTriangleRangeMap[leaf].first; buffer[1] = mTriangleRangeMap[leaf].second; buffer[2] = -1;//leaf->GetAxis(); buffer[3] = currentIdx ++; fwrite(buffer, sizeof(int), 4, fw); } else { BvhInterior *interior = (BvhInterior *)node; buffer[0] = interior->mFirst; buffer[1] = interior->mLast; buffer[2] = 0;//interior->mAxis; buffer[3] = currentIdx ++; 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->IsLeaf()) { int m; BvhInterior *interior = static_cast(node); ConstructTriangleRangeMap(bvh, interior->GetFront(), first, m); int newFirst = m + 1; ConstructTriangleRangeMap(bvh, interior->GetBack(), newFirst, last); mTriangleRangeMap[node] = pair(first, last); } else { //first = currentIdx; last = first + bvh->CountTriangles(node) - 1; //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->CountNumNodes(bvh->GetStaticRoot()); int first = 0, last; ConstructTriangleRangeMap(bvh, bvh->GetStaticRoot(), first, last); BvhLeafContainer nodes; bvh->CollectLeaves(bvh->GetStaticRoot(), nodes); vector triangles; BvhLeafContainer::const_iterator it, it_end = nodes.end(); for (it = nodes.begin(); it != it_end; ++ it) { BvhNode *node = *it; int f = mTriangleRangeMap[node].first; 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; } }