45#ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_AABP_TREE_INL
46#define LASS_GUARDIAN_OF_INCLUSION_SPAT_AABP_TREE_INL
60template <
typename O,
typename OT,
typename SH>
61AabpTree<O, OT, SH>::AabpTree(
const TSplitHeuristics& heuristics):
63 aabb_(TObjectTraits::aabbEmpty()),
66 end_(new TObjectIterator)
72template <
typename O,
typename OT,
typename SH>
73AabpTree<O, OT, SH>::AabpTree(TObjectIterator first, TObjectIterator last,
const TSplitHeuristics& heuristics):
75 aabb_(TObjectTraits::aabbEmpty()),
78 end_(new TObjectIterator(last))
80 const std::ptrdiff_t size = last - first;
83 LASS_THROW(
"AabpTree: invalid range");
85 if (
static_cast<size_t>(size) >= maxSize)
87 LASS_THROW(
"AabpTree: too many objects");
92 inputs.reserve(
static_cast<size_t>(size));
93 for (TObjectIterator i = first; i != last; ++i)
95 TAabb aabb = TObjectTraits::objectAabb(i);
96 aabb_ = TObjectTraits::aabbJoin(aabb_, aabb);
97 inputs.push_back(Input(aabb, i));
99 balance(inputs.begin(), inputs.end());
104template <
typename O,
typename OT,
typename SH>
105AabpTree<O, OT, SH>::AabpTree(TSelf&& other)
noexcept:
106 SH(std::forward< TSplitHeuristics>(other)),
107 objects_(std::move(other.objects_)),
108 nodes_(std::move(other.nodes_)),
109 end_(std::move(other.end_))
114template <
typename O,
typename OT,
typename SH>
115AabpTree<O, OT, SH>& AabpTree<O, OT, SH>::operator=(TSelf&& other)
noexcept
117 TSplitHeuristics::operator=(std::forward<TSplitHeuristics>(other));
118 objects_ = std::move(other.objects_);
119 nodes_ = std::move(other.nodes_);
120 end_ = std::move(other.end_);
125template <
typename O,
typename OT,
typename SH>
126void AabpTree<O, OT, SH>::reset()
128 TSelf temp(
static_cast<const SH&
>(*
this));
134template <
typename O,
typename OT,
typename SH>
135void AabpTree<O, OT, SH>::reset(TObjectIterator first, TObjectIterator last)
137 TSelf temp(first, last,
static_cast<const SH&
>(*
this));
143template <
typename O,
typename OT,
typename SH>
144const typename AabpTree<O, OT, SH>::TAabb&
145AabpTree<O, OT, SH>::aabb()
const
152template <
typename O,
typename OT,
typename SH>
153bool AabpTree<O, OT, SH>::contains(
const TPoint& point,
const TInfo* info)
const
155 if (isEmpty() || !TObjectTraits::aabbContains(aabb_, point))
159 return doContains(0, point, info);
164template <
typename O,
typename OT,
typename SH>
165template <
typename OutputIterator>
166OutputIterator AabpTree<O, OT, SH>::find(
const TPoint& point, OutputIterator result,
const TInfo* info)
const
168 if (isEmpty() || !TObjectTraits::aabbContains(aabb_, point))
172 return doFind(0, point, result, info);
177template <
typename O,
typename OT,
typename SH>
178template <
typename OutputIterator>
179OutputIterator AabpTree<O, OT, SH>::find(
const TAabb& box, OutputIterator result,
const TInfo* info)
const
181 if (isEmpty() || !TObjectTraits::aabbIntersects(aabb_, box))
185 return doFind(0, box, result, info);
190template <
typename O,
typename OT,
typename SH>
191template <
typename OutputIterator>
192OutputIterator AabpTree<O, OT, SH>::find(
const TRay& ray, TParam tMin, TParam tMax, OutputIterator result,
const TInfo* info)
const
195 if (isEmpty() || !TObjectTraits::aabbIntersect(aabb_, ray, tNear, tMin))
200 if (!TObjectTraits::aabbIntersect(aabb_, ray, tFar, tNear))
205 if (tNear > tMax || tFar < tMin)
209 const TVector reciprocalDirection = TObjectTraits::vectorReciprocal(TObjectTraits::rayDirection(ray));
210 return doFind(0, ray, tMin, tMax, result, info, reciprocalDirection, tNear, tFar);
215template <
typename O,
typename OT,
typename SH>
216const typename AabpTree<O, OT, SH>::TObjectIterator
217AabpTree<O, OT, SH>::intersect(
const TRay& ray, TReference t, TParam tMin,
const TInfo* info)
const
220 if (isEmpty() || !TObjectTraits::aabbIntersect(aabb_, ray, tNear, tMin))
225 if (!TObjectTraits::aabbIntersect(aabb_, ray, tFar, tNear))
230 const TVector reciprocalDirection = TObjectTraits::vectorReciprocal(TObjectTraits::rayDirection(ray));
231 TObjectIterator hit = doIntersect(0, ray, t, tMin, info, reciprocalDirection, tNear, tFar);
232 LASS_ASSERT((t > tMin && t >= tNear * (1 - 1e-7f) && t <= tFar * (1 + 1e-7f)) || hit == *end_);
238template <
typename O,
typename OT,
typename SH>
239bool AabpTree<O, OT, SH>::intersects(
240 const TRay& ray, TParam tMin, TParam tMax,
const TInfo* info)
const
242 LASS_ASSERT(tMax > tMin || (num::isInf(tMin) && num::isInf(tMax)));
244 if (isEmpty() || !TObjectTraits::aabbIntersect(aabb_, ray, tNear, tMin))
249 if (!TObjectTraits::aabbIntersect(aabb_, ray, tFar, tNear))
254 if (tNear > tMax || tFar < tMin)
258 const TPoint support = TObjectTraits::raySupport(ray);
259 const TVector direction = TObjectTraits::rayDirection(ray);
260 const TVector reciprocalDirection = TObjectTraits::vectorReciprocal(direction);
267 Visit(TIndex index = 0, TValue tNear = 0, TValue tFar = 0) : index(index), tNear(tNear), tFar(tFar) {}
270 TIndex stackSize = 0;
271 stack[stackSize++] = Visit(0, tNear, tFar);
272 while (stackSize > 0)
274 const Visit visit = stack[--stackSize];
275 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
276 LASS_ASSERT(visit.index < nodes_.size());
277 const Node& node = nodes_[visit.index];
281 for (TIndex i = node.first(); i != node.last(); ++i)
283 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
284 if (TObjectTraits::objectIntersects(objects_[i], ray, tMin, tMax, info))
292 const TIndex leftIndex = visit.index + 1;
293 const TIndex rightIndex = node.right();
294 const TValue s = TObjectTraits::coord(support, node.axis());
295 const TValue d = TObjectTraits::coord(direction, node.axis());
296 const TValue invD = TObjectTraits::coord(reciprocalDirection, node.axis());
297 const TValue tLeftBound = (node.leftBound() - s) * invD;
298 const TValue tRightBound = (node.rightBound() - s) * invD;
301 if (tRightBound < tFar)
303 stack[stackSize++] = Visit(rightIndex, std::max(tRightBound, visit.tNear), visit.tFar);
305 if (tLeftBound > tNear)
307 stack[stackSize++] = Visit(leftIndex, visit.tNear, std::min(tLeftBound, visit.tFar));
312 if (tRightBound > tNear)
314 stack[stackSize++] = Visit(rightIndex, visit.tNear, std::min(tRightBound, visit.tFar));
316 if (tLeftBound < tFar)
318 stack[stackSize++] = Visit(leftIndex, std::max(tLeftBound, visit.tNear), visit.tFar);
323 if (s >= node.rightBound())
325 stack[stackSize++] = Visit(rightIndex, visit.tNear, visit.tFar);
327 if (s <= node.leftBound())
329 stack[stackSize++] = Visit(leftIndex, visit.tNear, visit.tFar);
335 return doIntersects(0, ray, tMin, tMax, info, reciprocalDirection, tNear, tFar);
341template <
typename O,
typename OT,
typename SH>
342const typename AabpTree<O, OT, SH>::Neighbour
343AabpTree<O, OT, SH>::nearestNeighbour(
const TPoint& target,
const TInfo* info)
const
345 Neighbour nearest(*end_, std::numeric_limits<TValue>::infinity());
348 doNearestNeighbour(0, target, info, nearest);
355template <
class O,
class OT,
typename SH>
356template <
typename RandomAccessIterator>
358AabpTree<O, OT, SH>::rangeSearch(
359 const TPoint& target, TParam maxRadius,
size_t maxCount, RandomAccessIterator first,
360 const TInfo* info)
const
362 if (isEmpty() || maxRadius == 0)
366 TValue squaredRadius = maxRadius * maxRadius;
367 return doRangeSearch(0, target, squaredRadius, maxCount, first, first, info);
372template <
typename O,
typename OT,
typename SH>
373void AabpTree<O, OT, SH>::swap(TSelf& other)
376 std::swap(aabb_, other.aabb_);
377 nodes_.swap(other.nodes_);
378 objects_.swap(other.objects_);
379 end_.swap(other.end_);
384template <
typename O,
typename OT,
typename SH>
385bool AabpTree<O, OT, SH>::isEmpty()
const
387 return objects_.empty();
392template <
typename O,
typename OT,
typename SH>
393const typename AabpTree<O, OT, SH>::TObjectIterator
394AabpTree<O, OT, SH>::end()
const
407template <
typename O,
typename OT,
typename SH>
408const typename AabpTree<O, OT, SH>::BalanceResult
409AabpTree<O, OT, SH>::balance(TInputIterator first, TInputIterator last)
411 const SplitInfo<OT>
split = TSplitHeuristics::template split<OT>(first, last);
414 return BalanceResult(
split.aabb, addLeafNode(first, last));
417 TInputIterator middle = std::partition(first, last, impl::Splitter<TObjectTraits>(split));
418 if (middle == first || middle == last)
420 const std::ptrdiff_t halfSize = (last - first) / 2;
421 LASS_ASSERT(halfSize > 0);
422 middle = first + halfSize;
423 std::nth_element(first, middle, last, impl::LessAxis<TObjectTraits>(
split.axis));
425 LASS_ASSERT(middle != first && middle != last);
427 const TIndex index = addInternalNode(
split.axis);
428 const BalanceResult left = balance(first, middle);
429 const BalanceResult right = balance(middle, last);
431 Node& node = nodes_[index];
432 node.setLeftBound(TObjectTraits::coord(TObjectTraits::aabbMax(left.aabb),
split.axis));
433 node.setRightBound(TObjectTraits::coord(TObjectTraits::aabbMin(right.aabb),
split.axis));
434 LASS_ASSERT(left.index == index + 1);
435 node.setRight(right.index);
437 return BalanceResult(
split.aabb, index);
442template <
typename O,
typename OT,
typename SH>
443typename AabpTree<O, OT, SH>::TIndex
444AabpTree<O, OT, SH>::addLeafNode(TInputIterator first, TInputIterator last)
446 LASS_ASSERT(objects_.size() <= maxSize);
447 const TIndex begin =
static_cast<TIndex
>(objects_.size());
448 while (first != last)
450 objects_.push_back((first++)->
object);
453 LASS_ASSERT(objects_.size() <= maxSize);
454 const TIndex end =
static_cast<TIndex
>(objects_.size());
456 nodes_.push_back(Node(begin, end));
458 LASS_ASSERT(nodes_.size() > 0);
459 return static_cast<TIndex
>(nodes_.size() - 1);
464template <
typename O,
typename OT,
typename SH>
465typename AabpTree<O, OT, SH>::TIndex
466AabpTree<O, OT, SH>::addInternalNode(
size_t axis)
468 nodes_.push_back(Node(axis));
469 LASS_ASSERT(nodes_.size() > 0);
470 return static_cast<TIndex
>(nodes_.size() - 1);
475template <
typename O,
typename OT,
typename SH>
476bool AabpTree<O, OT, SH>::doContains(TIndex index,
const TPoint& point,
const TInfo* info)
const
478 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
479 LASS_ASSERT(index < nodes_.size());
480 const Node& node = nodes_[index];
484 for (TIndex i = node.first(); i != node.last(); ++i)
486 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
487 if (TObjectTraits::objectContains(objects_[i], point, info))
495 const TValue x = TObjectTraits::coord(point, node.axis());
496 if (x <= node.leftBound() && doContains(index + 1, point, info))
500 if (x >= node.rightBound() && doContains(node.right(), point, info))
509template <
typename O,
typename OT,
typename SH>
510template <
typename OutputIterator>
511OutputIterator AabpTree<O, OT, SH>::doFind(
512 TIndex index,
const TPoint& point, OutputIterator result,
const TInfo* info)
const
514 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
515 LASS_ASSERT(index < nodes_.size());
516 const Node& node = nodes_[index];
520 for (TIndex i = node.first(); i != node.last(); ++i)
522 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
523 if (TObjectTraits::objectContains(objects_[i], point, info))
525 *result++ = objects_[i];
531 const TValue x = TObjectTraits::coord(point, node.axis());
532 if (x <= node.leftBound())
534 result = doFind(index + 1, point, result, info);
536 if (x >= node.rightBound())
538 result = doFind(node.right(), point, result, info);
545template <
typename O,
typename OT,
typename SH>
546template <
typename OutputIterator>
547OutputIterator AabpTree<O, OT, SH>::doFind(
548 TIndex index,
const TAabb& box, OutputIterator result,
const TInfo* info)
const
550 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
551 LASS_ASSERT(index < nodes_.size());
552 const Node& node = nodes_[index];
556 for (TIndex i = node.first(); i != node.last(); ++i)
558 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
559 if (TObjectTraits::objectIntersects(objects_[i], box, info))
561 *result++ = objects_[i];
567 if (TObjectTraits::coord(TObjectTraits::aabbMin(box), node.axis()) <= node.leftBound())
569 result = doFind(index + 1, box, result, info);
571 if (TObjectTraits::coord(TObjectTraits::aabbMax(box), node.axis()) >= node.rightBound())
573 result = doFind(node.right(), box, result, info);
580template <
typename O,
typename OT,
typename SH>
581template <
typename OutputIterator>
582OutputIterator AabpTree<O, OT, SH>::doFind(
583 TIndex index,
const TRay& ray, TParam tMin, TParam tMax, OutputIterator result,
const TInfo* info,
584 const TVector& reciprocalDirection, TParam tNear, TParam tFar)
const
586 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
587 LASS_ASSERT(index < nodes_.size());
588 LASS_ASSERT(tFar >= tNear * (1 - 1e-6f));
589 const Node& node = nodes_[index];
593 for (TIndex i = node.first(); i != node.last(); ++i)
595 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
596 if (TObjectTraits::objectIntersects(objects_[i], ray, tMin, tMax, info))
598 *result++ = objects_[i];
605 const TIndex leftIndex = index + 1;
606 const TIndex rightIndex = node.right();
607 const TValue s = TObjectTraits::coord(TObjectTraits::raySupport(ray), node.axis());
608 const TValue d = TObjectTraits::coord(TObjectTraits::rayDirection(ray), node.axis());
609 const TValue invD = TObjectTraits::coord(reciprocalDirection, node.axis());
610 const TValue tLeftBound = (node.leftBound() - s) * invD;
611 const TValue tRightBound = (node.rightBound() - s) * invD;
615 if (tLeftBound > tNear)
617 result = doFind(leftIndex, ray, tMin, tMax, result, info, reciprocalDirection, tNear, std::min(tLeftBound, tFar));
619 if (tRightBound < tFar)
621 result = doFind(rightIndex, ray, tMin, tMax, result, info, reciprocalDirection, std::max(tRightBound, tNear), tFar);
626 if (tLeftBound < tFar)
628 result = doFind(leftIndex, ray, tMin, tMax, result, info, reciprocalDirection, std::max(tLeftBound, tNear), tFar);
630 if (tRightBound > tNear)
632 result = doFind(rightIndex, ray, tMin, tMax, result, info, reciprocalDirection, tNear, std::min(tRightBound, tFar));
637 if (s <= node.leftBound())
639 result = doFind(leftIndex, ray, tMin, tMax, result, info, reciprocalDirection, tNear, tFar);
641 if (s >= node.rightBound())
643 result = doFind(rightIndex, ray, tMin, tMax, result, info, reciprocalDirection, tNear, tFar);
651template <
typename O,
typename OT,
typename SH>
652const typename AabpTree<O, OT, SH>::TObjectIterator
653AabpTree<O, OT, SH>::doIntersect(
654 TIndex index,
const TRay& ray, TReference t, TParam tMin,
const TInfo* info,
655 const TVector& reciprocalDirection, TParam tNear, TParam tFar)
const
657 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
658 LASS_ASSERT(index < nodes_.size());
659 LASS_ASSERT(tFar >= tNear * (1 - 1e-6f));
660 const Node& node = nodes_[index];
665 TObjectIterator best = *end_;
666 for (TIndex i = node.first(); i != node.last(); ++i)
668 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
669 TValue tCandidate = 0;
670 if (TObjectTraits::objectIntersect(objects_[i], ray, tCandidate, tMin, info))
672 LASS_ASSERT(tCandidate > tMin);
673 if (best == *end_ || tCandidate < tBest)
675 LASS_ASSERT(tCandidate > tMin && tCandidate >= tNear * (1 - 1e-6f) && tCandidate <= tFar * (1 + 1e-6f));
689 const TIndex leftIndex = index + 1;
690 const TIndex rightIndex = node.right();
691 const TValue s = TObjectTraits::coord(TObjectTraits::raySupport(ray), node.axis());
692 const TValue d = TObjectTraits::coord(TObjectTraits::rayDirection(ray), node.axis());
693 const TValue invD = TObjectTraits::coord(reciprocalDirection, node.axis());
694 const TValue tLeftBound = (node.leftBound() - s) * invD;
695 const TValue tRightBound = (node.rightBound() - s) * invD;
699 TObjectIterator objectLeft = *end_;
700 TObjectIterator objectRight = *end_;
703 if (tLeftBound >= tNear * (1 - 1e-6f))
705 objectLeft = doIntersect(leftIndex, ray, tLeft, tMin, info, reciprocalDirection,
706 tNear, std::min(tLeftBound, tFar));
708 if (tRightBound <= tFar * (1 + 1e-6f))
710 objectRight = doIntersect(rightIndex, ray, tRight, tMin, info, reciprocalDirection,
711 std::max(tRightBound, tNear), tFar);
716 if (tLeftBound <= tFar * (1 + 1e-6f))
718 objectLeft = doIntersect(leftIndex, ray, tLeft, tMin, info, reciprocalDirection,
719 std::max(tLeftBound, tNear), tFar);
721 if (tRightBound >= tNear * (1 - 1e-6f))
723 objectRight = doIntersect(rightIndex, ray, tRight, tMin, info, reciprocalDirection,
724 tNear, std::min(tRightBound, tFar));
729 if (s <= node.leftBound())
731 objectLeft = doIntersect(leftIndex, ray, tLeft, tMin, info, reciprocalDirection,
734 if (s >= node.rightBound())
736 objectRight = doIntersect(rightIndex, ray, tRight, tMin, info, reciprocalDirection,
742 if (objectLeft != *end_ && (objectRight == *end_ || tLeft < tRight))
744 LASS_ASSERT(tLeft > tMin);
748 if (objectRight != *end_)
750 LASS_ASSERT(objectLeft == *end_ || !(tLeft < tRight));
751 LASS_ASSERT(tRight > tMin);
760template <
typename O,
typename OT,
typename SH>
761bool AabpTree<O, OT, SH>::doIntersects(
762 TIndex index,
const TRay& ray, TParam tMin, TParam tMax,
const TInfo* info,
763 const TVector& reciprocalDirection, TParam tNear, TParam tFar)
const
765 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
766 LASS_ASSERT(index < nodes_.size());
767 LASS_ASSERT(tMax > tMin);
768 const Node& node = nodes_[index];
772 for (TIndex i = node.first(); i != node.last(); ++i)
774 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
775 if (TObjectTraits::objectIntersects(objects_[i], ray, tMin, tMax, info))
784 const TIndex leftIndex = index + 1;
785 const TIndex rightIndex = node.right();
786 const TValue s = TObjectTraits::coord(TObjectTraits::raySupport(ray), node.axis());
787 const TValue d = TObjectTraits::coord(TObjectTraits::rayDirection(ray), node.axis());
788 const TValue invD = TObjectTraits::coord(reciprocalDirection, node.axis());
789 const TValue tLeftBound = (node.leftBound() - s) * invD;
790 const TValue tRightBound = (node.rightBound() - s) * invD;
794 if ((tLeftBound > tNear) && doIntersects(leftIndex, ray, tMin, tMax, info,
795 reciprocalDirection, tNear, std::min(tLeftBound, tFar)))
799 if ((tRightBound < tFar) && doIntersects(rightIndex, ray, tMin, tMax, info,
800 reciprocalDirection, std::max(tRightBound, tNear), tFar))
807 if ((tLeftBound < tFar) && doIntersects(leftIndex, ray, tMin, tMax, info,
808 reciprocalDirection, std::max(tLeftBound, tNear), tFar))
812 if ((tRightBound > tNear) && doIntersects(rightIndex, ray, tMin, tMax, info,
813 reciprocalDirection, tNear, std::min(tRightBound, tFar)))
820 if ((s <= node.leftBound()) && doIntersects(rightIndex, ray, tMin, tMax, info,
821 reciprocalDirection, tNear, tFar))
825 if ((s >= node.rightBound()) && doIntersects(rightIndex, ray, tMin, tMax, info,
826 reciprocalDirection, tNear, tFar))
836template <
typename O,
typename OT,
typename SH>
837void AabpTree<O, OT, SH>::doNearestNeighbour(
838 TIndex index,
const TPoint& target,
const TInfo* info, Neighbour& best)
const
840 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
841 LASS_ASSERT(index < nodes_.size());
842 LASS_ASSERT(best.squaredDistance() >= 0);
844 const Node& node = nodes_[index];
848 for (TIndex i = node.first(); i != node.last(); ++i)
850 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
851 const TValue squaredDistance =
852 TObjectTraits::objectSquaredDistance(objects_[i], target, info);
853 if (squaredDistance < best.squaredDistance())
855 best = Neighbour(objects_[i], squaredDistance);
862 TValue signedDist[2];
863 getChildren(index, target, children, signedDist);
864 if (signedDist[0] <= 0 || (signedDist[0] * signedDist[0]) < best.squaredDistance())
866 doNearestNeighbour(children[0], target, info, best);
867 if (signedDist[1] <= 0 || (signedDist[1] * signedDist[1]) < best.squaredDistance())
869 doNearestNeighbour(children[1], target, info, best);
877template <
typename O,
typename OT,
typename SH>
878template <
typename RandomIterator>
879RandomIterator AabpTree<O, OT, SH>::doRangeSearch(
880 TIndex index,
const TPoint& target, TReference squaredRadius,
size_t maxCount,
881 RandomIterator first, RandomIterator last,
const TInfo* info)
const
883 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_INIT_NODE(TInfo, info);
884 LASS_ASSERT(index < nodes_.size());
885 LASS_ASSERT(squaredRadius >= 0);
887 const Node& node = nodes_[index];
891 for (TIndex i = node.first(); i != node.last(); ++i)
893 LASS_SPAT_OBJECT_TREES_DIAGNOSTICS_VISIT_OBJECT;
894 const TValue sqrDist = TObjectTraits::objectSquaredDistance(objects_[i], target, info);
895 if (sqrDist < squaredRadius)
897 *last++ = Neighbour(objects_[i], sqrDist);
898 std::push_heap(first, last);
899 LASS_ASSERT(last >= first);
900 if (
static_cast<size_t>(last - first) > maxCount)
902 std::pop_heap(first, last);
904 squaredRadius = first->squaredDistance();
912 TValue signedDist[2];
913 getChildren(index, target, children, signedDist);
914 if (signedDist[0] <= 0 || (signedDist[0] * signedDist[0]) < squaredRadius)
916 last = doRangeSearch(children[0], target, squaredRadius, maxCount, first, last, info);
917 if (signedDist[1] <= 0 || (signedDist[1] * signedDist[1]) < squaredRadius)
919 last = doRangeSearch(children[1], target, squaredRadius, maxCount, first, last, info);
927template <
typename O,
typename OT,
typename SH>
928void AabpTree<O, OT, SH>::getChildren(
929 TIndex index,
const TPoint& target, TIndex indices[2], TValue signedDistances[2])
const
931 LASS_ASSERT(index < nodes_.size());
932 const Node& node = nodes_[index];
933 indices[0] = index + 1;
934 indices[1] = node.right();
935 const TValue x = TObjectTraits::coord(target, node.axis());
936 signedDistances[0] = x - node.leftBound();
937 signedDistances[1] = node.rightBound() - x;
939 if (signedDistances[1] < signedDistances[0])
941 std::swap(signedDistances[0], signedDistances[1]);
942 std::swap(indices[0], indices[1]);
std::vector< std::basic_string< Char, Traits, Alloc > > split(const std::basic_string< Char, Traits, Alloc > &to_be_split)
Reflects the Python function split without seperator argument.
spatial subdivisions, quadtrees, octrees, meshes in 2D and 3D, triangulators, ...
Library for Assembled Shared Sources.