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
17 changes: 17 additions & 0 deletions include/geode/geometry/aabb.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,23 @@ namespace geode
void compute_ray_element_bbox_intersections(
const Ray< dimension >& ray, EvalIntersection& action ) const;

/*!
* @brief Computes the intersections between a given infinite line and
* all element boxes.
* @param[in] line The line to test.
* @param[in] action The functor to run when a box is intersected by the
* line.
* @tparam EvalIntersection this functor should have an operator()
* defined like this:
* void 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 \p line.
*/
template < class EvalIntersection >
void compute_line_element_bbox_intersections(
const InfiniteLine< dimension >& line,
EvalIntersection& action ) const;

private:
IMPLEMENTATION_MEMBER( impl_ );
};
Expand Down
35 changes: 33 additions & 2 deletions include/geode/geometry/basic_objects/infinite_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace geode
{
FORWARD_DECLARATION_DIMENSION_CLASS( OwnerInfiniteLine );
FORWARD_DECLARATION_DIMENSION_CLASS( OwnerRay );
FORWARD_DECLARATION_DIMENSION_CLASS( Point );
template < typename PointType, index_t dimension >
class GenericSegment;
Expand Down Expand Up @@ -64,6 +65,7 @@ namespace geode

protected:
GenericInfiniteLine( const OwnerInfiniteLine< dimension >& other );
GenericInfiniteLine( const OwnerRay< dimension >& other );

private:
PointType origin_;
Expand All @@ -89,8 +91,22 @@ namespace geode
OwnerInfiniteLine< dimension >&& other );
};
ALIAS_1D_AND_2D_AND_3D( OwnerInfiniteLine );

template < index_t dimension >
using OwnerRay = OwnerInfiniteLine< dimension >;
class OwnerRay : public GenericInfiniteLine< Point< dimension >, dimension >
{
using Base = GenericInfiniteLine< Point< dimension >, dimension >;

public:
explicit OwnerRay( const Vector< dimension >& direction,
const Point< dimension >& origin );

OwnerRay( const Segment< dimension >& segment );
OwnerRay( const OwnerRay< dimension >& other );
OwnerRay< dimension >& operator=( const OwnerRay< dimension >& other );
OwnerRay( OwnerRay< dimension >&& other );
OwnerRay< dimension >& operator=( OwnerRay< dimension >&& other );
};
ALIAS_1D_AND_2D_AND_3D( OwnerRay );

template < index_t dimension >
Expand All @@ -113,7 +129,22 @@ namespace geode
InfiniteLine< dimension >&& other );
};
ALIAS_1D_AND_2D_AND_3D( InfiniteLine );

template < index_t dimension >
using Ray = InfiniteLine< dimension >;
class Ray : public GenericInfiniteLine< RefPoint< dimension >, dimension >
{
using Base = GenericInfiniteLine< RefPoint< dimension >, dimension >;

public:
Ray( const Vector< dimension >& direction,
const Point< dimension >& origin );
Ray( const Segment< dimension >& segment );

Ray( const Ray< dimension >& other );
Ray( const OwnerRay< dimension >& other );
Ray< dimension >& operator=( const Ray< dimension >& other );
Ray( Ray< dimension >&& other );
Ray< dimension >& operator=( Ray< dimension >&& other );
};
ALIAS_1D_AND_2D_AND_3D( Ray );
} // namespace geode
2 changes: 2 additions & 0 deletions include/geode/geometry/bounding_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ namespace geode

bool intersects( const Ray< dimension >& ray ) const;

bool intersects( const InfiniteLine< dimension >& line ) const;

/*!
* Returns the distance between the point and the box.
* If the point is inside the box, the distance is negative.
Expand Down
79 changes: 45 additions & 34 deletions include/geode/geometry/detail/aabb_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ namespace geode
index_t element_end,
const ACTION& action ) const;

template < class ACTION >
template < typename ACTION >
void bbox_intersect_recursive( const BoundingBox< dimension >& box,
index_t node_index,
index_t element_begin,
index_t element_end,
ACTION& action ) const;

template < class ACTION >
template < typename ACTION >
void self_intersect_recursive( index_t node_index1,
index_t element_begin1,
index_t element_end1,
Expand All @@ -114,7 +114,7 @@ namespace geode
index_t element_end2,
ACTION& action ) const;

template < class ACTION >
template < typename ACTION >
void other_intersect_recursive( index_t node_index1,
index_t element_begin1,
index_t element_end1,
Expand All @@ -124,8 +124,8 @@ namespace geode
index_t element_end2,
ACTION& action ) const;

template < class ACTION >
void ray_intersect_recursive( const Ray< dimension >& ray,
template < typename Line, typename ACTION >
void line_intersect_recursive( const Line& line,
index_t node_index,
index_t element_begin,
index_t element_end,
Expand Down Expand Up @@ -209,10 +209,23 @@ namespace geode
{
return;
}
impl_->ray_intersect_recursive(
impl_->line_intersect_recursive(
ray, Impl::ROOT_INDEX, 0, nb_bboxes(), action );
}

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

template < index_t dimension >
template < typename ACTION >
void AABBTree< dimension >::Impl::closest_element_box_recursive(
Expand Down Expand Up @@ -259,13 +272,13 @@ namespace geode
{
if( distance_left < distance )
{
closest_element_box_recursive< ACTION >( query, nearest_box,
closest_element_box_recursive( query, nearest_box,
nearest_point, distance, it.child_left, box_begin,
it.middle_box, action );
}
if( distance_right < distance )
{
closest_element_box_recursive< ACTION >( query, nearest_box,
closest_element_box_recursive( query, nearest_box,
nearest_point, distance, it.child_right, it.middle_box,
box_end, action );
}
Expand All @@ -274,13 +287,13 @@ namespace geode
{
if( distance_right < distance )
{
closest_element_box_recursive< ACTION >( query, nearest_box,
closest_element_box_recursive( query, nearest_box,
nearest_point, distance, it.child_right, it.middle_box,
box_end, action );
}
if( distance_left < distance )
{
closest_element_box_recursive< ACTION >( query, nearest_box,
closest_element_box_recursive( query, nearest_box,
nearest_point, distance, it.child_left, box_begin,
it.middle_box, action );
}
Expand Down Expand Up @@ -314,14 +327,14 @@ namespace geode

const auto it =
get_recursive_iterators( node_index, element_begin, element_end );
bbox_intersect_recursive< ACTION >(
bbox_intersect_recursive(
box, it.child_left, element_begin, it.middle_box, action );
bbox_intersect_recursive< ACTION >(
bbox_intersect_recursive(
box, it.child_right, it.middle_box, element_end, action );
}

template < index_t dimension >
template < class ACTION >
template < typename ACTION >
void AABBTree< dimension >::Impl::self_intersect_recursive(
index_t node_index1,
index_t element_begin1,
Expand Down Expand Up @@ -372,28 +385,26 @@ namespace geode
{
const auto it = get_recursive_iterators(
node_index2, element_begin2, element_end2 );
self_intersect_recursive< ACTION >( node_index1, element_begin1,
element_end1, it.child_left, element_begin2, it.middle_box,
action );
self_intersect_recursive< ACTION >( node_index1, element_begin1,
element_end1, it.child_right, it.middle_box, element_end2,
action );
self_intersect_recursive( node_index1, element_begin1, element_end1,
it.child_left, element_begin2, it.middle_box, action );
self_intersect_recursive( node_index1, element_begin1, element_end1,
it.child_right, it.middle_box, element_end2, action );
}
else
{
const auto it = get_recursive_iterators(
node_index1, element_begin1, element_end1 );
self_intersect_recursive< ACTION >( it.child_left, element_begin1,
self_intersect_recursive( it.child_left, element_begin1,
it.middle_box, node_index2, element_begin2, element_end2,
action );
self_intersect_recursive< ACTION >( it.child_right, it.middle_box,
self_intersect_recursive( it.child_right, it.middle_box,
element_end1, node_index2, element_begin2, element_end2,
action );
}
}

template < index_t dimension >
template < class ACTION >
template < typename ACTION >
void AABBTree< dimension >::Impl::other_intersect_recursive(
index_t node_index1,
index_t element_begin1,
Expand Down Expand Up @@ -433,30 +444,30 @@ namespace geode
{
const auto it = get_recursive_iterators(
node_index2, element_begin2, element_end2 );
other_intersect_recursive< ACTION >( node_index1, element_begin1,
other_intersect_recursive( node_index1, element_begin1,
element_end1, other_tree, it.child_left, element_begin2,
it.middle_box, action );
other_intersect_recursive< ACTION >( node_index1, element_begin1,
other_intersect_recursive( node_index1, element_begin1,
element_end1, other_tree, it.child_right, it.middle_box,
element_end2, action );
}
else
{
const auto it = get_recursive_iterators(
node_index1, element_begin1, element_end1 );
other_intersect_recursive< ACTION >( it.child_left, element_begin1,
other_intersect_recursive( it.child_left, element_begin1,
it.middle_box, other_tree, node_index2, element_begin2,
element_end2, action );
other_intersect_recursive< ACTION >( it.child_right, it.middle_box,
other_intersect_recursive( it.child_right, it.middle_box,
element_end1, other_tree, node_index2, element_begin2,
element_end2, action );
}
}

template < index_t dimension >
template < typename ACTION >
void AABBTree< dimension >::Impl::ray_intersect_recursive(
const Ray< dimension >& ray,
template < typename Line, typename ACTION >
void AABBTree< dimension >::Impl::line_intersect_recursive(
const Line& line,
index_t node_index,
index_t element_begin,
index_t element_end,
Expand All @@ -467,7 +478,7 @@ namespace geode
element_begin != element_end, "No iteration allowed start == end" );

// Prune sub-tree that does not have intersection
if( !node( node_index ).intersects( ray ) )
if( !node( node_index ).intersects( line ) )
{
return;
}
Expand All @@ -480,9 +491,9 @@ namespace geode

const auto it =
get_recursive_iterators( node_index, element_begin, element_end );
ray_intersect_recursive< ACTION >(
ray, it.child_left, element_begin, it.middle_box, action );
ray_intersect_recursive< ACTION >(
ray, it.child_right, it.middle_box, element_end, action );
line_intersect_recursive(
line, it.child_left, element_begin, it.middle_box, action );
line_intersect_recursive(
line, it.child_right, it.middle_box, element_end, action );
}
} // namespace geode
Loading