Back to home page

EIC code displayed by LXR

 
 

    


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 /// This builder is only a wrapper around all the other builders, which selects the best builder
0013 /// depending on the desired BVH quality and whether a multi-threaded build is desired.
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         /// The quality of the BVH produced by the builder. The higher the quality the faster the
0025         /// BVH is to traverse, but the slower it is to build.
0026         Quality quality = Quality::High;
0027 
0028         /// Threshold, in number of primitives, under which the builder operates in a single-thread.
0029         size_t parallel_threshold = 1024;
0030     };
0031 
0032     /// Build a BVH in parallel using the given thread pool.
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     /// Build a BVH in a single-thread.
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 } // namespace bvh::v2
0077 
0078 #endif