parry3d/partitioning/bvh/
bvh_refit.rs1use super::bvh_tree::{BvhNodeIndex, BvhNodeVec, BvhNodeWide};
2use super::{Bvh, BvhNode, BvhWorkspace};
3use crate::utils::VecMap;
4use alloc::vec::Vec;
5
6impl Bvh {
7 pub fn refit(&mut self, workspace: &mut BvhWorkspace) {
17 Self::refit_buffers(
18 &mut self.nodes,
19 &mut workspace.refit_tmp,
20 &mut self.leaf_node_indices,
21 &mut self.parents,
22 );
23
24 core::mem::swap(&mut self.nodes, &mut workspace.refit_tmp);
26 }
27
28 pub(super) fn refit_buffers(
29 source: &mut BvhNodeVec,
30 target: &mut BvhNodeVec,
31 leaf_data: &mut VecMap<BvhNodeIndex>,
32 parents: &mut Vec<BvhNodeIndex>,
33 ) {
34 if source.is_empty() {
35 target.clear();
36 parents.clear();
37 } else if source[0].leaf_count() <= 2 {
38 target.clear();
40 parents.clear();
41 target.push(source[0]);
42 target[0].left.data.resolve_pending_change();
43 if target[0].right.leaf_count() > 0 {
44 target[0].right.data.resolve_pending_change();
45 }
46 parents.push(BvhNodeIndex::default());
47 } else if !source.is_empty() && source[0].leaf_count() > 2 {
48 target.resize(
49 source.len(),
50 BvhNodeWide {
51 left: BvhNode::zeros(),
52 right: BvhNode::zeros(),
53 },
54 );
55
56 let mut len = 1;
57
58 let left_child_id = source[0].left.children;
60 let right_child_id = source[0].right.children;
61
62 if !source[0].left.is_leaf() {
63 Self::refit_recurse(
64 source,
65 target,
66 leaf_data,
67 parents,
68 left_child_id,
69 &mut len,
70 BvhNodeIndex::left(0),
71 );
72 } else {
73 target[0].left = source[0].left;
74 target[0].left.data.resolve_pending_change();
75
76 }
80
81 if !source[0].right.is_leaf() {
82 Self::refit_recurse(
83 source,
84 target,
85 leaf_data,
86 parents,
87 right_child_id,
88 &mut len,
89 BvhNodeIndex::right(0),
90 );
91 } else {
92 target[0].right = source[0].right;
93 target[0].right.data.resolve_pending_change();
94 }
98
99 source.truncate(len as usize);
100 target.truncate(len as usize);
101 parents.truncate(len as usize);
102 }
103 }
104
105 fn refit_recurse(
106 source: &BvhNodeVec,
107 target: &mut BvhNodeVec,
108 leaf_data: &mut VecMap<BvhNodeIndex>,
109 parents: &mut [BvhNodeIndex],
110 source_id: u32,
111 target_id_mut: &mut u32,
112 parent: BvhNodeIndex,
113 ) {
114 let target_id = *target_id_mut;
115 *target_id_mut += 1;
116
117 let node = &source[source_id as usize];
118 let left_is_leaf = node.left.is_leaf();
119 let right_is_leaf = node.right.is_leaf();
120 let left_source_id = node.left.children;
121 let right_source_id = node.right.children;
122
123 if !left_is_leaf {
124 Self::refit_recurse(
125 source,
126 target,
127 leaf_data,
128 parents,
129 left_source_id,
130 target_id_mut,
131 BvhNodeIndex::left(target_id),
132 );
133 } else {
134 let node = &source[source_id as usize];
135 target[target_id as usize].left = node.left;
136 target[target_id as usize]
137 .left
138 .data
139 .resolve_pending_change();
140 leaf_data[node.left.children as usize] = BvhNodeIndex::left(target_id);
141 }
142
143 if !right_is_leaf {
144 Self::refit_recurse(
145 source,
146 target,
147 leaf_data,
148 parents,
149 right_source_id,
150 target_id_mut,
151 BvhNodeIndex::right(target_id),
152 );
153 } else {
154 let node = &source[source_id as usize];
155 target[target_id as usize].right = node.right;
156 target[target_id as usize]
157 .right
158 .data
159 .resolve_pending_change();
160 leaf_data[node.right.children as usize] = BvhNodeIndex::right(target_id);
161 }
162
163 let node = &target[target_id as usize];
164 target[parent] = node.left.merged(&node.right, target_id);
165 parents[target_id as usize] = parent;
166 }
167
168 pub fn refit_without_opt(&mut self) {
173 if self.leaf_count() > 2 {
174 let root = &self.nodes[0];
175 let left = root.left.children;
176 let right = root.right.children;
177 let left_is_leaf = root.left.is_leaf();
178 let right_is_leaf = root.right.is_leaf();
179
180 if !left_is_leaf {
181 self.recurse_refit_without_opt(left, BvhNodeIndex::left(0));
182 }
183 if !right_is_leaf {
184 self.recurse_refit_without_opt(right, BvhNodeIndex::right(0));
185 }
186 }
187 }
188
189 fn recurse_refit_without_opt(&mut self, node_id: u32, parent: BvhNodeIndex) {
190 let node = &self.nodes[node_id as usize];
191 let left = &node.left;
192 let right = &node.right;
193 let left_is_leaf = left.is_leaf();
194 let right_is_leaf = right.is_leaf();
195 let left_children = left.children;
196 let right_children = right.children;
197
198 if !left_is_leaf {
199 self.recurse_refit_without_opt(left_children, BvhNodeIndex::left(node_id));
200 } else {
201 self.nodes[node_id as usize]
202 .left
203 .data
204 .resolve_pending_change();
205 }
206 if !right_is_leaf {
207 self.recurse_refit_without_opt(right_children, BvhNodeIndex::right(node_id));
208 } else {
209 self.nodes[node_id as usize]
210 .right
211 .data
212 .resolve_pending_change();
213 }
214
215 let node = &self.nodes[node_id as usize];
216 let left = &node.left;
217 let right = &node.right;
218 let merged = left.merged(right, node_id);
219
220 self.nodes[parent] = merged;
221 }
222}