typename BVHN<N>::NodeRef BVHN<N>::layoutLargeNodesRecursion(NodeRef& node, FastAllocator::ThreadLocal& allocator) { if (node.isBarrier()) { node.clearBarrier(); return node; } else if (node.isAlignedNode()) { AlignedNode* oldnode = node.alignedNode(); AlignedNode* newnode = (BVHN::AlignedNode*) allocator.malloc(sizeof(BVHN::AlignedNode),byteNodeAlignment); *newnode = *oldnode; for (size_t c=0; c<N; c++) newnode->child(c) = layoutLargeNodesRecursion(oldnode->child(c),allocator); return encodeNode(newnode); } else return node; }
BBox3fa BVHNRefitter<N>::refit_toplevel(NodeRef& ref, size_t &subtrees, const BBox3fa *const subTreeBounds, const size_t depth) { if (depth >= MAX_SUB_TREE_EXTRACTION_DEPTH) { assert(subtrees < MAX_NUM_SUB_TREES); assert(subTrees[subtrees] == ref); return subTreeBounds[subtrees++]; } if (ref.isAlignedNode()) { AlignedNode* node = ref.alignedNode(); BBox3fa bounds[N]; for (size_t i=0; i<N; i++) { NodeRef& child = node->child(i); if (unlikely(child == BVH::emptyNode)) bounds[i] = BBox3fa(empty); else bounds[i] = refit_toplevel(child,subtrees,subTreeBounds,depth+1); } BBox3vf<N> boundsT = transpose<N>(bounds); /* set new bounds */ node->lower_x = boundsT.lower.x; node->lower_y = boundsT.lower.y; node->lower_z = boundsT.lower.z; node->upper_x = boundsT.upper.x; node->upper_y = boundsT.upper.y; node->upper_z = boundsT.upper.z; return merge<N>(bounds); } else return leafBounds.leafBounds(ref); }
void BVHNRefitter<N>::gather_subtree_refs(NodeRef& ref, size_t &subtrees, const size_t depth) { if (depth >= MAX_SUB_TREE_EXTRACTION_DEPTH) { assert(subtrees < MAX_NUM_SUB_TREES); subTrees[subtrees++] = ref; return; } if (ref.isAlignedNode()) { AlignedNode* node = ref.alignedNode(); for (size_t i=0; i<N; i++) { NodeRef& child = node->child(i); if (unlikely(child == BVH::emptyNode)) continue; gather_subtree_refs(child,subtrees,depth+1); } } }
typename BVHNStatistics<N>::Statistics BVHNStatistics<N>::statistics(NodeRef node, const double A, const BBox1f t0t1) { Statistics s; double dt = max(0.0f,t0t1.size()); if (node.isAlignedNode()) { AlignedNode* n = node.alignedNode(); for (size_t i=0; i<N; i++) { if (n->child(i) == BVH::emptyNode) continue; s.statAlignedNodes.numChildren++; const double Ai = max(0.0f,halfArea(n->extend(i))); s = s + statistics(n->child(i),Ai,t0t1); } s.statAlignedNodes.numNodes++; s.statAlignedNodes.nodeSAH += dt*A; s.depth++; } else if (node.isUnalignedNode()) { UnalignedNode* n = node.unalignedNode(); for (size_t i=0; i<N; i++) { if (n->child(i) == BVH::emptyNode) continue; s.statUnalignedNodes.numChildren++; const double Ai = max(0.0f,halfArea(n->extend(i))); s = s + statistics(n->child(i),Ai,t0t1); } s.statUnalignedNodes.numNodes++; s.statUnalignedNodes.nodeSAH += dt*A; s.depth++; } else if (node.isAlignedNodeMB()) { AlignedNodeMB* n = node.alignedNodeMB(); for (size_t i=0; i<N; i++) { if (n->child(i) == BVH::emptyNode) continue; s.statAlignedNodesMB.numChildren++; const double Ai = max(0.0f,halfArea(n->extend0(i))); s = s + statistics(n->child(i),Ai,t0t1); } s.statAlignedNodesMB.numNodes++; s.statAlignedNodesMB.nodeSAH += dt*A; s.depth++; } else if (node.isUnalignedNodeMB()) { UnalignedNodeMB* n = node.unalignedNodeMB(); for (size_t i=0; i<N; i++) { if (n->child(i) == BVH::emptyNode) continue; s.statUnalignedNodesMB.numChildren++; const double Ai = max(0.0f,halfArea(n->extend0(i))); s = s + statistics(n->child(i),Ai,t0t1); } s.statUnalignedNodesMB.numNodes++; s.statUnalignedNodesMB.nodeSAH += dt*A; s.depth++; } else if (node.isTransformNode()) { s.statTransformNodes.numNodes++; s.statTransformNodes.nodeSAH += dt*A; s.depth++; } else if (node.isQuantizedNode()) { QuantizedNode* n = node.quantizedNode(); for (size_t i=0; i<N; i++) { if (n->child(i) == BVH::emptyNode) continue; s.statQuantizedNodes.numChildren++; const double Ai = max(0.0f,halfArea(n->extend(i))); s = s + statistics(n->child(i),Ai,t0t1); } s.statQuantizedNodes.numNodes++; s.statQuantizedNodes.nodeSAH += dt*A; s.depth++; } else if (node.isLeaf()) { size_t num; const char* tri = node.leaf(num); if (num) { for (size_t i=0; i<num; i++) { s.statLeaf.numPrims += bvh->primTy.size(tri+i*bvh->primTy.bytes); } s.statLeaf.numLeaves++; s.statLeaf.numPrimBlocks += num; s.statLeaf.leafSAH += dt*A*num; if (num-1 < Statistics::LeafStat::NHIST) { s.statLeaf.numPrimBlocksHistogram[num-1]++; } } } else { throw std::runtime_error("not supported node type in bvh_statistics"); } return s; }