unsigned int BVHAccel::BuildArray(BVHAccelTreeNode *node, unsigned int offset) { // Build array by recursively traversing the tree depth-first while (node) { BVHAccelArrayNode *p = &bvhTree[offset]; p->bbox = node->bbox; p->primitive = node->primitive; offset = BuildArray(node->leftChild, offset + 1); p->skipIndex = offset; node = node->rightSibling; } return offset; }
void BVHAccel::Init(const std::deque<Mesh *> &meshes, const unsigned int totalVertexCount, const unsigned int totalTriangleCount) { assert (!initialized); preprocessedMesh = TriangleMesh::Merge(totalVertexCount, totalTriangleCount, meshes, &preprocessedMeshIDs, &preprocessedMeshTriangleIDs); assert (preprocessedMesh->GetTotalVertexCount() == totalVertexCount); assert (preprocessedMesh->GetTotalTriangleCount() == totalTriangleCount); LR_LOG(ctx, "Total vertices memory usage: " << totalVertexCount * sizeof(Point) / 1024 << "Kbytes"); LR_LOG(ctx, "Total triangles memory usage: " << totalTriangleCount * sizeof(Triangle) / 1024 << "Kbytes"); const Point *v = preprocessedMesh->GetVertices(); const Triangle *p = preprocessedMesh->GetTriangles(); std::vector<BVHAccelTreeNode *> bvList; for (unsigned int i = 0; i < totalTriangleCount; ++i) { BVHAccelTreeNode *ptr = new BVHAccelTreeNode(); ptr->bbox = p[i].WorldBound(v); // NOTE - Ratow - Expand bbox a little to make sure rays collide ptr->bbox.Expand(MachineEpsilon::E(ptr->bbox)); ptr->primitive = i; ptr->leftChild = NULL; ptr->rightSibling = NULL; bvList.push_back(ptr); } LR_LOG(ctx, "Building Bounding Volume Hierarchy, primitives: " << totalTriangleCount); nNodes = 0; BVHAccelTreeNode *rootNode = BuildHierarchy(bvList, 0, bvList.size(), 2); LR_LOG(ctx, "Pre-processing Bounding Volume Hierarchy, total nodes: " << nNodes); bvhTree = new BVHAccelArrayNode[nNodes]; BuildArray(rootNode, 0); FreeHierarchy(rootNode); LR_LOG(ctx, "Total BVH memory usage: " << nNodes * sizeof(BVHAccelArrayNode) / 1024 << "Kbytes"); LR_LOG(ctx, "Finished building Bounding Volume Hierarchy array"); initialized = true; }
void BuildInput(void) { BuildArray(); BuildInitial(); }