/* prints the bvh4.triangle4v data structure */ void print_bvh4_triangle4v(BVH4::NodeRef node, size_t depth) { if (node.isNode()) { BVH4::Node* n = node.node(); std::cout << "Node {" << std::endl; for (size_t i=0; i<BVH4::N; i++) { for (size_t k=0; k<depth; k++) std::cout << " "; std::cout << " bounds" << i << " = " << n->bounds(i) << std::endl; } for (size_t i=0; i<BVH4::N; i++) { if (n->child(i) == BVH4::emptyNode) continue; for (size_t k=0; k<depth; k++) std::cout << " "; std::cout << " child" << i << " = "; print_bvh4_triangle4v(n->child(i),depth+1); } for (size_t k=0; k<depth; k++) std::cout << " "; std::cout << "}" << std::endl; } else { size_t num; const Triangle4v* tri = (const Triangle4v*) node.leaf(num); std::cout << "Leaf {" << std::endl; for (size_t i=0; i<num; i++) { for (size_t j=0; j<tri[i].size(); j++) { for (size_t k=0; k<depth; k++) std::cout << " "; std::cout << " Triangle { v0 = (" << tri[i].v0.x[j] << ", " << tri[i].v0.y[j] << ", " << tri[i].v0.z[j] << "), " "v1 = (" << tri[i].v1.x[j] << ", " << tri[i].v1.y[j] << ", " << tri[i].v1.z[j] << "), " "v2 = (" << tri[i].v2.x[j] << ", " << tri[i].v2.y[j] << ", " << tri[i].v2.z[j] << "), " "geomID = " << tri[i].geomID(j) << ", primID = " << tri[i].primID(j) << " }" << std::endl; } } for (size_t k=0; k<depth; k++) std::cout << " "; std::cout << "}" << std::endl; } }
void BVH4BuilderTopLevel::open_sequential() { size_t N = max(2*refs.size(),size_t(MIN_OPEN_SIZE)); refs.reserve(N); std::make_heap(refs.begin(),refs.end()); while (refs.size()+3 <= N) { std::pop_heap (refs.begin(),refs.end()); BVH4::NodeRef ref = refs.back().node; if (ref.isLeaf()) break; refs.pop_back(); BVH4::Node* node = ref.node(); for (size_t i=0; i<4; i++) { if (node->child(i) == BVH4::emptyNode) continue; refs.push_back(BuildRef(node->bounds(i),node->child(i))); std::push_heap (refs.begin(),refs.end()); } } }
void BVH4BuilderTopLevel::task_open_parallel(size_t threadIndex, size_t threadCount, size_t taskIndex, size_t taskCount, TaskScheduler::Event* event) { size_t N = global_dest; size_t M = refs1.size(); const size_t start0 = (threadIndex+0)*N/threadCount; const size_t end0 = (threadIndex+1)*N/threadCount; const size_t start1 = (threadIndex+0)*M/threadCount; const size_t end1 = (threadIndex+1)*M/threadCount; assert(end1-start1 >= end0-start0); BuildRef* prefs1 = &refs1[0]; /* copy from refs buffer to refs1 buffer */ for (size_t i=start0, j=start1; i<end0; i++, j++) refs1[j] = refs[i]; /* create max heap in our set of items */ size_t start = start1; size_t end = start1+end0-start0; std::make_heap(&prefs1[start],&prefs1[end]); float max_volume = 0.0f; while (true) { barrier.wait(threadIndex,threadCount); if (threadIndex == 0) global_max_volume = 0.0f; barrier.wait(threadIndex,threadCount); /* parallel calculation of maximal volume */ max_volume = 0.0f; if (end+3 <= end1) for (size_t i=start; i<end; i++) max_volume = max(max_volume,prefs1[i].lower.w); atomic_max_f32(&global_max_volume,max_volume); barrier.wait(threadIndex,threadCount); max_volume = global_max_volume; barrier.wait(threadIndex,threadCount); /* if maximal volume is 0, all threads are finished */ if (max_volume == 0.0f) break; /* open all nodes that are considered large in this iteration */ while (end+3 <= end1) { if (end-start == 0) break; std::pop_heap(&prefs1[start],&prefs1[end]); BVH4::NodeRef ref = prefs1[end-1].node; float vol = prefs1[end-1].lower.w; if (ref.isLeaf() || vol < 0.5f*max_volume) { std::push_heap(&prefs1[start],&prefs1[end]); break; } end--; BVH4::Node* node = ref.node(); for (size_t i=0; i<4; i++) { if (node->child(i) == BVH4::emptyNode) continue; prefs1[end++] = BuildRef(node->bounds(i),node->child(i)); std::push_heap(&prefs1[start],&prefs1[end]); } } } if (threadIndex == 0) global_dest = 0; barrier.wait(threadIndex,threadCount); /* copy again back to refs array */ size_t dest = atomic_add(&global_dest,end-start); for (size_t i=start, j=dest; i<end; i++, j++) refs[j] = refs1[i]; }