File indexing completed on 2025-09-17 09:13:46
0001 #ifndef BVH_V2_DEFAULT_BUILDER_H
0002 #define BVH_V2_DEFAULT_BUILDER_H
0003
0004 #include "bvh/v2/mini_tree_builder.h"
0005 #include "bvh/v2/sweep_sah_builder.h"
0006 #include "bvh/v2/binned_sah_builder.h"
0007 #include "bvh/v2/reinsertion_optimizer.h"
0008 #include "bvh/v2/thread_pool.h"
0009
0010 namespace bvh::v2 {
0011
0012
0013
0014 template <typename Node>
0015 class DefaultBuilder {
0016 using Scalar = typename Node::Scalar;
0017 using Vec = bvh::v2::Vec<Scalar, Node::dimension>;
0018 using BBox = bvh::v2::BBox<Scalar, Node::dimension>;
0019
0020 public:
0021 enum class Quality { Low, Medium, High };
0022
0023 struct Config : TopDownSahBuilder<Node>::Config {
0024
0025
0026 Quality quality = Quality::High;
0027
0028
0029 size_t parallel_threshold = 1024;
0030 };
0031
0032
0033 BVH_ALWAYS_INLINE static Bvh<Node> build(
0034 ThreadPool& thread_pool,
0035 std::span<const BBox> bboxes,
0036 std::span<const Vec> centers,
0037 const Config& config = {})
0038 {
0039 if (bboxes.size() < config.parallel_threshold)
0040 return build(bboxes, centers, config);
0041 auto bvh = MiniTreeBuilder<Node>::build(
0042 thread_pool, bboxes, centers, make_mini_tree_config(config));
0043 if (config.quality == Quality::High)
0044 ReinsertionOptimizer<Node>::optimize(thread_pool, bvh);
0045 return bvh;
0046 }
0047
0048
0049 BVH_ALWAYS_INLINE static Bvh<Node> build(
0050 std::span<const BBox> bboxes,
0051 std::span<const Vec> centers,
0052 const Config& config = {})
0053 {
0054 if (config.quality == Quality::Low)
0055 return BinnedSahBuilder<Node>::build(bboxes, centers, config);
0056 else {
0057 auto bvh = SweepSahBuilder<Node>::build(bboxes, centers, config);
0058 if (config.quality == Quality::High)
0059 ReinsertionOptimizer<Node>::optimize(bvh);
0060 return bvh;
0061 }
0062 }
0063
0064 private:
0065 BVH_ALWAYS_INLINE static auto make_mini_tree_config(const Config& config) {
0066 typename MiniTreeBuilder<Node>::Config mini_tree_config;
0067 static_cast<typename TopDownSahBuilder<Node>::Config&>(mini_tree_config) = config;
0068 mini_tree_config.enable_pruning = config.quality == Quality::Low ? false : true;
0069 mini_tree_config.pruning_area_ratio =
0070 config.quality == Quality::High ? static_cast<Scalar>(0.01) : static_cast<Scalar>(0.1);
0071 mini_tree_config.parallel_threshold = config.parallel_threshold;
0072 return mini_tree_config;
0073 }
0074 };
0075
0076 }
0077
0078 #endif