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