Skip to content

Commit 78f88bd

Browse files
yo35BotellaA
authored andcommitted
feat(AABBTree): generic intersection search method
1 parent 7f9fde0 commit 78f88bd

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

include/geode/geometry/aabb.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,29 @@ namespace geode
195195
const InfiniteLine< dimension >& line,
196196
EvalIntersection& action ) const;
197197

198+
/*!
199+
* @brief Computes the intersections between any object (for which
200+
* intersection against an arbitrary axis-aligned bounding box can be
201+
* detected efficiently) and all element boxes.
202+
* @param[in] boxFilter The functor to run to determine whether a box is
203+
* intersected by the searched object or not. The box may correspond
204+
* either to an internal tree node or to a tree element.
205+
* @param[in] action The functor to run when a tree element box is
206+
* intersected by the search object.
207+
* @tparam EvalBox this functor should have an operator() defined like
208+
* this: bool operator( const BoundingBox<dimension> & ) ;
209+
* @tparam EvalIntersection this functor should have an operator()
210+
* defined like this:
211+
* bool operator()( index_t cur_element_box ) ;
212+
* @note the operator define what to do with the box \p cur_element_box
213+
* if it is intersected by the searched object.
214+
* @note The returned boolean indicates if the search should stop or
215+
* continue. Return true to stop the search, false to continue.
216+
*/
217+
template < class EvalBox, class EvalIntersection >
218+
void compute_generic_element_bbox_intersections(
219+
EvalBox& boxFilter, EvalIntersection& action ) const;
220+
198221
/*!
199222
* @brief Computes the intersections between a given Segment and
200223
* all element boxes.

include/geode/geometry/detail/aabb_impl.hpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,54 @@ namespace geode
571571
return task.get();
572572
}
573573

574+
template < typename BOX_FILTER, typename ACTION >
575+
bool generic_intersect_recursive( BOX_FILTER& boxFilter,
576+
index_t node_index,
577+
index_t element_begin,
578+
index_t element_end,
579+
index_t depth,
580+
ACTION& action ) const
581+
{
582+
OPENGEODE_ASSERT(
583+
node_index < tree_.size(), "Node out of tree range" );
584+
OPENGEODE_ASSERT( element_begin != element_end,
585+
"No iteration allowed start == end" );
586+
587+
// Prune sub-tree that does not have intersection
588+
if( !boxFilter( node( node_index ) ) )
589+
{
590+
return false;
591+
}
592+
593+
if( is_leaf( element_begin, element_end ) )
594+
{
595+
return action( mapping_morton( element_begin ) );
596+
}
597+
598+
const auto it = get_recursive_iterators(
599+
node_index, element_begin, element_end );
600+
if( depth > async_depth_ )
601+
{
602+
if( generic_intersect_recursive( boxFilter, it.child_left,
603+
element_begin, it.element_middle, depth + 1, action ) )
604+
{
605+
return true;
606+
}
607+
return generic_intersect_recursive( boxFilter, it.child_right,
608+
it.element_middle, element_end, depth + 1, action );
609+
}
610+
auto task = async::local_spawn( [&] {
611+
return generic_intersect_recursive( boxFilter, it.child_left,
612+
element_begin, it.element_middle, depth + 1, action );
613+
} );
614+
if( generic_intersect_recursive( boxFilter, it.child_right,
615+
it.element_middle, element_end, depth + 1, action ) )
616+
{
617+
return true;
618+
}
619+
return task.get();
620+
}
621+
574622
[[nodiscard]] index_t closest_element_box_hint(
575623
const Point< dimension >& query ) const
576624
{
@@ -730,6 +778,19 @@ namespace geode
730778
line, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
731779
}
732780

781+
template < index_t dimension >
782+
template < class EvalBox, class EvalIntersection >
783+
void AABBTree< dimension >::compute_generic_element_bbox_intersections(
784+
EvalBox& boxFilter, EvalIntersection& action ) const
785+
{
786+
if( nb_bboxes() == 0 )
787+
{
788+
return;
789+
}
790+
impl_->generic_intersect_recursive(
791+
boxFilter, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
792+
}
793+
733794
template < index_t dimension >
734795
template < class EvalIntersection >
735796
void AABBTree< dimension >::compute_triangle_element_bbox_intersections(

0 commit comments

Comments
 (0)