10#ifndef PBAT_GEOMETRY_AABBKDTREEHIERARCHY_H
11#define PBAT_GEOMETRY_AABBKDTREEHIERARCHY_H
18#include "pbat/math/linalg/mini/Eigen.h"
39class AabbKdTreeHierarchy
42 static auto constexpr kDims = Dims;
45 AabbKdTreeHierarchy() =
default;
57 template <
class TDerivedL,
class TDerivedU>
59 Eigen::DenseBase<TDerivedL>
const& L,
60 Eigen::DenseBase<TDerivedU>
const& U,
61 Index maxPointsInLeaf = 8);
73 template <
class TDerivedL,
class TDerivedU>
75 Eigen::DenseBase<TDerivedL>
const& L,
76 Eigen::DenseBase<TDerivedU>
const& U,
77 Index maxPointsInLeaf = 8);
93 template <
class TDerivedL,
class TDerivedU>
94 void Update(Eigen::DenseBase<TDerivedL>
const& L, Eigen::DenseBase<TDerivedU>
const& U);
106 template <
class FNodeOverlaps,
class FObjectOverlaps,
class FOnOverlap>
109 FNodeOverlaps fNodeOverlaps,
110 FObjectOverlaps fObjectOverlaps,
111 FOnOverlap fOnOverlap)
127 template <
class FDistanceToNode,
class FDistanceToObject,
class FOnNearestNeighbour>
129 FDistanceToNode fDistanceToNode,
130 FDistanceToObject fDistanceToObject,
131 FOnNearestNeighbour fOnNearestNeighbour,
132 Scalar radius = std::numeric_limits<Scalar>::max(),
147 template <
class FDistanceToNode,
class FDistanceToObject,
class FOnNearestNeighbour>
149 FDistanceToNode fDistanceToNode,
150 FDistanceToObject fDistanceToObject,
151 FOnNearestNeighbour fOnNearestNeighbour,
153 Scalar radius = std::numeric_limits<Scalar>::max())
const;
162 template <
class FObjectsOverlap,
class FOnSelfOverlap>
163 void SelfOverlaps(FObjectsOverlap fObjectsOverlap, FOnSelfOverlap fOnSelfOverlap)
const;
175 template <
class FObjectsOverlap,
class FOnOverlap>
177 Overlaps(
SelfType const& rhs, FObjectsOverlap fObjectsOverlap, FOnOverlap fOnOverlap)
const;
201 auto Lower(
Index node)
const {
return IB.col(node).template head<kDims>(); }
208 auto Upper(
Index node)
const {
return IB.col(node).template tail<kDims>(); }
220template <
class TDerivedL,
class TDerivedU>
221inline AabbKdTreeHierarchy<Dims>::AabbKdTreeHierarchy(
222 Eigen::DenseBase<TDerivedL>
const& L,
223 Eigen::DenseBase<TDerivedU>
const& U,
224 Index maxPointsInLeaf)
230template <
class TDerivedL,
class TDerivedU>
232 Eigen::DenseBase<TDerivedL>
const& L,
233 Eigen::DenseBase<TDerivedU>
const& U,
234 Index maxPointsInLeaf)
236 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.Construct");
238 tree.Construct(P, maxPointsInLeaf);
239 auto const nNodes =
static_cast<Index>(tree.Nodes().size());
240 IB.resize(2 *
kDims, nNodes);
241 IB.template topRows<kDims>().setConstant(std::numeric_limits<Scalar>::max());
242 IB.template bottomRows<kDims>().setConstant(std::numeric_limits<Scalar>::lowest());
246template <
class TDerivedL,
class TDerivedU>
248 Eigen::DenseBase<TDerivedL>
const& L,
249 Eigen::DenseBase<TDerivedU>
const& U)
251 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.Update");
252 KdTreeNode const* nodes = tree.Nodes().data();
259 auto inds = perm(Eigen::seqN(node.
begin, node.
n));
260 IB.col(n).template head<kDims>() = L(Eigen::placeholders::all, inds).rowwise().
262 IB.col(n).template tail<kDims>() = U(Eigen::placeholders::all, inds).rowwise().
268 auto nbox = IB.col(n);
269 auto lbox = IB.col(node.
Left());
270 auto rbox = IB.col(node.
Right());
271 nbox.template head<kDims>() = lbox.template head<kDims>().cwiseMin(
272 rbox.template head<kDims>());
273 nbox.template tail<kDims>() = lbox.template tail<kDims>().cwiseMax(
274 rbox.template tail<kDims>());
278 if constexpr (c == 0)
279 return nodes[n].Left();
281 return nodes[n].
Right();
286template <
class FNodeOverlaps,
class FObjectOverlaps,
class FOnOverlap>
288 FNodeOverlaps fNodeOverlaps,
289 FObjectOverlaps fObjectOverlaps,
290 FOnOverlap fOnOverlap)
const
292 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.Overlaps");
293 KdTreeNode const* nodes = tree.Nodes().data();
297 if constexpr (c == 0)
298 return nodes[n].Left();
300 return nodes[n].
Right();
303 [&](
Index n) {
return nodes[n].
n; },
304 [&](
Index n,
Index i) {
return perm(nodes[n].begin + i); },
306 auto L = IB.col(n).template head<kDims>();
307 auto U = IB.col(n).template tail<kDims>();
308 using TDerivedL =
decltype(L);
309 using TDerivedU =
decltype(U);
310 return fNodeOverlaps.template operator()<TDerivedL, TDerivedU>(L, U);
317template <
class FDistanceToNode,
class FDistanceToObject,
class FOnNearestNeighbour>
319 FDistanceToNode fDistanceToNode,
320 FDistanceToObject fDistanceToObject,
321 FOnNearestNeighbour fOnNearestNeighbour,
325 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.NearestNeighbours");
326 KdTreeNode const* nodes = tree.Nodes().data();
330 if constexpr (c == 0)
331 return nodes[n].Left();
333 return nodes[n].
Right();
336 [&](
Index n) {
return nodes[n].
n; },
337 [&](
Index n,
Index i) {
return perm(nodes[n].begin + i); },
339 auto L = IB.col(n).template head<kDims>();
340 auto U = IB.col(n).template tail<kDims>();
341 using TDerivedL =
decltype(L);
342 using TDerivedU =
decltype(U);
343 return fDistanceToNode.template operator()<TDerivedL, TDerivedU>(L, U);
353template <
class FDistanceToNode,
class FDistanceToObject,
class FOnNearestNeighbour>
355 FDistanceToNode fDistanceToNode,
356 FDistanceToObject fDistanceToObject,
357 FOnNearestNeighbour fOnNearestNeighbour,
361 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.KNearestNeighbours");
362 KdTreeNode const* nodes = tree.Nodes().data();
366 if constexpr (c == 0)
367 return nodes[n].Left();
369 return nodes[n].
Right();
372 [&](
Index n) {
return nodes[n].
n; },
373 [&](
Index n,
Index i) {
return perm(nodes[n].begin + i); },
375 auto L = IB.col(n).template head<kDims>();
376 auto U = IB.col(n).template tail<kDims>();
377 using TDerivedL =
decltype(L);
378 using TDerivedU =
decltype(U);
379 return fDistanceToNode.template operator()<TDerivedL, TDerivedU>(L, U);
388template <
class FObjectsOverlap,
class FOnSelfOverlap>
390 FObjectsOverlap fObjectsOverlap,
391 FOnSelfOverlap fOnSelfOverlap)
const
393 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.SelfOverlaps");
394 KdTreeNode const* nodes = tree.Nodes().data();
398 if constexpr (c == 0)
399 return nodes[n].Left();
401 return nodes[n].
Right();
404 [&](
Index n) {
return nodes[n].
n; },
405 [&](
Index n,
Index i) {
return perm(nodes[n].begin + i); },
407 using math::linalg::mini::FromEigen;
408 auto L1 = IB.col(n1).template head<kDims>();
409 auto U1 = IB.col(n1).template tail<kDims>();
410 auto L2 = IB.col(n2).template head<kDims>();
411 auto U2 = IB.col(n2).template tail<kDims>();
423template <
class FObjectsOverlap,
class FOnOverlap>
426 FObjectsOverlap fObjectsOverlap,
427 FOnOverlap fOnOverlap)
const
429 PBAT_PROFILE_NAMED_SCOPE(
"pbat.geometry.AabbKdTreeHierarchy.Overlaps");
431 KdTreeNode const* nodes = tree.Nodes().data();
433 auto const fChildLhs = [&]<
auto c>(
Index n) ->
Index {
434 if constexpr (c == 0)
435 return nodes[n].Left();
437 return nodes[n].
Right();
439 auto const fIsLeafLhs = [&](
Index n) {
442 auto const fLeafSizeLhs = [&]([[maybe_unused]]
Index n) {
445 auto const fLeafObjectLhs = [&](
Index n, [[maybe_unused]]
Index i) {
446 return perm(nodes[n].begin + i);
451 auto const fChildRhs = [&]<
auto c>(
Index n) ->
Index {
452 if constexpr (c == 0)
453 return nodesRhs[n].Left();
455 return nodesRhs[n].
Right();
457 auto const fIsLeafRhs = [&](
Index n) {
458 return nodesRhs[n].
IsLeaf();
460 auto const fLeafSizeRhs = [&]([[maybe_unused]]
Index n) {
461 return nodesRhs[n].
n;
463 auto const fLeafObjectRhs = [&](
Index n, [[maybe_unused]]
Index i) {
464 return permRhs(nodesRhs[n].begin + i);
477 using math::linalg::mini::FromEigen;
478 auto L1 = IB.col(n1).template head<kDims>();
479 auto U1 = IB.col(n1).template tail<kDims>();
480 auto L2 = rhs.IB.col(n2).template head<kDims>();
481 auto U2 = rhs.IB.col(n2).template tail<kDims>();
This file contains the KdTree class.
Generic n-ary tree traversals.
This file contains functions to answer overlap queries.
Generic efficient spatial search query implementations.
auto Tree() const -> KdTree< kDims > const &
Get the underlying k-D tree.
Definition AabbKdTreeHierarchy.h:194
static auto constexpr kDims
Definition AabbKdTreeHierarchy.h:42
void Overlaps(FNodeOverlaps fNodeOverlaps, FObjectOverlaps fObjectOverlaps, FOnOverlap fOnOverlap) const
Find all objects that overlap with some user-defined query.
Definition AabbKdTreeHierarchy.h:287
auto InternalNodeBoundingBoxes() const -> Matrix< 2 *kDims, Eigen::Dynamic > const &
Get the internal node bounding boxes.
Definition AabbKdTreeHierarchy.h:185
AabbKdTreeHierarchy(Eigen::DenseBase< TDerivedL > const &L, Eigen::DenseBase< TDerivedU > const &U, Index maxPointsInLeaf=8)
Construct an Aabb Hierarchy from an input AABB matrices L, U.
Definition AabbKdTreeHierarchy.h:221
void Overlaps(SelfType const &rhs, FObjectsOverlap fObjectsOverlap, FOnOverlap fOnOverlap) const
Find all object pairs that overlap with another hierarchy.
Definition AabbKdTreeHierarchy.h:424
AabbKdTreeHierarchy< kDims > SelfType
Type of this template instantiation.
Definition AabbKdTreeHierarchy.h:43
void Construct(Eigen::DenseBase< TDerivedL > const &L, Eigen::DenseBase< TDerivedU > const &U, Index maxPointsInLeaf=8)
Construct an Aabb Hierarchy from an input AABB matrix B.
Definition AabbKdTreeHierarchy.h:231
void NearestNeighbours(FDistanceToNode fDistanceToNode, FDistanceToObject fDistanceToObject, FOnNearestNeighbour fOnNearestNeighbour, Scalar radius=std::numeric_limits< Scalar >::max(), Scalar eps=Scalar(0)) const
Find the nearest neighbour to some user-defined query. If there are multiple nearest neighbours,...
Definition AabbKdTreeHierarchy.h:318
void Update(Eigen::DenseBase< TDerivedL > const &L, Eigen::DenseBase< TDerivedU > const &U)
Recomputes k-D tree node AABBs given the object AABBs.
Definition AabbKdTreeHierarchy.h:247
void KNearestNeighbours(FDistanceToNode fDistanceToNode, FDistanceToObject fDistanceToObject, FOnNearestNeighbour fOnNearestNeighbour, Index K, Scalar radius=std::numeric_limits< Scalar >::max()) const
Find the K nearest neighbours to some user-defined query.
Definition AabbKdTreeHierarchy.h:354
auto Upper(Index node) const
Obtain the upper bound of the AABB of a node.
Definition AabbKdTreeHierarchy.h:208
auto Lower(Index node) const
Obtain the lower bound of the AABB of a node.
Definition AabbKdTreeHierarchy.h:201
void SelfOverlaps(FObjectsOverlap fObjectsOverlap, FOnSelfOverlap fOnSelfOverlap) const
Find all object pairs that overlap.
Definition AabbKdTreeHierarchy.h:389
KDTree class.
Definition KdTree.h:66
std::vector< KdTreeNode > const & Nodes() const
Returns the nodes of the k-D tree.
Definition KdTree.h:120
IndexVectorX const & Permutation() const
Returns the permutation of the points in the k-D tree.
Definition KdTree.h:129
PBAT_HOST_DEVICE void TraverseNAryTreePseudoPostOrder(FVisit fVisit, FChild fChild, TIndex root=0)
Post-order traversal over an n-ary tree starting from root.
Definition NAryTreeTraversal.h:84
PBAT_HOST_DEVICE bool AxisAlignedBoundingBoxes(TMatrixL1 const &L1, TMatrixU1 const &U1, TMatrixL2 const &L2, TMatrixU2 const &U2)
Tests for overlap between axis-aligned bounding box (L1,U1) and axis-aligned bounding box (L2,...
Definition OverlapQueries.h:608
Geometric queries, quantities and data structures.
Definition AabbKdTreeHierarchy.h:23
PBAT_HOST_DEVICE bool KNearestNeighbours(FChild fChild, FIsLeaf fIsLeaf, FLeafSize fLeafSize, FLeafObject fLeafObject, FDistanceLowerBound fLower, FDistance fDistance, FOnFound fOnFound, TIndex K, TScalar fUpper=std::numeric_limits< TScalar >::max(), TIndex root=0)
Find the (sorted) K objects with the smallest distances in a branch and bound tree rooted in root.
Definition SpatialSearch.h:1050
PBAT_HOST_DEVICE bool DfsAllNearestNeighbours(FChild fChild, FIsLeaf fIsLeaf, FLeafSize fLeafSize, FLeafObject fLeafObject, FDistanceLowerBound fLower, FDistance fDistance, FOnFound fOnFound, bool bUseBestFirstSearch=false, TScalar fUpper=std::numeric_limits< TScalar >::max(), TScalar eps=TScalar(0), TIndex root=0)
Find distance minimizing objects in branch and bound tree rooted in root.
Definition SpatialSearch.h:763
PBAT_HOST_DEVICE bool SelfOverlaps(FChild fChild, FIsLeaf fIsLeaf, FLeafSize fLeafSize, FLeafObject fLeafObject, FNodesOverlap fNodesOverlap, FObjectsOverlap fObjectsOverlap, FOnFound fOnFound, TIndex root=0)
Compute overlapping nodes from a branch and bound tree rooted in root.
Definition SpatialSearch.h:612
PBAT_HOST_DEVICE bool Overlaps(FChild fChild, FIsLeaf fIsLeaf, FLeafSize fLeafSize, FLeafObject fLeafObject, FNodeOverlap fNodeOverlaps, FObjectOverlap fObjectOverlaps, FOnFound fOnFound, TIndex root=0)
Find all nodes in a branch and bound tree that overlap with a given object.
Definition SpatialSearch.h:438
Eigen::Vector< Index, Eigen::Dynamic > IndexVectorX
Dynamic-size index vector type.
Definition Aliases.h:49
std::ptrdiff_t Index
Index type.
Definition Aliases.h:17
double Scalar
Scalar type.
Definition Aliases.h:18
Eigen::Matrix< Scalar, Rows, Cols > Matrix
Fixed-size matrix type.
Definition Aliases.h:31
Profiling utilities for the Physics-Based Animation Toolkit (PBAT)
Node of a KDTree.
Definition KdTree.h:31
Index begin
Index to first point encapsulated in this node's AABB in the permutation list.
Definition KdTree.h:33
bool IsLeaf() const
Returns true if this node is a leaf node, false otherwise.
Definition KdTree.h:42
Index n
Definition KdTree.h:34
auto Right() const
Returns right child node.
Definition KdTree.h:57
auto Left() const
Returns left child node.
Definition KdTree.h:52