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