1use std::time::{Duration, Instant};
2
3use crate::{
4 Boundable, BvhBuildParams, ploc::PlocBuilder, splits::split_aabbs_preset, triangle::Triangle,
5};
6
7use super::{Bvh2, leaf_collapser::collapse, reinsertion::ReinsertionOptimizer};
8
9pub fn build_bvh2_from_tris(
18 triangles: &[Triangle],
19 config: BvhBuildParams,
20 core_build_time: &mut Duration,
21) -> Bvh2 {
22 let mut bvh2;
23 let start_time;
24 if config.pre_split {
25 let mut largest_half_area = 0.0;
26 let mut avg_area = 0.0;
27
28 let mut aabbs = triangles
29 .iter()
30 .map(|tri| {
31 let aabb = tri.aabb();
32 let half_area = aabb.half_area();
33 largest_half_area = half_area.max(largest_half_area);
34 avg_area += half_area;
35 aabb
36 })
37 .collect::<Vec<_>>();
38 let mut indices = (0..triangles.len() as u32).collect::<Vec<_>>();
39
40 avg_area /= triangles.len() as f32;
41
42 start_time = Instant::now();
43
44 split_aabbs_preset(
45 &mut aabbs,
46 &mut indices,
47 triangles,
48 avg_area,
49 largest_half_area,
50 );
51 bvh2 = PlocBuilder::with_capacity(aabbs.len()).build(
52 config.ploc_search_distance,
53 &aabbs,
54 indices,
55 config.sort_precision,
56 config.search_depth_threshold,
57 );
58 } else {
59 start_time = Instant::now();
60 bvh2 = PlocBuilder::with_capacity(triangles.len()).build(
61 config.ploc_search_distance,
62 triangles,
63 (0..triangles.len() as u32).collect::<Vec<_>>(),
64 config.sort_precision,
65 config.search_depth_threshold,
66 );
67 }
68
69 bvh2.uses_spatial_splits = config.pre_split;
70 let mut reinsertion_optimizer = ReinsertionOptimizer::default();
71 reinsertion_optimizer.run(&mut bvh2, config.reinsertion_batch_ratio, None);
72 collapse(
73 &mut bvh2,
74 config.max_prims_per_leaf.clamp(1, 255),
75 config.collapse_traversal_cost,
76 );
77 reinsertion_optimizer.run(
78 &mut bvh2,
79 config.reinsertion_batch_ratio * config.post_collapse_reinsertion_batch_ratio_multiplier,
80 None,
81 );
82
83 *core_build_time += start_time.elapsed();
84
85 #[cfg(debug_assertions)]
86 {
87 bvh2.validate(triangles, false, config.pre_split);
88 }
89
90 bvh2
91}
92
93pub fn build_bvh2<T: Boundable>(
104 primitives: &[T],
105 config: BvhBuildParams,
106 core_build_time: &mut Duration,
107) -> Bvh2 {
108 let start_time = Instant::now();
109
110 let mut bvh2 = PlocBuilder::with_capacity(primitives.len()).build(
111 config.ploc_search_distance,
112 primitives,
113 (0..primitives.len() as u32).collect::<Vec<_>>(),
114 config.sort_precision,
115 config.search_depth_threshold,
116 );
117 let mut reinsertion_optimizer = ReinsertionOptimizer::default();
118 reinsertion_optimizer.run(&mut bvh2, config.reinsertion_batch_ratio, None);
119 collapse(
120 &mut bvh2,
121 config.max_prims_per_leaf.clamp(1, 255),
122 config.collapse_traversal_cost,
123 );
124 reinsertion_optimizer.run(
125 &mut bvh2,
126 config.reinsertion_batch_ratio * config.post_collapse_reinsertion_batch_ratio_multiplier,
127 None,
128 );
129
130 *core_build_time += start_time.elapsed();
131
132 #[cfg(debug_assertions)]
133 {
134 bvh2.validate(primitives, false, config.pre_split);
135 }
136
137 bvh2
138}