khora_core/physics/
dynamic_tree.rs1use crate::math::Aabb;
21use crate::math::Vec3;
22
23const NULL_NODE: i32 = -1;
24
25#[derive(Debug, Clone)]
27pub struct DynamicTreeNode<T: Clone> {
28 pub aabb: Aabb,
30 pub user_data: Option<T>,
32 pub parent: i32,
34 pub children: [i32; 2],
36 pub height: i32,
38}
39
40impl<T: Clone> DynamicTreeNode<T> {
41 #[inline]
43 pub fn is_leaf(&self) -> bool {
44 self.children[0] == NULL_NODE
45 }
46}
47
48#[derive(Debug, Clone)]
50pub struct DynamicTree<T: Clone> {
51 root: i32,
52 nodes: Vec<DynamicTreeNode<T>>,
53 free_list: i32,
54 node_count: usize,
55}
56
57impl<T: Clone> Default for DynamicTree<T> {
58 fn default() -> Self {
59 Self::new()
60 }
61}
62
63impl<T: Clone> DynamicTree<T> {
64 pub fn new() -> Self {
66 Self {
67 root: NULL_NODE,
68 nodes: Vec::new(),
69 free_list: NULL_NODE,
70 node_count: 0,
71 }
72 }
73
74 pub fn insert(&mut self, aabb: Aabb, user_data: T) -> i32 {
76 let leaf = self.allocate_node();
77 self.nodes[leaf as usize].aabb = aabb;
78 self.nodes[leaf as usize].user_data = Some(user_data);
79 self.nodes[leaf as usize].height = 0;
80
81 self.insert_leaf(leaf);
82 leaf
83 }
84
85 pub fn remove(&mut self, leaf: i32) {
87 debug_assert!(leaf != NULL_NODE);
88 debug_assert!(self.nodes[leaf as usize].is_leaf());
89
90 self.remove_leaf(leaf);
91 self.deallocate_node(leaf);
92 }
93
94 pub fn update(
97 &mut self,
98 leaf: i32,
99 aabb: Aabb,
100 displacement: Vec3,
101 force_update: bool,
102 ) -> bool {
103 debug_assert!(leaf != NULL_NODE);
104 debug_assert!(self.nodes[leaf as usize].is_leaf());
105
106 if !force_update && self.nodes[leaf as usize].aabb.contains_aabb(&aabb) {
107 return false;
108 }
109
110 self.remove_leaf(leaf);
111
112 let mut fat_aabb = aabb;
114 let extension = Vec3::ONE * 0.1; fat_aabb.min = fat_aabb.min - extension;
116 fat_aabb.max = fat_aabb.max + extension;
117
118 if displacement.x < 0.0 {
120 fat_aabb.min.x += displacement.x * 2.0;
121 } else {
122 fat_aabb.max.x += displacement.x * 2.0;
123 }
124 if displacement.y < 0.0 {
125 fat_aabb.min.y += displacement.y * 2.0;
126 } else {
127 fat_aabb.max.y += displacement.y * 2.0;
128 }
129 if displacement.z < 0.0 {
130 fat_aabb.min.z += displacement.z * 2.0;
131 } else {
132 fat_aabb.max.z += displacement.z * 2.0;
133 }
134
135 self.nodes[leaf as usize].aabb = fat_aabb;
136 self.insert_leaf(leaf);
137 true
138 }
139
140 pub fn get_user_data(&self, leaf: i32) -> &T {
142 self.nodes[leaf as usize].user_data.as_ref().unwrap()
143 }
144
145 pub fn query_pairs<F>(&self, mut callback: F)
147 where
148 F: FnMut(&T, &T),
149 {
150 if self.root == NULL_NODE {
151 return;
152 }
153
154 let mut stack: Vec<i32> = Vec::with_capacity(256);
156 stack.push(self.root);
157
158 while let Some(node_id) = stack.pop() {
159 let node = &self.nodes[node_id as usize];
160 if node.height < 1 {
161 continue;
162 }
163
164 let left = node.children[0];
165 let right = node.children[1];
166
167 self.query_overlap(left, right, &mut callback);
168
169 stack.push(left);
170 stack.push(right);
171 }
172 }
173
174 fn query_overlap<F>(&self, i_a: i32, i_b: i32, callback: &mut F)
175 where
176 F: FnMut(&T, &T),
177 {
178 let node_a = &self.nodes[i_a as usize];
179 let node_b = &self.nodes[i_b as usize];
180
181 if !node_a.aabb.intersects_aabb(&node_b.aabb) {
182 return;
183 }
184
185 if node_a.is_leaf() && node_b.is_leaf() {
186 if i_a != i_b {
187 callback(
188 node_a.user_data.as_ref().unwrap(),
189 node_b.user_data.as_ref().unwrap(),
190 );
191 }
192 } else if node_a.is_leaf() {
193 self.query_overlap(i_a, node_b.children[0], callback);
194 self.query_overlap(i_a, node_b.children[1], callback);
195 } else if node_b.is_leaf() {
196 self.query_overlap(node_a.children[0], i_b, callback);
197 self.query_overlap(node_a.children[1], i_b, callback);
198 } else {
199 self.query_overlap(node_a.children[0], node_b.children[0], callback);
200 self.query_overlap(node_a.children[0], node_b.children[1], callback);
201 self.query_overlap(node_a.children[1], node_b.children[0], callback);
202 self.query_overlap(node_a.children[1], node_b.children[1], callback);
203 }
204 }
205
206 pub fn query<F>(&self, aabb: &Aabb, mut callback: F)
208 where
209 F: FnMut(&T) -> bool,
210 {
211 if self.root == NULL_NODE {
212 return;
213 }
214
215 let mut stack = Vec::with_capacity(64);
216 stack.push(self.root);
217
218 while let Some(node_id) = stack.pop() {
219 let node = &self.nodes[node_id as usize];
220 if node.aabb.intersects_aabb(aabb) {
221 if node.is_leaf() {
222 let proceed = callback(node.user_data.as_ref().unwrap());
223 if !proceed {
224 return;
225 }
226 } else {
227 stack.push(node.children[0]);
228 stack.push(node.children[1]);
229 }
230 }
231 }
232 }
233
234 fn insert_leaf(&mut self, leaf: i32) {
237 if self.root == NULL_NODE {
238 self.root = leaf;
239 self.nodes[self.root as usize].parent = NULL_NODE;
240 return;
241 }
242
243 let leaf_aabb = self.nodes[leaf as usize].aabb;
245 let mut index = self.root;
246 while !self.nodes[index as usize].is_leaf() {
247 let node = &self.nodes[index as usize];
248 let child1 = node.children[0];
249 let child2 = node.children[1];
250
251 let area = node.aabb.surface_area();
252 let combined_aabb = node.aabb.merge(&leaf_aabb);
253 let combined_area = combined_aabb.surface_area();
254
255 let cost = 2.0 * combined_area;
257
258 let inheritance_cost = 2.0 * (combined_area - area);
260
261 let cost1 = {
263 let child1_node = &self.nodes[child1 as usize];
264 let new_area = child1_node.aabb.merge(&leaf_aabb).surface_area();
265 if child1_node.is_leaf() {
266 new_area + inheritance_cost
267 } else {
268 let old_area = child1_node.aabb.surface_area();
269 (new_area - old_area) + inheritance_cost
270 }
271 };
272
273 let cost2 = {
275 let child2_node = &self.nodes[child2 as usize];
276 let new_area = child2_node.aabb.merge(&leaf_aabb).surface_area();
277 if child2_node.is_leaf() {
278 new_area + inheritance_cost
279 } else {
280 let old_area = child2_node.aabb.surface_area();
281 (new_area - old_area) + inheritance_cost
282 }
283 };
284
285 if cost < cost1 && cost < cost2 {
287 break;
288 }
289
290 index = if cost1 < cost2 { child1 } else { child2 };
291 }
292
293 let sibling = index;
294
295 let old_parent = self.nodes[sibling as usize].parent;
297 let new_parent = self.allocate_node();
298 self.nodes[new_parent as usize].parent = old_parent;
299 self.nodes[new_parent as usize].user_data = None;
300 self.nodes[new_parent as usize].aabb = leaf_aabb.merge(&self.nodes[sibling as usize].aabb);
301 self.nodes[new_parent as usize].height = self.nodes[sibling as usize].height + 1;
302
303 if old_parent != NULL_NODE {
304 if self.nodes[old_parent as usize].children[0] == sibling {
306 self.nodes[old_parent as usize].children[0] = new_parent;
307 } else {
308 self.nodes[old_parent as usize].children[1] = new_parent;
309 }
310 self.nodes[new_parent as usize].children[0] = sibling;
311 self.nodes[new_parent as usize].children[1] = leaf;
312 self.nodes[sibling as usize].parent = new_parent;
313 self.nodes[leaf as usize].parent = new_parent;
314 } else {
315 self.nodes[new_parent as usize].children[0] = sibling;
317 self.nodes[new_parent as usize].children[1] = leaf;
318 self.nodes[sibling as usize].parent = new_parent;
319 self.nodes[leaf as usize].parent = new_parent;
320 self.root = new_parent;
321 }
322
323 index = self.nodes[leaf as usize].parent;
325 while index != NULL_NODE {
326 index = self.balance(index);
327
328 let child1 = self.nodes[index as usize].children[0];
329 let child2 = self.nodes[index as usize].children[1];
330
331 debug_assert!(child1 != NULL_NODE);
332 debug_assert!(child2 != NULL_NODE);
333
334 self.nodes[index as usize].height = 1 + self.nodes[child1 as usize]
335 .height
336 .max(self.nodes[child2 as usize].height);
337 self.nodes[index as usize].aabb = self.nodes[child1 as usize]
338 .aabb
339 .merge(&self.nodes[child2 as usize].aabb);
340
341 index = self.nodes[index as usize].parent;
342 }
343 }
344
345 fn remove_leaf(&mut self, leaf: i32) {
346 if leaf == self.root {
347 self.root = NULL_NODE;
348 return;
349 }
350
351 let parent = self.nodes[leaf as usize].parent;
352 let grand_parent = self.nodes[parent as usize].parent;
353 let sibling = if self.nodes[parent as usize].children[0] == leaf {
354 self.nodes[parent as usize].children[1]
355 } else {
356 self.nodes[parent as usize].children[0]
357 };
358
359 if grand_parent != NULL_NODE {
360 if self.nodes[grand_parent as usize].children[0] == parent {
362 self.nodes[grand_parent as usize].children[0] = sibling;
363 } else {
364 self.nodes[grand_parent as usize].children[1] = sibling;
365 }
366 self.nodes[sibling as usize].parent = grand_parent;
367 self.deallocate_node(parent);
368
369 let mut index = grand_parent;
371 while index != NULL_NODE {
372 index = self.balance(index);
373
374 let child1 = self.nodes[index as usize].children[0];
375 let child2 = self.nodes[index as usize].children[1];
376
377 self.nodes[index as usize].aabb = self.nodes[child1 as usize]
378 .aabb
379 .merge(&self.nodes[child2 as usize].aabb);
380 self.nodes[index as usize].height = 1 + self.nodes[child1 as usize]
381 .height
382 .max(self.nodes[child2 as usize].height);
383
384 index = self.nodes[index as usize].parent;
385 }
386 } else {
387 self.root = sibling;
388 self.nodes[sibling as usize].parent = NULL_NODE;
389 self.deallocate_node(parent);
390 }
391 }
392
393 fn allocate_node(&mut self) -> i32 {
396 if self.free_list != NULL_NODE {
397 let index = self.free_list;
398 self.free_list = self.nodes[index as usize].parent;
399 self.nodes[index as usize].parent = NULL_NODE;
400 self.nodes[index as usize].children = [NULL_NODE, NULL_NODE];
401 self.nodes[index as usize].height = 0;
402 self.node_count += 1;
403 index
404 } else {
405 let index = self.nodes.len() as i32;
406 self.nodes.push(DynamicTreeNode {
407 aabb: Aabb::INVALID,
408 user_data: None,
409 parent: NULL_NODE,
410 children: [NULL_NODE, NULL_NODE],
411 height: 0,
412 });
413 self.node_count += 1;
414 index
415 }
416 }
417
418 fn deallocate_node(&mut self, index: i32) {
419 debug_assert!(index != NULL_NODE);
420 self.nodes[index as usize].parent = self.free_list;
421 self.nodes[index as usize].user_data = None;
422 self.free_list = index;
423 self.node_count -= 1;
424 }
425
426 fn balance(&mut self, i_a: i32) -> i32 {
429 debug_assert!(i_a != NULL_NODE);
430
431 let node_a = &self.nodes[i_a as usize];
432 if node_a.is_leaf() || node_a.height < 2 {
433 return i_a;
434 }
435
436 let i_b = node_a.children[0];
437 let i_c = node_a.children[1];
438
439 let balance = self.nodes[i_c as usize].height - self.nodes[i_b as usize].height;
440
441 if balance > 1 {
443 let i_f = self.nodes[i_c as usize].children[0];
444 let i_g = self.nodes[i_c as usize].children[1];
445
446 self.nodes[i_c as usize].children[0] = i_a;
448 self.nodes[i_c as usize].parent = self.nodes[i_a as usize].parent;
449 self.nodes[i_a as usize].parent = i_c;
450
451 if self.nodes[i_c as usize].parent != NULL_NODE {
453 let p = self.nodes[i_c as usize].parent;
454 if self.nodes[p as usize].children[0] == i_a {
455 self.nodes[p as usize].children[0] = i_c;
456 } else {
457 self.nodes[p as usize].children[1] = i_c;
458 }
459 } else {
460 self.root = i_c;
461 }
462
463 if self.nodes[i_f as usize].height > self.nodes[i_g as usize].height {
465 self.nodes[i_c as usize].children[1] = i_f;
466 self.nodes[i_a as usize].children[1] = i_g;
467 self.nodes[i_g as usize].parent = i_a;
468
469 self.update_node_meta(i_a);
470 self.update_node_meta(i_c);
471 } else {
472 self.nodes[i_c as usize].children[1] = i_g;
473 self.nodes[i_a as usize].children[1] = i_f;
474 self.nodes[i_f as usize].parent = i_a;
475
476 self.update_node_meta(i_a);
477 self.update_node_meta(i_c);
478 }
479
480 return i_c;
481 }
482
483 if balance < -1 {
485 let i_d = self.nodes[i_b as usize].children[0];
486 let i_e = self.nodes[i_b as usize].children[1];
487
488 self.nodes[i_b as usize].children[0] = i_a;
490 self.nodes[i_b as usize].parent = self.nodes[i_a as usize].parent;
491 self.nodes[i_a as usize].parent = i_b;
492
493 if self.nodes[i_b as usize].parent != NULL_NODE {
495 let p = self.nodes[i_b as usize].parent;
496 if self.nodes[p as usize].children[0] == i_a {
497 self.nodes[p as usize].children[0] = i_b;
498 } else {
499 self.nodes[p as usize].children[1] = i_b;
500 }
501 } else {
502 self.root = i_b;
503 }
504
505 if self.nodes[i_d as usize].height > self.nodes[i_e as usize].height {
507 self.nodes[i_b as usize].children[1] = i_d;
508 self.nodes[i_a as usize].children[0] = i_e;
509 self.nodes[i_e as usize].parent = i_a;
510
511 self.update_node_meta(i_a);
512 self.update_node_meta(i_b);
513 } else {
514 self.nodes[i_b as usize].children[1] = i_e;
515 self.nodes[i_a as usize].children[0] = i_d;
516 self.nodes[i_d as usize].parent = i_a;
517
518 self.update_node_meta(i_a);
519 self.update_node_meta(i_b);
520 }
521
522 return i_b;
523 }
524
525 i_a
526 }
527
528 fn update_node_meta(&mut self, index: i32) {
529 let child1 = self.nodes[index as usize].children[0];
530 let child2 = self.nodes[index as usize].children[1];
531 self.nodes[index as usize].aabb = self.nodes[child1 as usize]
532 .aabb
533 .merge(&self.nodes[child2 as usize].aabb);
534 self.nodes[index as usize].height = 1 + self.nodes[child1 as usize]
535 .height
536 .max(self.nodes[child2 as usize].height);
537 }
538}
539
540pub struct DynamicTreeIterator<'a, T: Clone> {
542 tree: &'a DynamicTree<T>,
543 stack: Vec<i32>,
544}
545
546impl<'a, T: Clone> Iterator for DynamicTreeIterator<'a, T> {
547 type Item = &'a T;
548
549 fn next(&mut self) -> Option<Self::Item> {
550 while let Some(node_id) = self.stack.pop() {
551 let node = &self.tree.nodes[node_id as usize];
552 if node.is_leaf() {
553 return Some(node.user_data.as_ref().unwrap());
554 } else {
555 self.stack.push(node.children[0]);
556 self.stack.push(node.children[1]);
557 }
558 }
559 None
560 }
561}