#include #include #include #include #include "BvhLoader.h" #include "gzstream.h" namespace CHCDemoEngine { using namespace std; #define TYPE_INTERIOR -2 #define TYPE_LEAF -3 BvhNode *BvhLoader::LoadNextNode(igzstream &stream, BvhInterior *parent) { int nodeType; stream.read(reinterpret_cast(&nodeType), sizeof(int)); BvhNode *node; if (nodeType == TYPE_LEAF) node = new BvhLeaf(parent); else if (nodeType == TYPE_INTERIOR) node = new BvhInterior(parent); else cerr << "error: wrong node type: " << nodeType << endl; Vector3 bMin, bMax; stream.read(reinterpret_cast(&(node->mFirst)), sizeof(int)); stream.read(reinterpret_cast(&(node->mLast)), sizeof(int)); stream.read(reinterpret_cast(&bMin), sizeof(Vector3)); stream.read(reinterpret_cast(&bMax), sizeof(Vector3)); node->mBox = AxisAlignedBox3(bMin, bMax); node->mArea = node->mBox.SurfaceArea(); //cout << "box: " << node->mBox << " area: " << node->mArea << endl; return node; } Bvh *BvhLoader::Load(const string &filename, const SceneEntityContainer &entities) { queue tQueue; igzstream stream(filename.c_str()); if (!stream.is_open()) return NULL; cout << "loading bvh" << endl; Bvh *bvh = new Bvh(entities); bvh->mRoot = LoadNextNode(stream, NULL); tQueue.push(bvh->mRoot); bvh->mNumNodes = 1; while(!tQueue.empty()) { BvhNode *node = tQueue.front(); tQueue.pop(); if (!node->IsLeaf()) { bvh->mNumNodes += 2; BvhInterior *interior = static_cast(node); BvhNode *front = LoadNextNode(stream, interior); BvhNode *back = LoadNextNode(stream, interior); interior->mFront = front; interior->mBack = back; front->mDepth = interior->mDepth + 1; back->mDepth = interior->mDepth + 1; tQueue.push(front); tQueue.push(back); } } cout << "... finished loading " << bvh->mNumNodes << " nodes, updating boxes" << endl; bvh->mBox = bvh->mRoot->GetBox(); cout << "scene box: " << bvh->mBox << endl; /////////// //-- post process nodes bvh->PostProcess(); // set virtual leaves for specified number of triangles bvh->SetVirtualLeaves(INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES); bvh->UpdateNumLeaves(bvh->mRoot); // compute unique ids bvh->ComputeIds(); // specify bounds for occlusion tests bvh->RecomputeBounds(); // compute and print stats bvh->ComputeBvhStats(); bvh->PrintBvhStats(); return bvh; } }