1use std::fmt;
8use *;
9
10pub struct Octree<T: Collider> {
21 colliders: Vec<T>,
22 collider_garbage: Vec<Id>,
23 nodes: Vec<Node>,
24 garbage: Vec<Id>,
25 bcube: BCube,
26 root: Id,
27 n_colliders: u32,
28}
29
30const LINK: usize = 15; const LEAF: u32 = 0xFF_FF_FF_FF; #[derive(Debug, PartialEq, Eq, Copy, Clone)]
35pub struct Id(u32);
36
37impl Id {
38 fn none() -> Self {
40 Id(0)
41 }
42
43 fn is_none(&self) -> bool {
45 self.0 == 0
46 }
47
48 fn is_some(&self) -> bool {
50 !self.is_none()
51 }
52}
53
54impl Into<Id> for usize {
55 fn into(self) -> Id {
56 Id(self as u32 + 1)
57 }
58}
59
60impl Into<usize> for Id {
61 fn into(self) -> usize {
62 (self.0 - 1) as usize
63 }
64}
65
66struct Node {
77 child: [Id; 16],
79}
80
81impl fmt::Display for Node {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 if self.is_leaf() {
84 let l = self.link();
85 if l.is_some() {
86 write!(f, " LINK ")?;
87 }
88 for i in 0..=14 {
89 let id = self.child[i];
90 if id.is_some() {
91 let id: usize = id.into();
92 write!(f, "{} ", id)?;
93 }
94 }
95 } else {
96 write!(f, "Branch: [")?;
97 for i in 8..=14 {
98 let id = self.child[i];
99 if id.is_some() {
100 let id: usize = id.into();
101 write!(f, "{} ", id)?;
102 }
103 }
104 write!(f, "] -D [")?;
105 for i in 0..8 {
106 let id = self.child[i];
107 if id.is_some() {
108 let id: usize = id.into();
109 write!(f, "{}:{}", i, id)?;
110 }
111 }
112 write!(f, "];")?;
113 }
114
115 Ok(())
116 }
117}
118
119impl fmt::Debug for Node {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 if self.is_leaf() {
122 try!(write!(f, "leaf"));
123let l = self.link();
125 if l.is_some() {
126 try!(write!(f, " link: {:?}", l));
127 }
128 Ok(())
129 } else {
130 write!(f, "branch: {:?}", self.child)
131 }
132 }
133}
134
135impl Node {
136 fn new_leaf() -> Node {
138 Node {
139 child: [
141 Id(LEAF), Id::none(), Id::none(), Id::none(),
142 Id::none(), Id::none(), Id::none(), Id::none(),
143 Id::none(), Id::none(), Id::none(), Id::none(),
144 Id::none(), Id::none(), Id::none(), Id::none()
145 ],
146 }
147 }
148
149 fn new_branch() -> Node {
151 Node {
152 child: [Id::none(); 16],
153 }
154 }
155
156 fn is_leaf(&self) -> bool {
158 self.child[0] == Id(LEAF)
159 }
160
161 fn is_branch(&self) -> bool {
163 !self.is_leaf()
164 }
165
166 fn link(&self) -> Option<usize> {
168 if self.child[LINK].is_none() {
170 None
172 } else {
173 Some(self.child[LINK].into())
175 }
176 }
177
178 fn is_empty(&self) -> bool {
180 assert!(self.is_branch());
181 for i in &self.child[..=14] { if i.is_some() {
184 return false }
186 }
187
188 true }
190
191 fn branch_is_one(&self) -> Option<usize> {
193 assert!(self.is_branch());
194 let mut found = None;
196
197 for i in 0..8 { if self.child[i].is_some() {
199 if found.is_some() { return None;
201 } else {
202 found = Some(i);
203 }
204 }
205 }
206 for i in &self.child[8..=14] { if i.is_some() {
208 return None }
210 }
211
212 found
213 }
214
215 fn branch_open_slot(&self) -> Option<usize> {
217 assert!(self.is_branch());
218 for i in 8..=14 {
220 if self.child[i].is_none() { return Some(i) }
221 }
222 None
223 }
224
225 fn branch_add_collider(&mut self, id: Id) -> Option<()> {
227 assert!(self.is_branch());
228 let s = self.branch_open_slot()?;
229 self.child[s] = id;
230 Some(())
232 }
233
234 fn branch_remove_collider(&mut self, id: Id) -> Option<()> {
236 assert!(self.is_branch());
237 for i in 8..=14 {
239 if self.child[i] == id {
241 self.child[i] = Id::none();
242 return Some(());
243 }
244 }
245 return None;
247 }
248
249 fn leaf_remove_collider(&mut self, id: Id) -> Option<()> {
251 assert!(self.is_leaf());
252 for i in 1..=14 {
254 if self.child[i] == id {
256 self.child[i] = Id::none();
257 return Some(());
258 }
259 }
260 return None;
262 }
263
264 fn remove_collider(&mut self, id: Id) -> Option<()> {
266 if self.is_branch() {
267 self.branch_remove_collider(id)
268 } else {
269 self.leaf_remove_collider(id)
270 }
271 }
272
273 fn which_child2(c: Vector, p: Vector) -> [bool; 3] {
275 [p.x < c.x, p.y < c.y, p.z < c.z]
276 }
277
278 fn which_child_bbox(c: Vector, mut p: BBox) -> Option<usize> {
281 if p.min.x >= c.x - ::std::f32::EPSILON && p.min.x <= c.x + ::std::f32::EPSILON {
282p.min.x = p.max.x;
284 }
285 if p.min.y >= c.y - ::std::f32::EPSILON && p.min.y <= c.y + ::std::f32::EPSILON {
286p.min.y = p.max.y;
288 }
289 if p.min.z >= c.z - ::std::f32::EPSILON && p.min.z <= c.z + ::std::f32::EPSILON {
290p.min.z = p.max.z;
292 }
293 if p.max.x >= c.x - ::std::f32::EPSILON && p.max.x <= c.x + ::std::f32::EPSILON {
294p.max.x = p.min.x;
296 }
297 if p.max.y >= c.y - ::std::f32::EPSILON && p.max.y <= c.y + ::std::f32::EPSILON {
298p.max.y = p.min.y;
300 }
301 if p.max.z >= c.z - ::std::f32::EPSILON && p.max.z <= c.z + ::std::f32::EPSILON {
302p.max.z = p.min.z;
304 }
305
306 let min = Self::which_child2(c, p.min);
307 let max = Self::which_child2(c, p.max);
308
309 if max != min {
310 return None;
311 }
312
313 let a = Some(match (min[0], min[1], min[2]) {
314 (true, true, true) => 0,
315 (true, true, false) => 1,
316 (true, false, true) => 2,
317 (true, false, false) => 3,
318 (false, true, true) => 4,
319 (false, true, false) => 5,
320 (false, false, true) => 6,
321 (false, false, false) => 7,
322 });
323
324a
326 }
327
328 fn child_center(ch: usize, c: Vector, h: f32) -> Vector {
330 match ch {
331 0 => Vector::new(c.x - h, c.y - h, c.z - h),
332 1 => Vector::new(c.x - h, c.y - h, c.z + h),
333 2 => Vector::new(c.x - h, c.y + h, c.z - h),
334 3 => Vector::new(c.x - h, c.y + h, c.z + h),
335 4 => Vector::new(c.x + h, c.y - h, c.z - h),
336 5 => Vector::new(c.x + h, c.y - h, c.z + h),
337 6 => Vector::new(c.x + h, c.y + h, c.z - h),
338 7 => Vector::new(c.x + h, c.y + h, c.z + h),
339 a => panic!("ch must be 0-7, not {}", a),
340 }
341 }
342
343 fn child_bcube(ch: usize, bcube: BCube) -> BCube {
345 assert!(bcube.half_len > 0.1);
346 let half_len = bcube.half_len / 2.0;
347 let center = Node::child_center(ch, bcube.center, half_len);
348 BCube { center: center, half_len: half_len }
349 }
350
351}
359
360impl<T> Octree<T> where T: Collider {
361 pub fn new() -> Octree<T> {
363 let o = Octree {
364 colliders: vec![],
365 collider_garbage: vec![],
366 nodes: vec![],
367 garbage: vec![],
368 bcube: BCube::empty(),
369 root: Id::none(),
370 n_colliders: 0,
371 };
372
373 o
374 }
375
376 pub fn clear(&mut self) {
378 *self = Self::new();
379 }
380
381 pub fn add(&mut self, point: T) -> Id {
383let id = if let Some(id) = self.collider_garbage.pop() {
386 unsafe {
387 ::std::ptr::copy_nonoverlapping(&point,
388 &mut self.colliders[{ let id: usize = id.into(); id }], 1);
389 }
390 ::std::mem::forget(point); id
392 } else {
393 self.colliders.push(point);
394 Id(self.colliders.len() as u32)
395 };
396
397 match self.n_colliders {
399 0 => self.add_0(id),
400 _ => self.add_n(id),
401 }
402
403 self.n_colliders += 1;
405
406id
410 }
411
412 fn add_0(&mut self, id: Id) {
414 assert!(self.n_colliders == 0);
416
417 self.nodes.clear();
419 self.garbage.clear();
420
421 self.bcube = self[id].bbox().into();
423
424let i = self.new_branch();
428 self.nodes[{ let i: usize = i.into(); i }].branch_add_collider(id).unwrap();
429
430 self.root = i;
432 }
433
434 fn add_n(&mut self, id: Id) {
436 assert!(self.n_colliders > 0);
438 let bbox = self[id].bbox();
440
441 while !bbox.collide_bcube(self.bcube) {
443 self.grow_root(bbox);
444}
446
447 let bcube = self.bcube;
449 let root = self.root;
450 self.add_inside(id, root, bcube);
451
452}
454
455 fn grow_root(&mut self, bbox: BBox) {
457 assert!(!bbox.collide_bcube(self.bcube));
459 assert!(self.nodes[{ let a: usize = self.root.into(); a }].is_branch());
460
461 let old_bc = self.bcube;
463
464 self.bcube.extend(bbox);
467
468 let ch = Node::which_child_bbox(self.bcube.center, old_bc.to_bbox()).unwrap();
470 let id = self.new_branch();
471 self.nodes[{ let a: usize = id.into(); a }].child[ch] = self.root;
472 self.root = id;
473
474}
476
477 fn add_inside(&mut self, id: Id, node_id: Id, bcube: BCube) {
479 let bbox = self[id].bbox();
481 let node_id: usize = node_id.into();
483
484 assert!(bbox.collide_bcube(bcube));
486 assert!(self.nodes[node_id].is_branch());
488
489 if self.nodes[node_id].branch_add_collider(id).is_none() {
491 for i in 8..=14 {
493 let collider = self.nodes[node_id].child[i];
494 if self.add_down(collider, node_id, bcube) {
495 self.nodes[node_id].child[i]
499 = Id::none();
500 }
501 }
502
503 if self.add_down(id, node_id, bcube) {
505 return;
506 }
507
508 if self.nodes[node_id].branch_add_collider(id)
510 .is_none() {
512 let link_id = self.new_leaf();
513 self.nodes[node_id].child[LINK]
514 = link_id;
515 }
516 }
517 }
518
519 fn add_down(&mut self, id: Id, node_id: usize, bcube: BCube) -> bool {
521 let bbox = self[id].bbox();
523
524 if let Some(ch) = Node::which_child_bbox(bcube.center, bbox) {
526 let j = self.nodes[node_id].child[ch];
527 let bc = Node::child_bcube(ch, bcube);
528
529 if j.is_some() {
530 self.add_inside(id, j, bc);
532 } else {
533 let k = self.new_branch();
535 self.nodes[node_id].child[ch] = k;
537 self.nodes[{ let k: usize = k.into(); k }]
539 .branch_add_collider(id)
540 .unwrap(); }
542 true
543 } else {
544 false
545 }
546 }
547
548 fn new_node(&mut self, n: Node) -> Id {
550 if let Some(i) = self.garbage.pop() {
551 let k: usize = i.into();
552 self.nodes[k] = n;
553 k.into()
554 } else {
555 self.nodes.push(n);
556 Id(self.nodes.len() as u32)
557 }
558 }
559
560 fn new_leaf(&mut self) -> Id {
562 self.new_node(Node::new_leaf())
563 }
564
565 fn new_branch(&mut self) -> Id {
567 self.new_node(Node::new_branch())
568 }
569
570 pub fn remove(&mut self, id: Id) -> T {
572assert!(self.n_colliders > 0);
577 let bcube = self.bcube;
579 let root = self.root;
580 let clear = self.remove_inside(id, root, bcube).is_some();
582 self.collider_garbage.push(id);
584 loop {
586 let root: usize = self.root.into();
587 if let Some(ch) = self.nodes[root].branch_is_one() {
588 self.garbage.push(self.root);
590 self.root = self.nodes[root].child[ch];
592 self.bcube = Node::child_bcube(ch, self.bcube);
594 } else {
595 break;
596 }
597 }
598 self.n_colliders -= 1;
600
601 let mut ret = unsafe { ::std::mem::uninitialized() };
603
604 unsafe {
605 ::std::ptr::copy_nonoverlapping(
606 &self.colliders[{ let id: usize = id.into(); id }], &mut ret, 1);
607 }
608
609 if clear {
610 assert_eq!(self.n_colliders, 0);
611 self.clear();
612 }
613
614ret
619 }
620
621 fn remove_inside(&mut self, id: Id, node_id: Id, bcube: BCube)
623 -> Option<Id>
624 {
625 let bbox = self[id].bbox();
627 let node_id: usize = node_id.into();
629
630 assert!(bbox.collide_bcube(bcube));
632 assert!(self.nodes[node_id].is_branch());
634
635 if let Some(ch) = Node::which_child_bbox(bcube.center, bbox) {
638let j = self.nodes[node_id].child[ch];
640
641 if j.is_some() {
642let bcube = Node::child_bcube(ch, bcube);
647
648 if let Some(rm)
649 = self.remove_inside(id, j, bcube)
650 { assert_eq!(j, rm);
654 self.garbage.push(rm);
656 self.nodes[node_id].child[ch] =
658 Id::none();
659 }
660
661 if self.nodes[node_id].is_empty() {
663 Some(node_id.into())
664 } else {
665 None }
667 } else {
668self.remove_from_branch(id, node_id)
671 }
672 } else {
673self.remove_from_branch(id, node_id)
676 }
677 }
678
679 fn remove_from_branch(&mut self, id: Id, node_id: usize) -> Option<Id> {
681if self.nodes[node_id].remove_collider(id)
685 .is_some() {
687 if self.nodes[node_id].is_empty() {
689 return Some(node_id.into());
690 } else {
691 return None;
692 }
693 }
694
695 let node_id = self.nodes[node_id].link()
697 .unwrap(); let rm = self.remove_from_branch(id, node_id);
699
700 if let Some(rm) = rm {
702 assert_eq!(rm, self.nodes[node_id].child[LINK]);
704 self.garbage.push(rm);
706 self.nodes[node_id].child[LINK] = Id::none();
708 }
709
710 None }
712}
713
714impl<T> ::std::ops::Index<Id> for Octree<T> where T: Collider {
715 type Output = T;
716
717 fn index<'a>(&'a self, index: Id) -> &'a T {
718 let index: usize = index.into();
719 &self.colliders[index]
720 }
721}
722
723impl<T> ::std::ops::IndexMut<Id> for Octree<T> where T: Collider {
724 fn index_mut<'a>(&'a mut self, index: Id) -> &'a mut T {
725 let index: usize = index.into();
726 &mut self.colliders[index]
727 }
728}
729
730impl<T> fmt::Display for Octree<T> where T: Collider {
731 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
732 if self.root.is_none() {
733 write!(f, "No Root\n")?;
734 } else {
735 let root: usize = self.root.into();
736 write!(f, "Root {}:{:?}\n", root, self.bcube)?;
737 }
738
739 for i in 0..self.nodes.len() {
740 let id: Id = i.into();
741 if !self.garbage.contains(&id) {
742 writeln!(f, "{}: {}", i, self.nodes[i])?;
743 write!(f, "{}: ", i)?;
744 for j in 8..=14 { let index = self.nodes[i].child[j];
746 if index.is_some() {
747 write!(f, "{:?},", self[index].bbox())?;
748 }
749 }
750 writeln!(f, "")?;
751 }
752 }
753
754 write!(f, "")
755 }
756}
757
758impl<T> fmt::Debug for Octree<T> where T: Collider {
759 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
760 if self.root.is_none() {
761 write!(f, "No Root\n")?;
762 } else {
763 let root: usize = self.root.into();
764 write!(f, "root {}\n", root)?;
765 }
766
767 for i in 0..self.nodes.len() {
768 let id: Id = i.into();
769 if !self.garbage.contains(&id) {
770 write!(f, "{}: {:?}\n", i, self.nodes[i])?;
771 }
772 }
773
774 write!(f, "")
775 }
776}