Lagrange
EmbreeRayCaster< ScalarType > Class Template Reference

A wrapper for Embree's raycasting API to compute ray intersections with (instances of) meshes. More...

#include <lagrange/raycasting/EmbreeRayCaster.h>

Public Types

using Scalar = ScalarType
 
using Transform = Eigen::Matrix< Scalar, 4, 4 >
 
using Point = Eigen::Matrix< Scalar, 3, 1 >
 
using Direction = Eigen::Matrix< Scalar, 3, 1 >
 
using Index = size_t
 
using ClosestPoint = ClosestPointResult< Scalar >
 
using TransformVector = std::vector< Transform >
 
using Point4 = Eigen::Matrix< Scalar, 4, 3 >
 
using Direction4 = Eigen::Matrix< Scalar, 4, 3 >
 
using Index4 = Eigen::Matrix< size_t, 4, 1 >
 
using Scalar4 = Eigen::Matrix< Scalar, 4, 1 >
 
using Mask4 = Eigen::Matrix< std::int32_t, 4, 1 >
 
using FloatData = std::vector< float >
 
using IntData = std::vector< unsigned >
 
using FilterFunction = std::function< void(const EmbreeRayCaster *obj, const Index *mesh_index, const Index *instance_index, const RTCFilterFunctionNArguments *args)>
 Interface for a hit filter function. More...
 

Public Member Functions

 EmbreeRayCaster (RTCSceneFlags scene_flags=RTC_SCENE_FLAG_DYNAMIC, RTCBuildQuality build_quality=RTC_BUILD_QUALITY_LOW)
 Constructor.
 
virtual ~EmbreeRayCaster ()
 Destructor.
 
 EmbreeRayCaster (const EmbreeRayCaster &)=delete
 
void operator= (const EmbreeRayCaster &)=delete
 
Index get_num_meshes () const
 Get the total number of meshes (not instances).
 
Index get_num_instances () const
 Get the total number of mesh instances.
 
Index get_num_instances (Index mesh_index) const
 Get the number of instances of a particular mesh.
 
template<typename MeshType >
std::shared_ptr< MeshTypeget_mesh (Index index) const
 Get the mesh with a given index. More...
 
Index get_mesh_for_instance (Index cumulative_instance_index) const
 Get the index of the mesh corresponding to a given instance, where the instances are indexed sequentially starting from the instances of the first mesh, then the instances of the second mesh, and so on. More...
 
template<typename MeshType >
Index add_mesh (std::shared_ptr< MeshType > mesh, const Transform &trans=Transform::Identity(), RTCBuildQuality build_quality=RTC_BUILD_QUALITY_MEDIUM)
 Add an instance of a mesh to the scene, with a given transformation. More...
 
template<typename MeshType >
Index add_meshes (std::shared_ptr< MeshType > mesh, const TransformVector &trans_vector, RTCBuildQuality build_quality=RTC_BUILD_QUALITY_MEDIUM)
 Add multiple instances of a single mesh to the scene, with given transformations. More...
 
template<typename MeshType >
void update_mesh (Index index, std::shared_ptr< MeshType > mesh, RTCBuildQuality build_quality=RTC_BUILD_QUALITY_MEDIUM)
 Update a particular mesh with a new mesh object. More...
 
void update_mesh_vertices (Index index)
 Update the object to reflect external changes to the vertices of a particular mesh which is already in the scene. More...
 
Transform get_transform (Index mesh_index, Index instance_index) const
 Get the transform applied to a given mesh instance.
 
void update_transformation (Index mesh_index, Index instance_index, const Transform &trans)
 Update the transform applied to a given mesh instance.
 
bool get_visibility (Index mesh_index, Index instance_index) const
 Get the visibility flag of a given mesh instance.
 
void update_visibility (Index mesh_index, Index instance_index, bool visible)
 Update the visibility of a given mesh index (true for visible, false for invisible).
 
void set_intersection_filter (Index mesh_index, FilterFunction filter)
 Set an intersection filter that is called for every hit on (every instance of) a mesh during an intersection query. More...
 
FilterFunction get_intersection_filter (Index mesh_index) const
 Get the intersection filter function currently bound to a given mesh. More...
 
void set_occlusion_filter (Index mesh_index, FilterFunction filter)
 Set an occlusion filter that is called for every hit on (every instance of) a mesh during an occlusion query. More...
 
FilterFunction get_occlusion_filter (Index mesh_index) const
 Get the occlusion filter function currently bound to a given mesh. More...
 
void commit_scene_changes ()
 Call rtcCommitScene() on the overall scene, if it has been marked as modified. More...
 
void ensure_no_errors () const
 Throw an exception if an Embree error has occurred.
 
uint32_t cast4 (uint32_t batch_size, const Point4 &origin, const Direction4 &direction, const Mask4 &mask, Index4 &mesh_index, Index4 &instance_index, Index4 &facet_index, Scalar4 &ray_depth, Point4 &barycentric_coord, Point4 &normal, const Scalar4 &tmin=Scalar4::Zero(), const Scalar4 &tmax=Scalar4::Constant(std::numeric_limits< Scalar >::infinity()))
 Cast a packet of up to 4 rays through the scene, returning full data of the closest intersections including normals and instance indices.
 
uint32_t cast4 (uint32_t batch_size, const Point4 &origin, const Direction4 &direction, const Mask4 &mask, Index4 &mesh_index, Index4 &facet_index, Scalar4 &ray_depth, Point4 &barycentric_coord, const Scalar4 &tmin=Scalar4::Zero(), const Scalar4 &tmax=Scalar4::Constant(std::numeric_limits< Scalar >::infinity()))
 Cast a packet of up to 4 rays through the scene, returning data of the closest intersections excluding normals and instance indices.
 
uint32_t cast4 (uint32_t batch_size, const Point4 &origin, const Direction4 &direction, const Mask4 &mask, const Scalar4 &tmin=Scalar4::Zero(), const Scalar4 &tmax=Scalar4::Constant(std::numeric_limits< Scalar >::infinity()))
 Cast a packet of up to 4 rays through the scene and check whether they hit anything or not.
 
bool cast (const Point &origin, const Direction &direction, Index &mesh_index, Index &instance_index, Index &facet_index, Scalar &ray_depth, Point &barycentric_coord, Point &normal, Scalar tmin=0, Scalar tmax=std::numeric_limits< Scalar >::infinity())
 Cast a single ray through the scene, returning full data of the closest intersection including the normal and the instance index.
 
bool cast (const Point &origin, const Direction &direction, Index &mesh_index, Index &facet_index, Scalar &ray_depth, Point &barycentric_coord, Scalar tmin=0, Scalar tmax=std::numeric_limits< Scalar >::infinity())
 Cast a single ray through the scene, returning data of the closest intersection excluding the normal and the instance index.
 
bool cast (const Point &origin, const Direction &direction, Scalar tmin=0, Scalar tmax=std::numeric_limits< Scalar >::infinity())
 Cast a single ray through the scene and check whether it hits anything or not.
 
ClosestPoint query_closest_point (const Point &p) const
 Use the underlying BVH to find the point closest to a query point.
 
Index add_raycasting_mesh (std::unique_ptr< RaycasterMesh > mesh, const Transform &trans=Transform::Identity(), RTCBuildQuality build_quality=RTC_BUILD_QUALITY_MEDIUM)
 Add raycasting utilities.
 
void update_raycasting_mesh (Index index, std::unique_ptr< RaycasterMesh > mesh, RTCBuildQuality build_quality=RTC_BUILD_QUALITY_MEDIUM)
 

Protected Member Functions

void release_scenes ()
 Release internal Embree scenes.
 
virtual RTCSceneFlags get_scene_flags () const
 Get the Embree scene flags.
 
virtual RTCBuildQuality get_scene_build_quality () const
 Get the Embree geometry build quality.
 
void update_internal ()
 Update all internal structures based on the current dirty flags.
 
void generate_scene ()
 Build the whole Embree scene from the specified meshes, instances, etc. More...
 
const float * extract_float_data (const RaycasterMesh &mesh)
 Get the vertex data of a mesh as an array of floats.
 
const unsigned * extract_int_data (const RaycasterMesh &mesh)
 Get the index data of a mesh as an array of integers.
 
void ensure_no_errors_internal () const
 

Protected Attributes

RTCSceneFlags m_scene_flags
 
RTCBuildQuality m_build_quality
 
RTCDevice m_device
 
RTCScene m_embree_world_scene
 
bool m_need_rebuild
 
bool m_need_commit
 
std::vector< FloatData > m_float_data
 
std::vector< IntData > m_int_data
 
std::vector< std::unique_ptr< RaycasterMesh > > m_meshes
 
std::vector< RTCBuildQuality > m_mesh_build_qualities
 
std::vector< RTCScene > m_embree_mesh_scenes
 
std::vector< Index > m_mesh_vertex_counts
 
std::vector< FilterFunctionm_filters [2]
 
std::vector< Index > m_instance_index_ranges
 
std::vector< Index > m_instance_to_user_mesh
 
std::vector< Transform > m_transforms
 
std::vector< bool > m_visibility
 

Detailed Description

template<typename ScalarType>
class lagrange::raycasting::EmbreeRayCaster< ScalarType >

A wrapper for Embree's raycasting API to compute ray intersections with (instances of) meshes.

Supports intersection and occlusion queries on single rays and ray packets (currently only packets of size at most 4 are supported). Filters may be specified (per mesh, not per instance) to process each individual hit event during any of these queries.

Member Typedef Documentation

◆ FilterFunction

using FilterFunction = std::function<void( const EmbreeRayCaster* obj, const Index* mesh_index, const Index* instance_index, const RTCFilterFunctionNArguments* args)>

Interface for a hit filter function.

Most information in RTCFilterFunctionNArguments maps directly to elements of the EmbreeRayCaster class, but the mesh and instance IDs need special conversion. mesh_index is an array of args->N EmbreeRayCaster mesh indices, and instance_index is an array of args->N EmbreeRayCaster instance indices, one for each ray/hit. For the other elements of args, the mappings are:

facet_index <-- primID
ray_depth <-- tfar
barycentric_coord <-- [u, v, 1 - u - v]
normal <-- Ng

Member Function Documentation

◆ get_mesh()

std::shared_ptr< MeshType > get_mesh ( Index  index) const
inline

Get the mesh with a given index.

Requires the caller to know the original type of the mesh (MeshType) in advance.

◆ get_mesh_for_instance()

Index get_mesh_for_instance ( Index  cumulative_instance_index) const
inline

Get the index of the mesh corresponding to a given instance, where the instances are indexed sequentially starting from the instances of the first mesh, then the instances of the second mesh, and so on.

Use get_mesh() to map the returned index to an actual mesh.

Parameters
cumulative_instance_indexAn integer in the range 0 to get_num_instances() - 1 (both inclusive).

◆ add_mesh()

Index add_mesh ( std::shared_ptr< MeshType mesh,
const Transform &  trans = Transform::Identity(),
RTCBuildQuality  build_quality = RTC_BUILD_QUALITY_MEDIUM 
)
inline

Add an instance of a mesh to the scene, with a given transformation.

If another instance of the same mesh has been previously added to the scene, the two instances will NOT be considered to share the same mesh, but will be treated as separate instances of separate meshes. To add multiple instances of the same mesh, use add_meshes().

◆ add_meshes()

Index add_meshes ( std::shared_ptr< MeshType mesh,
const TransformVector &  trans_vector,
RTCBuildQuality  build_quality = RTC_BUILD_QUALITY_MEDIUM 
)
inline

Add multiple instances of a single mesh to the scene, with given transformations.

If another instance of the same mesh has been previously added to the scene, the new instances will NOT be considered to share the same mesh as the old instance, but will be treated as instances of a new mesh. Add all instances in a single add_meshes() call if you want to avoid this.

◆ update_mesh()

void update_mesh ( Index  index,
std::shared_ptr< MeshType mesh,
RTCBuildQuality  build_quality = RTC_BUILD_QUALITY_MEDIUM 
)
inline

Update a particular mesh with a new mesh object.

All its instances will be affected.

Note
If you have changed the vertices of a mesh already in the scene, and just want the object to reflect that, then call update_mesh_vertices() instead.

◆ update_mesh_vertices()

void update_mesh_vertices ( Index  index)
inline

Update the object to reflect external changes to the vertices of a particular mesh which is already in the scene.

All its instances will be affected. The number of vertices in the mesh, and their order in the vertex array, must not change.

◆ set_intersection_filter()

void set_intersection_filter ( Index  mesh_index,
FilterFunction  filter 
)
inline

Set an intersection filter that is called for every hit on (every instance of) a mesh during an intersection query.

The filter function must be callable as:

void filter(const EmbreeRayCaster* obj, const Index* mesh_index, const Index* instance_index,
const RTCFilterFunctionNArguments* args);
A wrapper for Embree's raycasting API to compute ray intersections with (instances of) meshes.
Definition: EmbreeRayCaster.h:47

It functions exactly like Embree's rtcSetGeometryIntersectFilterFunction, except it also receives a handle to this object, and mesh and instance indices specific to this object. A null filter disables intersection filtering for this mesh.

Note
Embree dictates that filters can be associated only with meshes (raw geometries), not instances.

◆ get_intersection_filter()

FilterFunction get_intersection_filter ( Index  mesh_index) const
inline

Get the intersection filter function currently bound to a given mesh.

Note
Embree dictates that filters can be associated only with meshes (raw geometries), not instances.

◆ set_occlusion_filter()

void set_occlusion_filter ( Index  mesh_index,
FilterFunction  filter 
)
inline

Set an occlusion filter that is called for every hit on (every instance of) a mesh during an occlusion query.

The filter function must be callable as:

void filter(const EmbreeRayCaster* obj, const Index* mesh_index, const Index* instance_index,
const RTCFilterFunctionNArguments* args);

It functions exactly like Embree's rtcSetGeometryOccludedFilterFunction, except it also receives a handle to this object, and mesh and instance indices specific to this object. A null filter disables occlusion filtering for this mesh.

Note
Embree dictates that filters can be associated only with meshes (raw geometries), not instances.

◆ get_occlusion_filter()

FilterFunction get_occlusion_filter ( Index  mesh_index) const
inline

Get the occlusion filter function currently bound to a given mesh.

Note
Embree dictates that filters can be associated only with meshes (raw geometries), not instances.

◆ commit_scene_changes()

void commit_scene_changes ( )
inline

Call rtcCommitScene() on the overall scene, if it has been marked as modified.

Todo:
Now that this is automatically called by update_internal() based on a dirty flag, can we make this a protected/private function? That would break the API so maybe reserve it for a major version.

◆ generate_scene()

void generate_scene ( )
inlineprotected

Build the whole Embree scene from the specified meshes, instances, etc.

Todo:
Make the dirty flags more fine-grained so that only the changed meshes are re-sent to Embree.

The documentation for this class was generated from the following file: