FCL  0.6.0
Flexible Collision Library
hierarchy_tree-inl.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2016, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
38 #ifndef FCL_HIERARCHY_TREE_INL_H
39 #define FCL_HIERARCHY_TREE_INL_H
40 
41 #include "fcl/broadphase/detail/hierarchy_tree.h"
42 
43 namespace fcl
44 {
45 
46 namespace detail
47 {
48 
49 //==============================================================================
50 template<typename BV>
51 HierarchyTree<BV>::HierarchyTree(int bu_threshold_, int topdown_level_)
52 {
53  root_node = nullptr;
54  n_leaves = 0;
55  free_node = nullptr;
56  max_lookahead_level = -1;
57  opath = 0;
58  bu_threshold = bu_threshold_;
59  topdown_level = topdown_level_;
60 }
61 
62 //==============================================================================
63 template<typename BV>
65 {
66  clear();
67 }
68 
69 //==============================================================================
70 template<typename BV>
71 void HierarchyTree<BV>::init(std::vector<NodeType*>& leaves, int level)
72 {
73  switch(level)
74  {
75  case 0:
76  init_0(leaves);
77  break;
78  case 1:
79  init_1(leaves);
80  break;
81  case 2:
82  init_2(leaves);
83  break;
84  case 3:
85  init_3(leaves);
86  break;
87  default:
88  init_0(leaves);
89  }
90 }
91 
92 //==============================================================================
93 template<typename BV>
94 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::insert(const BV& bv, void* data)
95 {
96  NodeType* leaf = createNode(nullptr, bv, data);
97  insertLeaf(root_node, leaf);
98  ++n_leaves;
99  return leaf;
100 }
101 
102 //==============================================================================
103 template<typename BV>
105 {
106  removeLeaf(leaf);
107  deleteNode(leaf);
108  --n_leaves;
109 }
110 
111 //==============================================================================
112 template<typename BV>
114 {
115  if(root_node)
116  recurseDeleteNode(root_node);
117  n_leaves = 0;
118  delete free_node;
119  free_node = nullptr;
120  max_lookahead_level = -1;
121  opath = 0;
122 }
123 
124 //==============================================================================
125 template<typename BV>
127 {
128  return (nullptr == root_node);
129 }
130 
131 //==============================================================================
132 template<typename BV>
133 void HierarchyTree<BV>::update(NodeType* leaf, int lookahead_level)
134 {
135  typename HierarchyTree<BV>::NodeType* root = removeLeaf(leaf);
136  if(root)
137  {
138  if(lookahead_level > 0)
139  {
140  for(int i = 0; (i < lookahead_level) && root->parent; ++i)
141  root = root->parent;
142  }
143  else
144  root = root_node;
145  }
146  insertLeaf(root, leaf);
147 }
148 
149 //==============================================================================
150 template<typename BV>
151 bool HierarchyTree<BV>::update(NodeType* leaf, const BV& bv)
152 {
153  if(leaf->bv.contain(bv)) return false;
154  update_(leaf, bv);
155  return true;
156 }
157 
158 //==============================================================================
159 template <typename S, typename BV>
161 {
162  static bool run(
163  const HierarchyTree<BV>& tree,
164  typename HierarchyTree<BV>::NodeType* leaf,
165  const BV& bv,
166  const Vector3<S>& /*vel*/,
167  S /*margin*/)
168  {
169  if(leaf->bv.contain(bv)) return false;
170  tree.update_(leaf, bv);
171  return true;
172  }
173 
174  static bool run(
175  const HierarchyTree<BV>& tree,
176  typename HierarchyTree<BV>::NodeType* leaf,
177  const BV& bv,
178  const Vector3<S>& /*vel*/)
179  {
180  if(leaf->bv.contain(bv)) return false;
181  tree.update_(leaf, bv);
182  return true;
183  }
184 };
185 
186 //==============================================================================
187 template<typename BV>
188 bool HierarchyTree<BV>::update(NodeType* leaf, const BV& bv, const Vector3<S>& vel, S margin)
189 {
190  return UpdateImpl<typename BV::S, BV>::run(*this, leaf, bv, vel, margin);
191 }
192 
193 //==============================================================================
194 template<typename BV>
195 bool HierarchyTree<BV>::update(NodeType* leaf, const BV& bv, const Vector3<S>& vel)
196 {
197  return UpdateImpl<typename BV::S, BV>::run(*this, leaf, bv, vel);
198 }
199 
200 //==============================================================================
201 template<typename BV>
203 {
204  if(!root_node)
205  return 0;
206  return getMaxHeight(root_node);
207 }
208 
209 //==============================================================================
210 template<typename BV>
212 {
213  if(!root_node) return 0;
214 
215  size_t max_depth;
216  getMaxDepth(root_node, 0, max_depth);
217  return max_depth;
218 }
219 
220 //==============================================================================
221 template<typename BV>
223 {
224  if(root_node)
225  {
226  std::vector<NodeType*> leaves;
227  leaves.reserve(n_leaves);
228  fetchLeaves(root_node, leaves);
229  bottomup(leaves.begin(), leaves.end());
230  root_node = leaves[0];
231  }
232 }
233 
234 //==============================================================================
235 template<typename BV>
237 {
238  if(root_node)
239  {
240  std::vector<NodeType*> leaves;
241  leaves.reserve(n_leaves);
242  fetchLeaves(root_node, leaves);
243  root_node = topdown(leaves.begin(), leaves.end());
244  }
245 }
246 
247 //==============================================================================
248 template<typename BV>
250 {
251  if(iterations < 0) iterations = n_leaves;
252  if(root_node && (iterations > 0))
253  {
254  for(int i = 0; i < iterations; ++i)
255  {
256  NodeType* node = root_node;
257  unsigned int bit = 0;
258  while(!node->isLeaf())
259  {
260  node = sort(node, root_node)->children[(opath>>bit)&1];
261  bit = (bit+1)&(sizeof(unsigned int) * 8-1);
262  }
263  update(node);
264  ++opath;
265  }
266  }
267 }
268 
269 //==============================================================================
270 template<typename BV>
272 {
273  if(root_node)
274  recurseRefit(root_node);
275 }
276 
277 //==============================================================================
278 template<typename BV>
279 void HierarchyTree<BV>::extractLeaves(const NodeType* root, std::vector<NodeType*>& leaves) const
280 {
281  if(!root->isLeaf())
282  {
283  extractLeaves(root->children[0], leaves);
284  extractLeaves(root->children[1], leaves);
285  }
286  else
287  leaves.push_back(root);
288 }
289 
290 //==============================================================================
291 template<typename BV>
293 {
294  return n_leaves;
295 }
296 
297 //==============================================================================
298 template<typename BV>
300 {
301  return root_node;
302 }
303 
304 //==============================================================================
305 template<typename BV>
307 {
308  return root_node;
309 }
310 
311 //==============================================================================
312 template<typename BV>
313 void HierarchyTree<BV>::print(NodeType* root, int depth)
314 {
315  for(int i = 0; i < depth; ++i)
316  std::cout << " ";
317  std::cout << " (" << root->bv.min_[0] << ", " << root->bv.min_[1] << ", " << root->bv.min_[2] << "; " << root->bv.max_[0] << ", " << root->bv.max_[1] << ", " << root->bv.max_[2] << ")" << std::endl;
318  if(root->isLeaf())
319  {
320  }
321  else
322  {
323  print(root->children[0], depth+1);
324  print(root->children[1], depth+1);
325  }
326 }
327 
328 //==============================================================================
329 template<typename BV>
330 void HierarchyTree<BV>::bottomup(const NodeVecIterator lbeg, const NodeVecIterator lend)
331 {
332  NodeVecIterator lcur_end = lend;
333  while(lbeg < lcur_end - 1)
334  {
335  NodeVecIterator min_it1, min_it2;
336  S min_size = std::numeric_limits<S>::max();
337  for(NodeVecIterator it1 = lbeg; it1 < lcur_end; ++it1)
338  {
339  for(NodeVecIterator it2 = it1 + 1; it2 < lcur_end; ++it2)
340  {
341  S cur_size = ((*it1)->bv + (*it2)->bv).size();
342  if(cur_size < min_size)
343  {
344  min_size = cur_size;
345  min_it1 = it1;
346  min_it2 = it2;
347  }
348  }
349  }
350 
351  NodeType* n[2] = {*min_it1, *min_it2};
352  NodeType* p = createNode(nullptr, n[0]->bv, n[1]->bv, nullptr);
353  p->children[0] = n[0];
354  p->children[1] = n[1];
355  n[0]->parent = p;
356  n[1]->parent = p;
357  *min_it1 = p;
358  NodeType* tmp = *min_it2;
359  lcur_end--;
360  *min_it2 = *lcur_end;
361  *lcur_end = tmp;
362  }
363 }
364 
365 //==============================================================================
366 template<typename BV>
367 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::topdown(const NodeVecIterator lbeg, const NodeVecIterator lend)
368 {
369  switch(topdown_level)
370  {
371  case 0:
372  return topdown_0(lbeg, lend);
373  break;
374  case 1:
375  return topdown_1(lbeg, lend);
376  break;
377  default:
378  return topdown_0(lbeg, lend);
379  }
380 }
381 
382 //==============================================================================
383 template<typename BV>
384 size_t HierarchyTree<BV>::getMaxHeight(NodeType* node) const
385 {
386  if(!node->isLeaf())
387  {
388  size_t height1 = getMaxHeight(node->children[0]);
389  size_t height2 = getMaxHeight(node->children[1]);
390  return std::max(height1, height2) + 1;
391  }
392  else
393  return 0;
394 }
395 
396 //==============================================================================
397 template<typename BV>
398 void HierarchyTree<BV>::getMaxDepth(NodeType* node, size_t depth, size_t& max_depth) const
399 {
400  if(!node->isLeaf())
401  {
402  getMaxDepth(node->children[0], depth+1, max_depth);
403  getMaxDepth(node->children[1], depth+1, max_depth);
404  }
405  else
406  max_depth = std::max(max_depth, depth);
407 }
408 
409 //==============================================================================
410 template<typename BV>
411 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::topdown_0(const NodeVecIterator lbeg, const NodeVecIterator lend)
412 {
413  int num_leaves = lend - lbeg;
414  if(num_leaves > 1)
415  {
416  if(num_leaves > bu_threshold)
417  {
418  BV vol = (*lbeg)->bv;
419  for(NodeVecIterator it = lbeg + 1; it < lend; ++it)
420  vol += (*it)->bv;
421 
422  int best_axis = 0;
423  S extent[3] = {vol.width(), vol.height(), vol.depth()};
424  if(extent[1] > extent[0]) best_axis = 1;
425  if(extent[2] > extent[best_axis]) best_axis = 2;
426 
427  // compute median
428  NodeVecIterator lcenter = lbeg + num_leaves / 2;
429  std::nth_element(lbeg, lcenter, lend, std::bind(&nodeBaseLess<BV>, std::placeholders::_1, std::placeholders::_2, std::ref(best_axis)));
430 
431  NodeType* node = createNode(nullptr, vol, nullptr);
432  node->children[0] = topdown_0(lbeg, lcenter);
433  node->children[1] = topdown_0(lcenter, lend);
434  node->children[0]->parent = node;
435  node->children[1]->parent = node;
436  return node;
437  }
438  else
439  {
440  bottomup(lbeg, lend);
441  return *lbeg;
442  }
443  }
444  return *lbeg;
445 }
446 
447 //==============================================================================
448 template<typename BV>
449 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::topdown_1(const NodeVecIterator lbeg, const NodeVecIterator lend)
450 {
451  int num_leaves = lend - lbeg;
452  if(num_leaves > 1)
453  {
454  if(num_leaves > bu_threshold)
455  {
456  Vector3<S> split_p = (*lbeg)->bv.center();
457  BV vol = (*lbeg)->bv;
458  NodeVecIterator it;
459  for(it = lbeg + 1; it < lend; ++it)
460  {
461  split_p += (*it)->bv.center();
462  vol += (*it)->bv;
463  }
464  split_p /= (S)(num_leaves);
465  int best_axis = -1;
466  int bestmidp = num_leaves;
467  int splitcount[3][2] = {{0,0}, {0,0}, {0,0}};
468  for(it = lbeg; it < lend; ++it)
469  {
470  Vector3<S> x = (*it)->bv.center() - split_p;
471  for(size_t j = 0; j < 3; ++j)
472  ++splitcount[j][x[j] > 0 ? 1 : 0];
473  }
474 
475  for(size_t i = 0; i < 3; ++i)
476  {
477  if((splitcount[i][0] > 0) && (splitcount[i][1] > 0))
478  {
479  int midp = std::abs(splitcount[i][0] - splitcount[i][1]);
480  if(midp < bestmidp)
481  {
482  best_axis = i;
483  bestmidp = midp;
484  }
485  }
486  }
487 
488  if(best_axis < 0) best_axis = 0;
489 
490  S split_value = split_p[best_axis];
491  NodeVecIterator lcenter = lbeg;
492  for(it = lbeg; it < lend; ++it)
493  {
494  if((*it)->bv.center()[best_axis] < split_value)
495  {
496  NodeType* temp = *it;
497  *it = *lcenter;
498  *lcenter = temp;
499  ++lcenter;
500  }
501  }
502 
503  NodeType* node = createNode(nullptr, vol, nullptr);
504  node->children[0] = topdown_1(lbeg, lcenter);
505  node->children[1] = topdown_1(lcenter, lend);
506  node->children[0]->parent = node;
507  node->children[1]->parent = node;
508  return node;
509  }
510  else
511  {
512  bottomup(lbeg, lend);
513  return *lbeg;
514  }
515  }
516  return *lbeg;
517 }
518 
519 //==============================================================================
520 template<typename BV>
521 void HierarchyTree<BV>::init_0(std::vector<NodeType*>& leaves)
522 {
523  clear();
524  root_node = topdown(leaves.begin(), leaves.end());
525  n_leaves = leaves.size();
526  max_lookahead_level = -1;
527  opath = 0;
528 }
529 
530 //==============================================================================
531 template<typename BV>
532 void HierarchyTree<BV>::init_1(std::vector<NodeType*>& leaves)
533 {
534  clear();
535 
536  BV bound_bv;
537  if(leaves.size() > 0)
538  bound_bv = leaves[0]->bv;
539  for(size_t i = 1; i < leaves.size(); ++i)
540  bound_bv += leaves[i]->bv;
541 
542  morton_functor<typename BV::S, uint32> coder(bound_bv);
543  for(size_t i = 0; i < leaves.size(); ++i)
544  leaves[i]->code = coder(leaves[i]->bv.center());
545 
546  std::sort(leaves.begin(), leaves.end(), SortByMorton());
547 
548  root_node = mortonRecurse_0(leaves.begin(), leaves.end(), (1 << (coder.bits()-1)), coder.bits()-1);
549 
550  refit();
551  n_leaves = leaves.size();
552  max_lookahead_level = -1;
553  opath = 0;
554 }
555 
556 //==============================================================================
557 template<typename BV>
558 void HierarchyTree<BV>::init_2(std::vector<NodeType*>& leaves)
559 {
560  clear();
561 
562  BV bound_bv;
563  if(leaves.size() > 0)
564  bound_bv = leaves[0]->bv;
565  for(size_t i = 1; i < leaves.size(); ++i)
566  bound_bv += leaves[i]->bv;
567 
568  morton_functor<typename BV::S, uint32> coder(bound_bv);
569  for(size_t i = 0; i < leaves.size(); ++i)
570  leaves[i]->code = coder(leaves[i]->bv.center());
571 
572  std::sort(leaves.begin(), leaves.end(), SortByMorton());
573 
574  root_node = mortonRecurse_1(leaves.begin(), leaves.end(), (1 << (coder.bits()-1)), coder.bits()-1);
575 
576  refit();
577  n_leaves = leaves.size();
578  max_lookahead_level = -1;
579  opath = 0;
580 }
581 
582 //==============================================================================
583 template<typename BV>
584 void HierarchyTree<BV>::init_3(std::vector<NodeType*>& leaves)
585 {
586  clear();
587 
588  BV bound_bv;
589  if(leaves.size() > 0)
590  bound_bv = leaves[0]->bv;
591  for(size_t i = 1; i < leaves.size(); ++i)
592  bound_bv += leaves[i]->bv;
593 
594  morton_functor<typename BV::S, uint32> coder(bound_bv);
595  for(size_t i = 0; i < leaves.size(); ++i)
596  leaves[i]->code = coder(leaves[i]->bv.center());
597 
598  std::sort(leaves.begin(), leaves.end(), SortByMorton());
599 
600  root_node = mortonRecurse_2(leaves.begin(), leaves.end());
601 
602  refit();
603  n_leaves = leaves.size();
604  max_lookahead_level = -1;
605  opath = 0;
606 }
607 
608 //==============================================================================
609 template<typename BV>
610 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::mortonRecurse_0(const NodeVecIterator lbeg, const NodeVecIterator lend, const uint32& split, int bits)
611 {
612  int num_leaves = lend - lbeg;
613  if(num_leaves > 1)
614  {
615  if(bits > 0)
616  {
617  NodeType dummy;
618  dummy.code = split;
619  NodeVecIterator lcenter = std::lower_bound(lbeg, lend, &dummy, SortByMorton());
620 
621  if(lcenter == lbeg)
622  {
623  uint32 split2 = split | (1 << (bits - 1));
624  return mortonRecurse_0(lbeg, lend, split2, bits - 1);
625  }
626  else if(lcenter == lend)
627  {
628  uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
629  return mortonRecurse_0(lbeg, lend, split1, bits - 1);
630  }
631  else
632  {
633  uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
634  uint32 split2 = split | (1 << (bits - 1));
635 
636  NodeType* child1 = mortonRecurse_0(lbeg, lcenter, split1, bits - 1);
637  NodeType* child2 = mortonRecurse_0(lcenter, lend, split2, bits - 1);
638  NodeType* node = createNode(nullptr, nullptr);
639  node->children[0] = child1;
640  node->children[1] = child2;
641  child1->parent = node;
642  child2->parent = node;
643  return node;
644  }
645  }
646  else
647  {
648  NodeType* node = topdown(lbeg, lend);
649  return node;
650  }
651  }
652  else
653  return *lbeg;
654 }
655 
656 //==============================================================================
657 template<typename BV>
658 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::mortonRecurse_1(const NodeVecIterator lbeg, const NodeVecIterator lend, const uint32& split, int bits)
659 {
660  int num_leaves = lend - lbeg;
661  if(num_leaves > 1)
662  {
663  if(bits > 0)
664  {
665  NodeType dummy;
666  dummy.code = split;
667  NodeVecIterator lcenter = std::lower_bound(lbeg, lend, &dummy, SortByMorton());
668 
669  if(lcenter == lbeg)
670  {
671  uint32 split2 = split | (1 << (bits - 1));
672  return mortonRecurse_1(lbeg, lend, split2, bits - 1);
673  }
674  else if(lcenter == lend)
675  {
676  uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
677  return mortonRecurse_1(lbeg, lend, split1, bits - 1);
678  }
679  else
680  {
681  uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
682  uint32 split2 = split | (1 << (bits - 1));
683 
684  NodeType* child1 = mortonRecurse_1(lbeg, lcenter, split1, bits - 1);
685  NodeType* child2 = mortonRecurse_1(lcenter, lend, split2, bits - 1);
686  NodeType* node = createNode(nullptr, nullptr);
687  node->children[0] = child1;
688  node->children[1] = child2;
689  child1->parent = node;
690  child2->parent = node;
691  return node;
692  }
693  }
694  else
695  {
696  NodeType* child1 = mortonRecurse_1(lbeg, lbeg + num_leaves / 2, 0, bits - 1);
697  NodeType* child2 = mortonRecurse_1(lbeg + num_leaves / 2, lend, 0, bits - 1);
698  NodeType* node = createNode(nullptr, nullptr);
699  node->children[0] = child1;
700  node->children[1] = child2;
701  child1->parent = node;
702  child2->parent = node;
703  return node;
704  }
705  }
706  else
707  return *lbeg;
708 }
709 
710 //==============================================================================
711 template<typename BV>
712 typename HierarchyTree<BV>::NodeType* HierarchyTree<BV>::mortonRecurse_2(const NodeVecIterator lbeg, const NodeVecIterator lend)
713 {
714  int num_leaves = lend - lbeg;
715  if(num_leaves > 1)
716  {
717  NodeType* child1 = mortonRecurse_2(lbeg, lbeg + num_leaves / 2);
718  NodeType* child2 = mortonRecurse_2(lbeg + num_leaves / 2, lend);
719  NodeType* node = createNode(nullptr, nullptr);
720  node->children[0] = child1;
721  node->children[1] = child2;
722  child1->parent = node;
723  child2->parent = node;
724  return node;
725  }
726  else
727  return *lbeg;
728 }
729 
730 //==============================================================================
731 template<typename BV>
732 void HierarchyTree<BV>::update_(NodeType* leaf, const BV& bv)
733 {
734  NodeType* root = removeLeaf(leaf);
735  if(root)
736  {
737  if(max_lookahead_level >= 0)
738  {
739  for(int i = 0; (i < max_lookahead_level) && root->parent; ++i)
740  root = root->parent;
741  }
742  else
743  root = root_node;
744  }
745 
746  leaf->bv = bv;
747  insertLeaf(root, leaf);
748 }
749 
750 //==============================================================================
751 template<typename BV>
753 {
754  NodeType* p = n->parent;
755  if(p > n)
756  {
757  int i = indexOf(n);
758  int j = 1 - i;
759  NodeType* s = p->children[j];
760  NodeType* q = p->parent;
761  if(q) q->children[indexOf(p)] = n; else r = n;
762  s->parent = n;
763  p->parent = n;
764  n->parent = q;
765  p->children[0] = n->children[0];
766  p->children[1] = n->children[1];
767  n->children[0]->parent = p;
768  n->children[1]->parent = p;
769  n->children[i] = p;
770  n->children[j] = s;
771  std::swap(p->bv, n->bv);
772  return p;
773  }
774  return n;
775 }
776 
777 //==============================================================================
778 template<typename BV>
780 {
781  if(!root_node)
782  {
783  root_node = leaf;
784  leaf->parent = nullptr;
785  }
786  else
787  {
788  if(!root->isLeaf())
789  {
790  do
791  {
792  root = root->children[select(*leaf, *(root->children[0]), *(root->children[1]))];
793  }
794  while(!root->isLeaf());
795  }
796 
797  NodeType* prev = root->parent;
798  NodeType* node = createNode(prev, leaf->bv, root->bv, nullptr);
799  if(prev)
800  {
801  prev->children[indexOf(root)] = node;
802  node->children[0] = root; root->parent = node;
803  node->children[1] = leaf; leaf->parent = node;
804  do
805  {
806  if(!prev->bv.contain(node->bv))
807  prev->bv = prev->children[0]->bv + prev->children[1]->bv;
808  else
809  break;
810  node = prev;
811  } while (nullptr != (prev = node->parent));
812  }
813  else
814  {
815  node->children[0] = root; root->parent = node;
816  node->children[1] = leaf; leaf->parent = node;
817  root_node = node;
818  }
819  }
820 }
821 
822 //==============================================================================
823 template<typename BV>
825 {
826  if(leaf == root_node)
827  {
828  root_node = nullptr;
829  return nullptr;
830  }
831  else
832  {
833  NodeType* parent = leaf->parent;
834  NodeType* prev = parent->parent;
835  NodeType* sibling = parent->children[1-indexOf(leaf)];
836  if(prev)
837  {
838  prev->children[indexOf(parent)] = sibling;
839  sibling->parent = prev;
840  deleteNode(parent);
841  while(prev)
842  {
843  BV new_bv = prev->children[0]->bv + prev->children[1]->bv;
844  if(!new_bv.equal(prev->bv))
845  {
846  prev->bv = new_bv;
847  prev = prev->parent;
848  }
849  else break;
850  }
851 
852  return prev ? prev : root_node;
853  }
854  else
855  {
856  root_node = sibling;
857  sibling->parent = nullptr;
858  deleteNode(parent);
859  return root_node;
860  }
861  }
862 }
863 
864 //==============================================================================
865 template<typename BV>
866 void HierarchyTree<BV>::fetchLeaves(NodeType* root, std::vector<NodeType*>& leaves, int depth)
867 {
868  if((!root->isLeaf()) && depth)
869  {
870  fetchLeaves(root->children[0], leaves, depth-1);
871  fetchLeaves(root->children[1], leaves, depth-1);
872  deleteNode(root);
873  }
874  else
875  {
876  leaves.push_back(root);
877  }
878 }
879 
880 //==============================================================================
881 template<typename BV>
883 {
884  // node cannot be nullptr
885  return (node->parent->children[1] == node);
886 }
887 
888 //==============================================================================
889 template<typename BV>
891  const BV& bv,
892  void* data)
893 {
894  NodeType* node = createNode(parent, data);
895  node->bv = bv;
896  return node;
897 }
898 
899 //==============================================================================
900 template<typename BV>
902  const BV& bv1,
903  const BV& bv2,
904  void* data)
905 {
906  NodeType* node = createNode(parent, data);
907  node->bv = bv1 + bv2;
908  return node;
909 }
910 
911 //==============================================================================
912 template<typename BV>
914 {
915  NodeType* node = nullptr;
916  if(free_node)
917  {
918  node = free_node;
919  free_node = nullptr;
920  }
921  else
922  node = new NodeType();
923  node->parent = parent;
924  node->data = data;
925  node->children[1] = 0;
926  return node;
927 }
928 
929 //==============================================================================
930 template<typename BV>
932 {
933  if(free_node != node)
934  {
935  delete free_node;
936  free_node = node;
937  }
938 }
939 
940 //==============================================================================
941 template<typename BV>
943 {
944  if(!node->isLeaf())
945  {
946  recurseDeleteNode(node->children[0]);
947  recurseDeleteNode(node->children[1]);
948  }
949 
950  if(node == root_node) root_node = nullptr;
951  deleteNode(node);
952 }
953 
954 //==============================================================================
955 template<typename BV>
957 {
958  if(!node->isLeaf())
959  {
960  recurseRefit(node->children[0]);
961  recurseRefit(node->children[1]);
962  node->bv = node->children[0]->bv + node->children[1]->bv;
963  }
964  else
965  return;
966 }
967 
968 //==============================================================================
969 template<typename BV>
970 BV HierarchyTree<BV>::bounds(const std::vector<NodeType*>& leaves)
971 {
972  if(leaves.size() == 0) return BV();
973  BV bv = leaves[0]->bv;
974  for(size_t i = 1; i < leaves.size(); ++i)
975  {
976  bv += leaves[i]->bv;
977  }
978 
979  return bv;
980 }
981 
982 //==============================================================================
983 template<typename BV>
984 BV HierarchyTree<BV>::bounds(const NodeVecIterator lbeg, const NodeVecIterator lend)
985 {
986  if(lbeg == lend) return BV();
987  BV bv = *lbeg;
988  for(NodeVecIterator it = lbeg + 1; it < lend; ++it)
989  {
990  bv += (*it)->bv;
991  }
992 
993  return bv;
994 }
995 
996 //==============================================================================
997 template<typename BV>
998 bool nodeBaseLess(NodeBase<BV>* a, NodeBase<BV>* b, int d)
999 {
1000  if(a->bv.center()[d] < b->bv.center()[d]) return true;
1001  return false;
1002 }
1003 
1004 //==============================================================================
1005 template <typename S, typename BV>
1007 {
1008  static std::size_t run(
1009  const NodeBase<BV>& /*query*/,
1010  const NodeBase<BV>& /*node1*/,
1011  const NodeBase<BV>& /*node2*/)
1012  {
1013  return 0;
1014  }
1015 
1016  static std::size_t run(
1017  const BV& /*query*/,
1018  const NodeBase<BV>& /*node1*/,
1019  const NodeBase<BV>& /*node2*/)
1020  {
1021  return 0;
1022  }
1023 };
1024 
1025 //==============================================================================
1026 template<typename BV>
1027 size_t select(
1028  const NodeBase<BV>& query,
1029  const NodeBase<BV>& node1,
1030  const NodeBase<BV>& node2)
1031 {
1032  return SelectImpl<typename BV::S, BV>::run(query, node1, node2);
1033 }
1034 
1035 //==============================================================================
1036 template<typename BV>
1037 size_t select(
1038  const BV& query,
1039  const NodeBase<BV>& node1,
1040  const NodeBase<BV>& node2)
1041 {
1042  return SelectImpl<typename BV::S, BV>::run(query, node1, node2);
1043 }
1044 
1045 //==============================================================================
1046 template <typename S>
1047 struct SelectImpl<S, AABB<S>>
1048 {
1049  static std::size_t run(
1050  const NodeBase<AABB<S>>& node,
1051  const NodeBase<AABB<S>>& node1,
1052  const NodeBase<AABB<S>>& node2)
1053  {
1054  const AABB<S>& bv = node.bv;
1055  const AABB<S>& bv1 = node1.bv;
1056  const AABB<S>& bv2 = node2.bv;
1057  Vector3<S> v = bv.min_ + bv.max_;
1058  Vector3<S> v1 = v - (bv1.min_ + bv1.max_);
1059  Vector3<S> v2 = v - (bv2.min_ + bv2.max_);
1060  S d1 = fabs(v1[0]) + fabs(v1[1]) + fabs(v1[2]);
1061  S d2 = fabs(v2[0]) + fabs(v2[1]) + fabs(v2[2]);
1062  return (d1 < d2) ? 0 : 1;
1063  }
1064 
1065  static std::size_t run(
1066  const AABB<S>& query,
1067  const NodeBase<AABB<S>>& node1,
1068  const NodeBase<AABB<S>>& node2)
1069  {
1070  const AABB<S>& bv = query;
1071  const AABB<S>& bv1 = node1.bv;
1072  const AABB<S>& bv2 = node2.bv;
1073  Vector3<S> v = bv.min_ + bv.max_;
1074  Vector3<S> v1 = v - (bv1.min_ + bv1.max_);
1075  Vector3<S> v2 = v - (bv2.min_ + bv2.max_);
1076  S d1 = fabs(v1[0]) + fabs(v1[1]) + fabs(v1[2]);
1077  S d2 = fabs(v2[0]) + fabs(v2[1]) + fabs(v2[2]);
1078  return (d1 < d2) ? 0 : 1;
1079  }
1080 
1081  static bool run(
1082  const HierarchyTree<AABB<S>>& tree,
1083  typename HierarchyTree<AABB<S>>::NodeType* leaf,
1084  const AABB<S>& bv_,
1085  const Vector3<S>& vel,
1086  S margin)
1087  {
1088  AABB<S> bv(bv_);
1089  if(leaf->bv.contain(bv)) return false;
1090  Vector3<S> marginv(margin);
1091  bv.min_ -= marginv;
1092  bv.max_ += marginv;
1093  if(vel[0] > 0) bv.max_[0] += vel[0];
1094  else bv.min_[0] += vel[0];
1095  if(vel[1] > 0) bv.max_[1] += vel[1];
1096  else bv.min_[1] += vel[1];
1097  if(vel[2] > 0) bv.max_[2] += vel[2];
1098  else bv.max_[2] += vel[2];
1099  tree.update(leaf, bv);
1100  return true;
1101  }
1102 
1103  static bool run(
1104  const HierarchyTree<AABB<S>>& tree,
1105  typename HierarchyTree<AABB<S>>::NodeType* leaf,
1106  const AABB<S>& bv_,
1107  const Vector3<S>& vel)
1108  {
1109  AABB<S> bv(bv_);
1110  if(leaf->bv.contain(bv)) return false;
1111  if(vel[0] > 0) bv.max_[0] += vel[0];
1112  else bv.min_[0] += vel[0];
1113  if(vel[1] > 0) bv.max_[1] += vel[1];
1114  else bv.min_[1] += vel[1];
1115  if(vel[2] > 0) bv.max_[2] += vel[2];
1116  else bv.max_[2] += vel[2];
1117  tree.update(leaf, bv);
1118  return true;
1119  }
1120 };
1121 
1122 } // namespace detail
1123 } // namespace fcl
1124 
1125 #endif
dynamic AABB<S> tree node
Definition: node_base.h:51
void clear()
Clear the tree.
Definition: hierarchy_tree-inl.h:113
Definition: hierarchy_tree-inl.h:1006
void extractLeaves(const NodeType *root, std::vector< NodeType * > &leaves) const
extract all the leaves of the tree
Definition: hierarchy_tree-inl.h:279
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
void balanceBottomup()
balance the tree from bottom
Definition: hierarchy_tree-inl.h:222
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition: AABB.h:49
NodeBase< BV > * parent
pointer to parent node
Definition: node_base.h:57
size_t getMaxDepth() const
get the max depth of the tree
Definition: hierarchy_tree-inl.h:211
void update(NodeType *leaf, int lookahead_level=-1)
update one leaf node
Definition: hierarchy_tree-inl.h:133
Vector3< S > max_
The max point in the AABB.
Definition: AABB.h:59
size_t getMaxHeight() const
get the max height of the tree
Definition: hierarchy_tree-inl.h:202
NodeBase< BV > * children[2]
for leaf node, children nodes
Definition: node_base.h:68
void balanceIncremental(int iterations)
balance the tree in an incremental way
Definition: hierarchy_tree-inl.h:249
Definition: hierarchy_tree-inl.h:160
NodeType * getRoot() const
get the root of the tree
Definition: hierarchy_tree-inl.h:299
uint32 code
morton code for current BV
Definition: node_base.h:73
void refit()
refit the tree, i.e., when the leaf nodes&#39; bounding volumes change, update the entire tree in a botto...
Definition: hierarchy_tree-inl.h:271
bool empty() const
Whether the tree is empty.
Definition: hierarchy_tree-inl.h:126
void remove(NodeType *leaf)
Remove a leaf node.
Definition: hierarchy_tree-inl.h:104
bool isLeaf() const
whether is a leaf
Definition: node_base-inl.h:57
Class for hierarchy tree structure.
Definition: hierarchy_tree.h:58
Vector3< S > min_
The min point in the AABB.
Definition: AABB.h:56
void init(std::vector< NodeType * > &leaves, int level=0)
Initialize the tree by a set of leaves using algorithm with a given level.
Definition: hierarchy_tree-inl.h:71
BV bv
the bounding volume for the node
Definition: node_base.h:54
size_t size() const
number of leaves in the tree
Definition: hierarchy_tree-inl.h:292
void balanceTopdown()
balance the tree from top
Definition: hierarchy_tree-inl.h:236
NodeType * insert(const BV &bv, void *data)
Insest a node.
Definition: hierarchy_tree-inl.h:94
void print(NodeType *root, int depth)
print the tree in a recursive way
Definition: hierarchy_tree-inl.h:313
HierarchyTree(int bu_threshold_=16, int topdown_level_=0)
Create hierarchy tree with suitable setting. bu_threshold decides the height of tree node to start bo...
Definition: hierarchy_tree-inl.h:51