DHART
Loading...
Searching...
No Matches
RayTracer

Classes

struct  RayResult
 The result of casting a ray at an object. Contains distance to the hitpoint and the ID of the mesh. More...
 

Functions

C_INTERFACE CreateRaytracer (HF::Geometry::MeshInfo< float > *mesh, HF::RayTracer::EmbreeRayTracer **out_raytracer, bool use_precise)
 Create a new raytracer using several meshes. More...
 
C_INTERFACE CreateRaytracerMultiMesh (HF::Geometry::MeshInfo< float > **meshes, int num_meshes, HF::RayTracer::EmbreeRayTracer **out_raytracer, bool use_precise)
 Create a new raytracer using several meshes. More...
 
C_INTERFACE AddMesh (HF::RayTracer::EmbreeRayTracer *ERT, HF::Geometry::MeshInfo< float > *MI)
 Add a new mesh to a raytracer. More...
 
C_INTERFACE AddMeshes (HF::RayTracer::EmbreeRayTracer *ERT, HF::Geometry::MeshInfo< float > **MI, int number_of_meshes)
 Add a new mesh to a raytracer. More...
 
C_INTERFACE DestroyRayTracer (HF::RayTracer::EmbreeRayTracer *rt_to_destroy)
 Delete an existing raytracer. More...
 
C_INTERFACE CastRaysDistance (HF::RayTracer::EmbreeRayTracer *ert, float *origins, int num_origins, float *directions, int num_directions, std::vector< RayResult > **out_results, RayResult **results_data)
 Cast rays for each node in origins/directions as ordered pairs and get distance back as a result. More...
 
C_INTERFACE CastSingleRayDistance (HF::RayTracer::EmbreeRayTracer *ert, const float *origin, const float *direction, const float max_distance, float *out_distance, int *out_meshid)
 Cast a single ray and get the distance to its hit and the mesh ID if it hit anything. If it missed, then distance and meshid will both be -1. More...
 
C_INTERFACE CastRay (HF::RayTracer::EmbreeRayTracer *ert, float &x, float &y, float &z, float dx, float dy, float dz, float max_distance, bool &result)
 Cast a single ray from the raytracer and receive a point in return. More...
 
C_INTERFACE CastMultipleRays (HF::RayTracer::EmbreeRayTracer *ert, float *origins, const float *directions, int size, float max_distance, bool *result_array)
 Cast multiple rays at once in parallel and receive their hitpoints in return. The number of directions must be equal to the number of origins. More...
 
C_INTERFACE CastMultipleOriginsOneDirection (HF::RayTracer::EmbreeRayTracer *ert, float *origins, const float *direction, int size, float max_distance, bool *result_array)
 Cast rays from each origin point in the given direction. More...
 
C_INTERFACE CastMultipleDirectionsOneOrigin (HF::RayTracer::EmbreeRayTracer *ert, const float *origin, float *directions, int size, float max_distance, bool *result_array)
 Cast rays from a single origin point in multiple directions and get a the points where they intersected the geometry. More...
 
C_INTERFACE CastOcclusionRays (HF::RayTracer::EmbreeRayTracer *ert, const float *origins, const float *directions, int origin_size, int direction_size, float max_distance, bool *result_array)
 Cast one or more occlusion rays in parallel. More...
 
C_INTERFACE DestroyRayResultVector (std::vector< RayResult > *analysis)
 Destroy a vector of rayresults. More...
 
C_INTERFACE PreciseIntersection (HF::RayTracer::EmbreeRayTracer *RT, double x, double y, double z, double dx, double dy, double dz, double *out_distance)
 

Detailed Description

Perform efficient ray intersections using Intel's Embree Library.

Raytracer setup

Every example below will be assumed to begin with this body of code;
we will call it the 'setup':

First, begin by loading the .OBJ file:
Mesh setup (from objloader_C.h)

Then, create the BVH:

// Create BVH
// We now declare a pointer to EmbreeRayTracer, named bvh.
// Note that we pass the address of this pointer to CreateRaytracer.
//
// Note also that we pass the (vector<MeshInfo> *), loaded_obj, to CreateRaytracer -- by value.
// This is okay, because CreateRaytracer is not assigning loaded_obj any new addresses,
// it is only interested in accessing the pointee.
status = CreateRaytracer(loaded_obj, &bvh);
if (status != -1) {
std::cerr << "Error at CreateRaytracer, code: " << status << std::endl;
}
else {
std::cout << "CreateRaytracer created EmbreeRayTracer successfully into bvh at address " << bvh << ", code: " << status << std::endl;
}
C_INTERFACE CreateRaytracer(MeshInfo *mesh, EmbreeRayTracer **out_raytracer, bool use_precise)
Create a new raytracer using several meshes.
Definition: raytracer_C.cpp:15
A wrapper for Intel's Embree Library.

At this point, you are ready to use your BVH.
All examples below will assume you have already created a BVH from the .OBJ file provided.
(all examples below begin with the setup code described above)

Raytracer teardown

When you are finished with the BVH, you must then release its memory resources:

// destroy raytracer
status = DestroyRayTracer(bvh);
if (status != 1) {
std::cerr << "Error at DestroyRayTracer, code: " << status << std::endl;
}
C_INTERFACE DestroyRayTracer(HF::RayTracer::EmbreeRayTracer *rt_to_destroy)
Delete an existing raytracer.
Definition: raytracer_C.cpp:91

After destroying the BVH,
you must also do the same for the (vector<HF::Geometry::MeshInfo> *) used by LoadOBJ.
Mesh teardown (from objloader_C.h)

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019C4EA752E0, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019C4EA12820, code: 1

The client is responsible for releasing the memory for
the mesh (vector<HF::Geometry::MeshInfo> *) and the BVH (HF::RayTracer::EmbreeRayTracer *).

Every example for each function should be followed up by the 'teardown' code described above.

Function Documentation

◆ AddMesh()

C_INTERFACE AddMesh ( HF::RayTracer::EmbreeRayTracer ERT,
HF::Geometry::MeshInfo< float > *  MI 
)

#include <Cinterface/raytracer_C.h>

Add a new mesh to a raytracer.

Parameters
ERTraytracer to add the mesh to
MIMeshInfo to add to the raytracer. Will try to maintain IDs, however if there is a collision, then the MeshInfo will be updated to contain the ID assigned to it by the raytracer.
Returns
HF_STATUS::OK On completion

Definition at line 84 of file raytracer_C.cpp.

References HF::RayTracer::EmbreeRayTracer::AddMesh().

+ Here is the call graph for this function:

◆ AddMeshes()

C_INTERFACE AddMeshes ( HF::RayTracer::EmbreeRayTracer ERT,
HF::Geometry::MeshInfo< float > **  MI,
int  number_of_meshes 
)

#include <Cinterface/raytracer_C.h>

Add a new mesh to a raytracer.

Parameters
ERTraytracer toa dd the mesh to
MIMeshInfo to add to the raytracer. Will try to maintain IDs, however if there is a collision, then each MeshInfo will be updated to contain the ID assigned to it by the raytracer.
number_of_meshesNumber of meshes in MI.
Returns
HF_STATUS::OK On completion

Definition at line 71 of file raytracer_C.cpp.

References HF::RayTracer::EmbreeRayTracer::AddMesh().

+ Here is the call graph for this function:

◆ CastMultipleDirectionsOneOrigin()

C_INTERFACE CastMultipleDirectionsOneOrigin ( HF::RayTracer::EmbreeRayTracer ert,
const float *  origin,
float *  directions,
int  size,
float  max_distance,
bool *  result_array 
)

#include <Cinterface/raytracer_C.h>

Cast rays from a single origin point in multiple directions and get a the points where they intersected the geometry.

Parameters
ertA pointer to a valid embree raytracer.
originAn array of 3 floats representing the X, Y, and Z coordinates of the origin to cast from respectively
directionsA list of floats representing directions, with each 3 floats representing one direction. If a ray cast in a direction resulted in a hit, that direction will be overwritten to the hitpoint.
sizeNumber of points and directions, equal to the total number of floats in one array / 3
max_distanceMaximum distance a ray can travel and still hit a target
result_arrayOutput parameter conatining an ordered list of booleans set to true if the their rays hit, and false if their rays did not.
returnsHF_STATUS::OK on completion.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.
Define the vector components of the ray(s) that will be cast.

// Define point to start ray
// These are Cartesian coordinates.
const std::array<float, 3> p1 { 0.0f, 0.0f, 2.0f };
// Define directions to cast rays
// These are vector components, not Cartesian coordinates.
std::array<float, 9> dir { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, -3.0f };
const int size_dir = dir.size();
const int count_dir = size_dir / 3;

Define a maximum distance value, and a container to store the ray collision results.

const int max_distance = -1;
// If a given ray i hits a target (dir[i] is a vector extending from points[i]),
// results[i] will be set true. Otherwise, results[i] will be set false.
std::array<bool, count_dir> results;
// dir, and results will be mutated by CastMultipleDirectionsOneOrigin.
// if results[i] is true, representing a hit,
// dir[i], dir[i + 1], dir[i + 2] represents a hit point.
status = CastMultipleDirectionsOneOrigin(bvh, p1.data(), dir.data(), count_dir, max_distance, results.data());
if (status != 1) {
// Error!
std::cerr << "Error at CastMultipleDirectionsOneOrigin, code: " << status << std::endl;
}
C_INTERFACE CastMultipleDirectionsOneOrigin(EmbreeRayTracer *ert, const float *origin, float *directions, int size, float max_distance, bool *result_array)
Cast rays from a single origin point in multiple directions and get a the points where they intersect...

We can review the results by outputting the contents of the results container:

//
// Review results:
//
for (int i = 0, k = 0; i < count_dir; i++, k += 3) {
std::string label = results[i] ? "hit" : "miss";
std::cout << "result[" << i << "]: " << label << std::endl;
std::cout << "[" << dir[0] << ", " << dir[1] << ", " << dir[2]
<< "], direction [" << dir[k] << ", " << dir[k + 1] << ", " << dir[k + 2] << "]"
<< std::endl;
}

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019E906587A0, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019E86D22500, code: 1
>>> result[0]: hit
>>> [0, 0, 0], direction [0, 0, 0]
>>> result[1]: hit
>>> [0, 0, 0], direction [0, 0, 0]
>>> result[2]: hit
>>> [0, 0, 0], direction [0, 0, 1.19209e-07]

Definition at line 249 of file raytracer_C.cpp.

References ConvertRawFloatArrayToPoints(), HF::Exceptions::OK, and HF::RayTracer::EmbreeRayTracer::PointIntersections().

+ Here is the call graph for this function:

◆ CastMultipleOriginsOneDirection()

C_INTERFACE CastMultipleOriginsOneDirection ( HF::RayTracer::EmbreeRayTracer ert,
float *  origins,
const float *  direction,
int  size,
float  max_distance,
bool *  result_array 
)

#include <Cinterface/raytracer_C.h>

Cast rays from each origin point in the given direction.

Parameters
ertThe raytracer to cast each ray from.
originsA list of floats representing origin points, with each 3 floats representing one point.
directionAn array of 3 floats representing the X, Y, and Z coordinates respectively.
sizeNumber of points and directions, equal to the total number of floats in one array / 3.
max_distanceMaximum distance a ray can travel and still hit a target.
result_arrayOutput parameter conatining an ordered list of booleans set to true if the their rays hit, and false if their rays did not.
Returns
HF_STATUS::OK on completion.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.

// Define points to start rays
// These are Cartesian coordinates.
std::array<float, 9> p1 { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 4.0f };
const int size_p1 = p1.size();
const int count_p1 = size_p1 / 3;

Define the vector components of the ray that will be cast.

// Define one direction to cast rays
// These are vector components, not Cartesian coordinates.
const std::array<float, 3> dir { 0.0f, 0.0f, -1.0f };
const int size_dir = dir.size();
const int count_dir = size_dir / 3;

Define a maximum distance value, and a container to store the ray collision results.

// Maximum distance a ray can travel and still hit a target
const int max_distance = -1;
// If a given ray i hits a target (dir[i] is a vector extending from p1[i]),
// results[i] will be set true. Otherwise, results[i] will be set false.
// count_points rays will be cast, from the coordinates described at the array p1.
// results[i] is true if a ray cast from p1[i], p1[i + 1], p1[i + 2] via direction dir
// makes a hit.
std::array<bool, count_p1> results;
// results will be mutated by CastMultipleOriginsOneDirection.
status = CastMultipleOriginsOneDirection(bvh, p1.data(), dir.data(), count_p1, max_distance, results.data());
if (status != 1) {
// Error!
std::cerr << "Error at CastMultipleDirectionsOneOrigin, code: " << status << std::endl;
}
C_INTERFACE CastMultipleOriginsOneDirection(EmbreeRayTracer *ert, float *origins, const float *direction, int size, float max_distance, bool *result_array)
Cast rays from each origin point in the given direction.

We can review the results by outputting the contents of the results container:

//
// Review results:
//
for (int i = 0, k = 0; i < count_p1; i++, k += 3) {
std::string label = results[i] ? "hit" : "miss";
std::cout << "result[" << i << "]: " << label << std::endl;
std::cout << "[" << dir[0] << ", " << dir[1] << ", " << dir[2]
<< "], from point [" << p1[k] << ", " << p1[k + 1] << ", " << p1[k + 2] << "]"
<< std::endl;
}

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019E90659220, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019E86D22BE0, code: 1
>>> result[0]: hit
>>> [0, 0, -1], from point [0, 0, 0]
>>> result[1]: hit
>>> [0, 0, -1], from point [0, 0, -2.38419e-07]
>>> result[2]: hit
>>> [0, 0, -1], from point [0, 0, 0]

Definition at line 227 of file raytracer_C.cpp.

References ConvertRawFloatArrayToPoints(), HF::Exceptions::OK, and HF::RayTracer::EmbreeRayTracer::PointIntersections().

+ Here is the call graph for this function:

◆ CastMultipleRays()

C_INTERFACE CastMultipleRays ( HF::RayTracer::EmbreeRayTracer ert,
float *  origins,
const float *  directions,
int  size,
float  max_distance,
bool *  result_array 
)

#include <Cinterface/raytracer_C.h>

Cast multiple rays at once in parallel and receive their hitpoints in return. The number of directions must be equal to the number of origins.

Parameters
ertRaytracer to cast each ray from.
originsA list of floats representing origin points, with each 3 floats representing one point. If the ray cast from a point is successful, said point will be overwritten with the place it hit.
directionsA list of floats representing ray directions, with each 3 floats representing one direction.
sizeNumber of points and directions, equal to the total number of floats in one array / 3.
max_distanceMaximum distance a ray can travel and still hit a target. Any hits beyond this point will not be recorded.
result_arrayOutput parameter containing an ordered list of booleans set to true if the their rays hit, and false if their rays did not.
Returns
HF_STATUS::OK on completion.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.
Define the vector components of the ray that will be cast.

// Define points for rays
// These are Cartesian coordinates.
std::array<float, 9> points { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 3.0f, 0.0, 0.0, 4.0f };
const int size_points = points.size();
const int count_points = size_points / 3;
// Define directions for casting rays
// These are vector components, not Cartesian coordinates.
std::array<float, 9> dir { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, -3.0f };
const int size_dir = dir.size();
const int count_dir = 3;

Define a maximum distance value, and a container to store the ray collision results.

// Maximum distance a ray can travel and still hit its target.
const int max_distance = -1;
// If a given ray i hits a target (dir[i] is a vector extending from points[i]),
// results[i] will be set true. Otherwise, results[i] will be set false.
std::array<bool, count_dir> results;
status = CastMultipleRays(bvh, points.data(), dir.data(), count_points, max_distance, results.data());
if (status != 1) {
// Error!
std::cerr << "Error at CastMultipleRays, code: " << status << std::endl;
}
C_INTERFACE CastMultipleRays(EmbreeRayTracer *ert, float *origins, const float *directions, int size, float max_distance, bool *result_array)
Cast multiple rays at once in parallel and receive their hitpoints in return. The number of direction...

We can review the results by outputting the contents of the results container:

//
// Review results:
//
for (int i = 0, k = 0; i < count_dir; i++, k += 3) {
std::string label = results[i] ? "hit" : "miss";
std::cout << "result[" << i << "]: " << label << std::endl;
std::cout << "[" << points[k] << ", " << points[k + 1] << ", " << points[k + 2]
<< "], direction [" << dir[k] << ", " << dir[k + 1] << ", " << dir[k + 2] << "]"
<< std::endl;
}

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019E906596A0, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019E86D22500, code: 1
>>> result[0]: hit
>>> [0, 0, 0], direction [0, 0, -1]
>>> result[1]: hit
>>> [0, 0, -2.38419e-07], direction [0, 0, -2]
>>> result[2]: hit
>>> [0, 0, 2.38419e-07], direction [0, 0, -3]

Definition at line 199 of file raytracer_C.cpp.

References ConvertRawFloatArrayToPoints(), HF::Exceptions::OK, and HF::RayTracer::EmbreeRayTracer::PointIntersections().

+ Here is the call graph for this function:

◆ CastOcclusionRays()

C_INTERFACE CastOcclusionRays ( HF::RayTracer::EmbreeRayTracer ert,
const float *  origins,
const float *  directions,
int  origin_size,
int  direction_size,
float  max_distance,
bool *  result_array 
)

#include <Cinterface/raytracer_C.h>

Cast one or more occlusion rays in parallel.

Parameters
ertA pointer to a valid embree raytracer
originsA list of floats representing origin points, with each 3 floats representing one point
directionsA list of floats representing ray directions, with each 3 floats representing one direction
origin_sizeHow many origins points are included are included. Note that a single origin point is 3 floats, so this should equal the length of the origin array/3. This must match direction_size or be equal to one.
direction_sizeHow many directions are included. Note that a single direction is 3 floats, so this should equal the length of the origin array / 3. This must match origin_size or be equal to one.
max_distanceMaximum distance a ray can travel and still hit a target.
result_arrayOutput array booleans
Returns
HF_STATUS::OK on completion
Remarks
Occlusion rays are noticably faster than standard rays but are only capable of returning whether they hit something or not. This makes them good for line of sight checks.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.

// Define point to start ray
// These are Cartesian coordinates.
const std::array<float, 3> p1_occl { 0.0f, 0.0f, 2.0f };
const int size_p1_occl = static_cast<int>(p1_occl.size());
// count_origin represents how many sets of origin coordinates we are dealing with.
const int count_origin = size_p1_occl / 3;

Define the vector components of the ray(s) that will be cast.

// All of the direction components, inline, one after another.
const std::array<float, 9> dir_occl { 0.0f, 0.0f, -1.0, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
const int size_dir_occl = static_cast<int>(dir_occl.size());
// count_dir_occl represents how many sets of directions we are dealing with.
const int count_dir_occl = size_dir_occl / 3;

Define a maximum distance value, and a container to store the ray occlusion results.

// The array results should be the amount of rays we are casting, i.e. the value of count_dir_occl.
std::array<bool, count_dir_occl> results;
float max_distance_occl = 9999.0f;
status = CastOcclusionRays(bvh, p1_occl.data(), dir_occl.data(), count_origin, count_dir_occl, max_distance_occl, results.data());
if (status != 1) {
// Error!
std::cerr << "Error at CastOcclusionRays, code: " << status << std::endl;
}
C_INTERFACE CastOcclusionRays(EmbreeRayTracer *ert, const float *origins, const float *directions, int origin_size, int direction_size, float max_distance, bool *result_array)
Cast one or more occlusion rays in parallel.

If does_occlude is true, the ray connects.

bool does_occlude = results[0];
std::cout << "Does the ray connect? " << (does_occlude ? std::string("True") : std::string("False")) << std::endl;
STL namespace.

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019E90658440, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019E86D22BE0, code: 1
>>> Using multidirection, single origin
>>> Does the ray connect? True

Definition at line 271 of file raytracer_C.cpp.

References ConvertRawFloatArrayToPoints(), HF::RayTracer::EmbreeRayTracer::Occlusions(), and HF::Exceptions::OK.

+ Here is the call graph for this function:

◆ CastRay()

C_INTERFACE CastRay ( HF::RayTracer::EmbreeRayTracer ert,
float &  x,
float &  y,
float &  z,
float  dx,
float  dy,
float  dz,
float  max_distance,
bool &  result 
)

#include <Cinterface/raytracer_C.h>

Cast a single ray from the raytracer and receive a point in return.

Parameters
ertRaytracer to cast each ray from.
xx coordinate of the ray's origin. Will be set to the hit point's x coordinate if the ray something.
yy coordinate of the ray's origin. Will be set to the hit point's y coordinate if the ray something.
zz coordinate of the ray's origin. Will be set to the hit point's z coordinate if the ray something.
dxx coordinate of the ray's direction.
dyy coordinate of the ray's direction.
dzz coordinate of the ray's direction.
max_distanceMaximum distance to record a hit within. Any hits beyond this distance will not be counted.
resultSet to true if the ray hits, false otherwise
Returns
HF::OK on completion
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.
Define the vector components of the ray that will be cast.

// Define point to start ray
// These are Cartesian coordinates.
std::array<float, 3> p1 { 0.0f, 0.0f, 2.0f };
// Define direction to cast ray
// These are vector components, not Cartesian coordinates.
std::array<float, 3> dir { 0.0f, 0.0f, -1.0f };

Define a maximum distance value, and a hit point that determines the ray's intended destination..

// Cast a ray for the hitpoint (Cast a ray, get a hit point back)
float max_distance = -1;
bool did_hit = false;
// We copy the contents of p1 into hit_point.
// hit_point will be initialized to the origin point values,
// and if a hit occurs, hit_point will be set to the hit coordinate values.
//
// We will know if a hit occurs if did_hit is set 'true' by CastRay.
std::array<float, 3> hit_point = { p1[0], p1[1], p1[2] };

Invoke PointIntersection . did_hit will be set true if a hit occurred.

status = CastRay(bvh, hit_point[0], hit_point[1], hit_point[2], dir[0], dir[1], dir[2], max_distance, did_hit);
if (status != 1) {
// Error!
std::cerr << "Error at CastRay, code: " << status << std::endl;
}
if (did_hit) {
std::cout << "Hit point: " << "[" << hit_point[0] << ", " << hit_point[1] << ", " << hit_point[2] << "]" << std::endl;
}
else {
std::cout << "Hit point: " << "(miss)" << std::endl;
}
C_INTERFACE CastRay(EmbreeRayTracer *ert, float &x, float &y, float &z, float dx, float dy, float dz, float max_distance, bool &result)
Cast a single ray from the raytracer and receive a point in return.

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019E906599A0, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019E86D22BE0, code: 1
>>> Hit point: [0, 0, 0]

Definition at line 193 of file raytracer_C.cpp.

References HF::Exceptions::OK, and HF::RayTracer::EmbreeRayTracer::PointIntersection().

+ Here is the call graph for this function:

◆ CastRaysDistance()

C_INTERFACE CastRaysDistance ( HF::RayTracer::EmbreeRayTracer ert,
float *  origins,
int  num_origins,
float *  directions,
int  num_directions,
std::vector< RayResult > **  out_results,
RayResult **  results_data 
)

#include <Cinterface/raytracer_C.h>

Cast rays for each node in origins/directions as ordered pairs and get distance back as a result.

Parameters
ertThe raytracer to use for casting every ray.
originsAn array of origin points to cast rays from. Should be an array of floats with every 3 floats representing a new origin point.
num_originsThe number of points in origins. NOTE: This should be equal to the length of origins / 3, since every 3 floats in origins equals a single point.
directionsAn array of directions points to cast rays from. Should be an array of floats with every 3 floats representing a new direction.
num_directionsThe number of directions in directions. NOTE: This should be equal to the length of directions / 3, since every 3 floats in directions equals a single direction.
out_resultsOutput parameter for ray results.
results_dataOutput parameter for the data of the array held by out_results
Returns
HF_STATUS::OK on completion. HF::GENERIC_ERROR if the input parameters didn't meet at least one of the required cases below.
Remarks
Can be cast in 3 configurations:

Equal amount of directions/origins: Cast a ray for every pair of origin/direction in order. i.e. (origin[0], direction[0]), (origin[1], direction[1]).

One direction, multiple origins: Cast a ray in the given direction from each origin point in origins.

One origin, multiple directions: Cast a ray from the origin point in each direction in directions.

See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.
Define the vector components of the ray that will be cast.

// Define points for rays
// These are Cartesian coordinates.
std::array<float, 9> points{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 3.0f, 0.0, 0.0, 4.0f };
const int size_points = points.size();
const int count_points = size_points / 3;
// Define directions for casting rays
// These are vector components, not Cartesian coordinates.
std::array<float, 9> dir{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, -3.0f };
const int size_dir = dir.size();
const int count_dir = size_dir / 3;

Prepare a pointer to std::vector<RayResult>, and a pointer to a RayResult .
Then, invoke CastRaysDistance .

// Declare a pointer to vector<RayResult>.
// CastRaysDistance will allocate memory for this pointer,
// we must call DestroyRayResultVector on ray_result when we are done with it.
// ray_result_data will refer to the address of (*ray_result)'s internal buffer.
// As such, we do NOT call operator delete on ray_result_data.
std::vector<RayResult>* ray_result = nullptr;
RayResult* ray_result_data = nullptr;
status = CastRaysDistance(bvh, points.data(), count_points, dir.data(), count_dir, &ray_result, &ray_result_data);
if (status != 1) {
// Error!
std::cerr << "Error at CastRaysDistance, code: " << status << std::endl;
}
C_INTERFACE CastRaysDistance(HF::RayTracer::EmbreeRayTracer *ert, float *origins, int num_origins, float *directions, int num_directions, std::vector< RayResult > **out_results, RayResult **results_data)
Cast rays for each node in origins/directions as ordered pairs and get distance back as a result.
The result of casting a ray at an object. Contains distance to the hitpoint and the ID of the mesh.
Definition: raytracer_C.h:89

We can review the results by outputting the contents of the results container:

//
// Iterate over *(ray_result) and output its contents
//
auto it = ray_result->begin();
std::cout << "Ray result: [";
while (it < ray_result->end()) {
auto rr = *(it++);
std::cout <<
"{Distance: " << rr.distance << "\n" << "Mesh ID: " << rr.meshid
<< "}";
if (it < ray_result->end()) {
std::cout << ", ";
}
}
std::cout << "]" << std::endl;

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019C4EA752E0, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019C4EA12280, code: 1
>>> Ray result: [{Distance: 2
>>> Mesh ID: 0}, {Distance: 1.5
>>> Mesh ID: 0}, {Distance: 1.33333
>>> Mesh ID: 0}]

Definition at line 111 of file raytracer_C.cpp.

References ConvertRawFloatArrayToPoints(), HF::Exceptions::GENERIC_ERROR, HF::RayTracer::EmbreeRayTracer::IntersectOutputArguments(), and HF::Exceptions::OK.

+ Here is the call graph for this function:

◆ CastSingleRayDistance()

C_INTERFACE CastSingleRayDistance ( HF::RayTracer::EmbreeRayTracer ert,
const float *  origin,
const float *  direction,
const float  max_distance,
float *  out_distance,
int *  out_meshid 
)

#include <Cinterface/raytracer_C.h>

Cast a single ray and get the distance to its hit and the mesh ID if it hit anything. If it missed, then distance and meshid will both be -1.

Parameters
ertThe ray tracer to cast from.
originThe origin point to cast from.
directionThe direction to cast the ray in.
max_distanceMaximum distance to record a hit within. Any hits beyond this distance will not be counted.
out_distanceOut parameter for Distance to the hitpoint. Will be set to -1 if the ray didn't hit anything.
out_meshidOut parameter for the ID of the hit mesh. Will be set to -1 if the ray didn't hit anything.
Returns
HF_STATUS::OK on success
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Define the starting points from where the ray will cast.
Define the vector components of the ray that will be cast.

// Define point to start ray
// These are Cartesian coordinates.
std::array<float, 3> p1 = { 0.0f, 0.0f, 2.0f };
// Define direction to cast ray
// These are vector components, not Cartesian coordinates.
std::array<float, 3> dir = { 0.0f, 0.0f, -1.0f };

Define a max_distance.
Also create variables distance and mesh_id and initialize them as shown.
They will be mutated if a hit occurs.
Then, invoke CastSingleRayDistance

float max_distance = -1;
float distance = 0.0f;
int mesh_id = -1;
// Cast a ray for the distance/meshid (Cast a ray, get a distance/mesh ID back)
status = CastSingleRayDistance(bvh, p1.data(), dir.data(), max_distance, &distance, &mesh_id);
if (status != 1) {
// Error!
std::cerr << "Error at CastSingleRayDistance, code: " << status << std::endl;
}
C_INTERFACE CastSingleRayDistance(HF::RayTracer::EmbreeRayTracer *ert, const float *origin, const float *direction, const float max_distance, float *out_distance, int *out_meshid)
Cast a single ray and get the distance to its hit and the mesh ID if it hit anything....
Definition: raytracer_C.cpp:98

If mesh_id is not -1, and distance is not -1, a hit was made.

std::cout << "Distance is " << distance << ", " << "meshid is " << mesh_id << std::endl;

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used in this example –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::RayTracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000019C4EA3FCB0, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000019C4EA12820, code: 1
>>> Distance is 2, meshid is 0

Definition at line 98 of file raytracer_C.cpp.

References HF::RayTracer::EmbreeRayTracer::IntersectOutputArguments(), and HF::Exceptions::OK.

+ Here is the call graph for this function:

◆ CreateRaytracer()

C_INTERFACE CreateRaytracer ( HF::Geometry::MeshInfo< float > *  mesh,
HF::RayTracer::EmbreeRayTracer **  out_raytracer,
bool  use_precise 
)

#include <Cinterface/raytracer_C.h>

Create a new raytracer using several meshes.

Parameters
meshThe meshes to add to raytracer's BVH.
out_raytracerOutput parameter for the new raytracer.
use_preciseIf true, use a more precise but slower method of triangle intersections
Returns
HF_STATUS::MISSING_DEPEND if Embree's dll couldn't be found. HF_STATUS::GENERIC_ERROR if mesh is null.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Definition at line 15 of file raytracer_C.cpp.

References HF::Exceptions::GENERIC_ERROR, HF::Exceptions::INVALID_OBJ, HF::Exceptions::MISSING_DEPEND, and HF::Exceptions::OK.

◆ CreateRaytracerMultiMesh()

C_INTERFACE CreateRaytracerMultiMesh ( HF::Geometry::MeshInfo< float > **  meshes,
int  num_meshes,
HF::RayTracer::EmbreeRayTracer **  out_raytracer,
bool  use_precise 
)

#include <Cinterface/raytracer_C.h>

Create a new raytracer using several meshes.

Parameters
meshThe meshes to add to raytracer's BVH.
num_meshesNumber of meshes in meshes
out_raytracerOutput parameter for the new raytracer.
Returns
HF_STATUS::MISSING_DEPEND if Embree's dll couldn't be found. HF_STATUS::GENERIC_ERROR if mesh is null.

Definition at line 39 of file raytracer_C.cpp.

References HF::Exceptions::GENERIC_ERROR, HF::Exceptions::INVALID_OBJ, HF::Exceptions::MISSING_DEPEND, and HF::Exceptions::OK.

◆ DestroyRayResultVector()

C_INTERFACE DestroyRayResultVector ( std::vector< RayResult > *  analysis)

#include <Cinterface/raytracer_C.h>

Destroy a vector of rayresults.

Parameters
analysisThe ray results to destroy
Returns
HF_STATUS::OK on completion
//
// Memory resource cleanup.
//
// destroy vector<RayResult>
status = DestroyRayResultVector(ray_result);
if (status != 1) {
std::cerr << "Error at DestroyRayResultVector, code: " << status << std::endl;
}
C_INTERFACE DestroyRayResultVector(std::vector< RayResult > *var)
Destroy a vector of rayresults.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH), CastRaysDistance

Definition at line 281 of file raytracer_C.cpp.

References DeleteRawPtr(), and HF::Exceptions::OK.

+ Here is the call graph for this function:

◆ DestroyRayTracer()

C_INTERFACE DestroyRayTracer ( HF::RayTracer::EmbreeRayTracer rt_to_destroy)

#include <Cinterface/raytracer_C.h>

Delete an existing raytracer.

Parameters
rt_to_destroyRaytracer to destroy
Returns
HF::OK on completion.
See also
Mesh setup (how to create a mesh), Mesh teardown (how to destroy a mesh)
Raytracer setup (how to create a BVH), Raytracer teardown (how to destroy a BVH)

Definition at line 91 of file raytracer_C.cpp.

References HF::Exceptions::OK.

◆ PreciseIntersection()

C_INTERFACE PreciseIntersection ( HF::RayTracer::EmbreeRayTracer RT,
double  x,
double  y,
double  z,
double  dx,
double  dy,
double  dz,
double out_distance 
)

#include <Cinterface/raytracer_C.h>

Definition at line 286 of file raytracer_C.cpp.

References HF::RayTracer::HitStruct< numeric_type >::distance, HF::RayTracer::EmbreeRayTracer::Intersect(), and HF::Exceptions::OK.

+ Here is the call graph for this function: