Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions include/geode/geometry/aabb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,29 @@ namespace geode
const InfiniteLine< dimension >& line,
EvalIntersection& action ) const;

/*!
* @brief Computes the intersections between any object (for which
* intersection against an arbitrary axis-aligned bounding box can be
* detected efficiently) and all element boxes.
* @param[in] box_filter The functor to run to determine whether a box
* is intersected by the searched object or not. The box may correspond
* either to an internal tree node or to a tree element.
* @param[in] action The functor to run when a tree element box is
* intersected by the search object.
* @tparam EvalBox this functor should have an operator() defined like
* this: bool operator( const BoundingBox<dimension> & ) ;
* @tparam EvalIntersection this functor should have an operator()
* defined like this:
* bool operator()( index_t cur_element_box ) ;
* @note the operator define what to do with the box \p cur_element_box
* if it is intersected by the searched object.
* @note The returned boolean indicates if the search should stop or
* continue. Return true to stop the search, false to continue.
*/
template < class EvalBox, class EvalIntersection >
void compute_generic_element_bbox_intersections(
EvalBox& box_filter, EvalIntersection& action ) const;

/*!
* @brief Computes the intersections between a given Segment and
* all element boxes.
Expand Down
167 changes: 36 additions & 131 deletions include/geode/geometry/detail/aabb_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,104 +260,6 @@ namespace geode
}
}

template < typename ACTION >
bool bbox_intersect_recursive( const BoundingBox< dimension >& box,
index_t node_index,
index_t element_begin,
index_t element_end,
index_t depth,
ACTION& action ) const

{
OPENGEODE_ASSERT(
node_index < tree_.size(), "Node out of tree range" );
OPENGEODE_ASSERT( element_begin != element_end,
"No iteration allowed start == end" );

// Prune sub-tree that does not have intersection
if( !box.intersects( node( node_index ) ) )
{
return false;
}

if( is_leaf( element_begin, element_end ) )
{
return action( mapping_morton( element_begin ) );
}

const auto it = get_recursive_iterators(
node_index, element_begin, element_end );
if( depth > async_depth_ )
{
if( bbox_intersect_recursive( box, it.child_left, element_begin,
it.element_middle, depth + 1, action ) )
{
return true;
}
return bbox_intersect_recursive( box, it.child_right,
it.element_middle, element_end, depth + 1, action );
}
auto task = async::local_spawn( [&] {
return bbox_intersect_recursive( box, it.child_left,
element_begin, it.element_middle, depth + 1, action );
} );
if( bbox_intersect_recursive( box, it.child_right,
it.element_middle, element_end, depth + 1, action ) )
{
return true;
}
return task.get();
}

template < typename ACTION >
bool triangle_intersect_recursive(
const Triangle< dimension >& triangle,
index_t node_index,
index_t element_begin,
index_t element_end,
index_t depth,
ACTION& action ) const
{
OPENGEODE_ASSERT(
node_index < tree_.size(), "Node out of tree range" );
OPENGEODE_ASSERT( element_begin != element_end,
"No iteration allowed start == end" );

// Prune sub-tree that does not have intersection
if( !node( node_index ).intersects( triangle ) )
{
return false;
}

if( is_leaf( element_begin, element_end ) )
{
return action( mapping_morton( element_begin ) );
}

const auto it = get_recursive_iterators(
node_index, element_begin, element_end );
if( depth > async_depth_ )
{
if( triangle_intersect_recursive( triangle, it.child_left,
element_begin, it.element_middle, depth + 1, action ) )
{
return true;
}
return triangle_intersect_recursive( triangle, it.child_right,
it.element_middle, element_end, depth + 1, action );
}
auto task = async::local_spawn( [&] {
return triangle_intersect_recursive( triangle, it.child_left,
element_begin, it.element_middle, depth + 1, action );
} );
if( triangle_intersect_recursive( triangle, it.child_right,
it.element_middle, element_end, depth + 1, action ) )
{
return true;
}
return task.get();
}

template < typename ACTION >
bool self_intersect_recursive( index_t node_index1,
index_t element_begin1,
Expand Down Expand Up @@ -523,8 +425,8 @@ namespace geode
return task.get();
}

template < typename Line, typename ACTION >
bool line_intersect_recursive( const Line& line,
template < typename BOX_FILTER, typename ACTION >
bool generic_intersect_recursive( BOX_FILTER& box_filter,
index_t node_index,
index_t element_begin,
index_t element_end,
Expand All @@ -537,7 +439,7 @@ namespace geode
"No iteration allowed start == end" );

// Prune sub-tree that does not have intersection
if( !node( node_index ).intersects( line ) )
if( !box_filter( node( node_index ) ) )
{
return false;
}
Expand All @@ -551,19 +453,19 @@ namespace geode
node_index, element_begin, element_end );
if( depth > async_depth_ )
{
if( line_intersect_recursive( line, it.child_left,
if( generic_intersect_recursive( box_filter, it.child_left,
element_begin, it.element_middle, depth + 1, action ) )
{
return true;
}
return line_intersect_recursive( line, it.child_right,
return generic_intersect_recursive( box_filter, it.child_right,
it.element_middle, element_end, depth + 1, action );
}
auto task = async::local_spawn( [&] {
return line_intersect_recursive( line, it.child_left,
return generic_intersect_recursive( box_filter, it.child_left,
element_begin, it.element_middle, depth + 1, action );
} );
if( line_intersect_recursive( line, it.child_right,
if( generic_intersect_recursive( box_filter, it.child_right,
it.element_middle, element_end, depth + 1, action ) )
{
return true;
Expand Down Expand Up @@ -669,12 +571,10 @@ namespace geode
void AABBTree< dimension >::compute_bbox_element_bbox_intersections(
const BoundingBox< dimension >& box, EvalIntersection& action ) const
{
if( nb_bboxes() == 0 )
{
return;
}
impl_->bbox_intersect_recursive(
box, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
auto box_filter = [&box]( const BoundingBox< dimension >& inner_box ) {
return inner_box.intersects( box );
};
compute_generic_element_bbox_intersections( box_filter, action );
}

template < index_t dimension >
Expand Down Expand Up @@ -709,50 +609,55 @@ namespace geode
void AABBTree< dimension >::compute_ray_element_bbox_intersections(
const Ray< dimension >& ray, EvalIntersection& action ) const
{
if( nb_bboxes() == 0 )
{
return;
}
impl_->line_intersect_recursive(
ray, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
auto box_filter = [&ray]( const BoundingBox< dimension >& box ) {
return box.intersects( ray );
};
compute_generic_element_bbox_intersections( box_filter, action );
}

template < index_t dimension >
template < class EvalIntersection >
void AABBTree< dimension >::compute_line_element_bbox_intersections(
const InfiniteLine< dimension >& line, EvalIntersection& action ) const
{
auto box_filter = [&line]( const BoundingBox< dimension >& box ) {
return box.intersects( line );
};
compute_generic_element_bbox_intersections( box_filter, action );
}

template < index_t dimension >
template < class EvalBox, class EvalIntersection >
void AABBTree< dimension >::compute_generic_element_bbox_intersections(
EvalBox& box_filter, EvalIntersection& action ) const
{
if( nb_bboxes() == 0 )
{
return;
}
impl_->line_intersect_recursive(
line, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
impl_->generic_intersect_recursive(
box_filter, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
}

template < index_t dimension >
template < class EvalIntersection >
void AABBTree< dimension >::compute_triangle_element_bbox_intersections(
const Triangle< dimension >& triangle, EvalIntersection& action ) const
{
if( nb_bboxes() == 0 )
{
return;
}
impl_->triangle_intersect_recursive(
triangle, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
auto box_filter = [&triangle]( const BoundingBox< dimension >& box ) {
return box.intersects( triangle );
};
compute_generic_element_bbox_intersections( box_filter, action );
}

template < index_t dimension >
template < class EvalIntersection >
void AABBTree< dimension >::compute_segment_element_bbox_intersections(
const Segment< dimension >& segment, EvalIntersection& action ) const
{
if( nb_bboxes() == 0 )
{
return;
}
impl_->line_intersect_recursive(
segment, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action );
auto box_filter = [&segment]( const BoundingBox< dimension >& box ) {
return box.intersects( segment );
};
compute_generic_element_bbox_intersections( box_filter, action );
}
} // namespace geode
Loading