BVHNode* BVHBuild::run() { BVHRange root; /* add references */ add_references(root); if(progress.get_cancel()) return NULL; /* init spatial splits */ if(params.top_level) /* todo: get rid of this */ params.use_spatial_split = false; spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha; spatial_right_bounds.clear(); spatial_right_bounds.resize(max(root.size(), (int)BVHParams::NUM_SPATIAL_BINS) - 1); /* init progress updates */ progress_start_time = time_dt(); progress_count = 0; progress_total = references.size(); progress_original_total = progress_total; prim_segment.resize(references.size()); prim_index.resize(references.size()); prim_object.resize(references.size()); /* build recursively */ BVHNode *rootnode; if(params.use_spatial_split) { /* singlethreaded spatial split build */ rootnode = build_node(root, 0); } else { /* multithreaded binning build */ BVHObjectBinning rootbin(root, (references.size())? &references[0]: NULL); rootnode = build_node(rootbin, 0); task_pool.wait_work(); } /* delete if we canceled */ if(rootnode) { if(progress.get_cancel()) { rootnode->deleteSubtree(); rootnode = NULL; } else if(!params.use_spatial_split) { /*rotate(rootnode, 4, 5);*/ rootnode->update_visibility(); } } return rootnode; }
BVHNode* BVHBuild::run() { BVHRange root; /* add references */ add_references(root); if(progress.get_cancel()) return NULL; /* init spatial splits */ if(params.top_level) { /* NOTE: Technically it is supported by the builder but it's not really * optimized for speed yet and not really clear yet if it has measurable * improvement on render time. Needs some extra investigation before * enabling spatial split for top level BVH. */ params.use_spatial_split = false; } spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha; if(params.use_spatial_split) { /* NOTE: The API here tries to be as much ready for multi-threaded build * as possible, but at the same time it tries not to introduce any * changes in behavior for until all refactoring needed for threading is * finished. * * So we currently allocate single storage for now, which is only used by * the only thread working on the spatial BVH build. */ spatial_storage.resize(TaskScheduler::num_threads() + 1); size_t num_bins = max(root.size(), (int)BVHParams::NUM_SPATIAL_BINS) - 1; foreach(BVHSpatialStorage &storage, spatial_storage) { storage.right_bounds.clear(); } spatial_storage[0].right_bounds.resize(num_bins); }