1use std::time::{Duration, Instant};
2
3use crate::{
4 Boundable, BvhBuildParams,
5 bvh2::reinsertion::ReinsertionOptimizer,
6 cwbvh::{CwBvh, bvh2_to_cwbvh::bvh2_to_cwbvh},
7 ploc::PlocBuilder,
8 splits::split_aabbs_preset,
9 triangle::Triangle,
10};
11
12pub fn build_cwbvh_from_tris(
21 triangles: &[Triangle],
22 config: BvhBuildParams,
23 core_build_time: &mut Duration,
24) -> CwBvh {
25 let mut bvh2;
26 let start_time;
27 if config.pre_split {
28 let mut largest_half_area = 0.0;
29 let mut avg_area = 0.0;
30
31 let mut aabbs = triangles
32 .iter()
33 .map(|tri| {
34 let aabb = tri.aabb();
35 let half_area = aabb.half_area();
36 largest_half_area = half_area.max(largest_half_area);
37 avg_area += half_area;
38 aabb
39 })
40 .collect::<Vec<_>>();
41 let mut indices = (0..triangles.len() as u32).collect::<Vec<_>>();
42
43 avg_area /= triangles.len() as f32;
44
45 start_time = Instant::now();
46
47 split_aabbs_preset(
48 &mut aabbs,
49 &mut indices,
50 triangles,
51 avg_area,
52 largest_half_area,
53 );
54 bvh2 = PlocBuilder::with_capacity(aabbs.len()).build(
55 config.ploc_search_distance,
56 &aabbs,
57 indices,
58 config.sort_precision,
59 config.search_depth_threshold,
60 );
61 } else {
62 start_time = Instant::now();
63 bvh2 = PlocBuilder::with_capacity(triangles.len()).build(
64 config.ploc_search_distance,
65 triangles,
66 (0..triangles.len() as u32).collect::<Vec<_>>(),
67 config.sort_precision,
68 config.search_depth_threshold,
69 );
70 }
71
72 bvh2.uses_spatial_splits = config.pre_split;
73 ReinsertionOptimizer::default().run(&mut bvh2, config.reinsertion_batch_ratio, None);
74 let cwbvh = bvh2_to_cwbvh(&bvh2, config.max_prims_per_leaf.clamp(1, 3), true, false);
75
76 *core_build_time += start_time.elapsed();
77
78 #[cfg(debug_assertions)]
79 {
80 bvh2.validate(triangles, false, config.pre_split);
81 cwbvh.validate(triangles, false);
82 }
83
84 cwbvh
85}
86
87pub fn build_cwbvh<T: Boundable>(
98 primitives: &[T],
99 config: BvhBuildParams,
100 core_build_time: &mut Duration,
101) -> CwBvh {
102 let start_time = Instant::now();
103
104 let mut bvh2 = PlocBuilder::with_capacity(primitives.len()).build(
105 config.ploc_search_distance,
106 primitives,
107 (0..primitives.len() as u32).collect::<Vec<_>>(),
108 config.sort_precision,
109 config.search_depth_threshold,
110 );
111 ReinsertionOptimizer::default().run(&mut bvh2, config.reinsertion_batch_ratio, None);
112 let cwbvh = bvh2_to_cwbvh(&bvh2, config.max_prims_per_leaf.clamp(1, 3), true, false);
113
114 #[cfg(debug_assertions)]
115 {
116 bvh2.validate(primitives, false, config.pre_split);
117 cwbvh.validate(primitives, false);
118 }
119
120 *core_build_time += start_time.elapsed();
121
122 cwbvh
123}