DHART
Loading...
Searching...
No Matches
embree_raytracer.h
Go to the documentation of this file.
1
7
8#pragma once
9#ifndef EMBREE_RAY_TRACER
10#define EMBREE_RAY_TRACER
11
12#include <rpc.h>
13#include <rtcore.h>
14
15#include <corecrt_math_defines.h>
16#include <vector>
17#include <array>
18#include <HitStruct.h>
19#define _USE_MATH_DEFINES
20
21namespace HF::Geometry {
22 template <typename T> class MeshInfo;
23}
24
38namespace HF::RayTracer {
39 struct Vector3D {
40 double x; double y; double z;
41
42 inline Vector3D::Vector3D(double x, double y, double z) {
43 this->x = x;
44 this->y = y;
45 this->z = z;
46
47 }
48 inline Vector3D operator-(const Vector3D& v2) const {
49 return Vector3D{
50 x - v2.x,
51 y - v2.y,
52 z - v2.z
53 };
54 }
55 // Scalar multiplication overload
56 inline Vector3D operator*(const double&a) const {
57 return Vector3D{
58 a * x,
59 a * y,
60 a * z
61 };
62 }
63 };
64
65 //*! \brief Determine whether this mesh did or did not intersect */
66 bool DidIntersect(int mesh_id);
67
68 struct RayRequest;
69 struct Vertex;
70 struct Triangle;
71
82 RTCDevice device;
84 RTCScene scene;
86 RTCIntersectContext context;
91
92 bool use_precise = false;
93
94 std::vector<RTCGeometry> geometry; //> A list of the geometry being used by RTCScene.
95
96 private:
112 void SetupScene();
113
127 std::array<Vector3D, 3> GetTriangle(unsigned int geomID, unsigned int primID) const;
128
138 int InsertGeom(RTCGeometry& geom, int id = -1);
139
164 unsigned int geom_id,
165 unsigned int prim_id,
166 const Vector3D& origin,
167 const Vector3D& direction) const;
168
185
227 RTCRayHit Intersect_IMPL(
228 float x,
229 float y,
230 float z,
231 float dx,
232 float dy,
233 float dz,
234 float max_distance = -1,
235 int mesh_id = -1
236 );
237
253
293 bool Occluded_IMPL(
294 float x,
295 float y,
296 float z,
297 float dx,
298 float dy,
299 float dz,
300 float distance = -1,
301 int mesh_id = -1
302 );
303
304
318
364 bool Occluded_IMPL(
365 const std::array<float, 3>& origin,
366 const std::array<float, 3>& direction,
367 float max_dist = -1
368 );
369
379 RTCGeometry ConstructGeometryFromBuffers(std::vector<Triangle>& tris, std::vector<Vertex>& verts);
380
381 public:
397 EmbreeRayTracer(bool use_precise = false);
398
410
427 EmbreeRayTracer(std::vector<HF::Geometry::MeshInfo<float>>& MI, bool use_precise_intersection = false);
428
437
438
444 EmbreeRayTracer(const EmbreeRayTracer& ERT2);
445
446
447
463
482 EmbreeRayTracer(const std::vector<std::array<float, 3>>& geometry);
483
498
529 bool AddMesh(std::vector<std::array<float, 3>>& Mesh, int ID, bool Commit = false);
530
545
584 bool AddMesh(HF::Geometry::MeshInfo<float>& Mesh, bool Commit);
585
592
643 bool AddMesh(std::vector<HF::Geometry::MeshInfo<float>>& Meshes, bool Commit = true);
644
663
712 std::array<float, 3>& origin,
713 const std::array<float, 3>& dir,
714 float distance = -1,
715 int mesh_id = -1
716 );
717
738
783 float& x,
784 float& y,
785 float& z,
786 float dx,
787 float dy,
788 float dz,
789 float distance = -1,
790 int mesh_id = -1
791 );
792
830
877 std::vector<char> PointIntersections(
878 std::vector<std::array<float, 3>>& origins,
879 std::vector<std::array<float, 3>>& directions,
880 bool use_parallel = true,
881 float max_distance = -1,
882 int mesh_id = -1
883 );
884
885
886
919
968 std::vector<char> Occlusions(
969 const std::vector<std::array<float, 3>>& origins,
970 const std::vector<std::array<float, 3>>& directions,
971 float max_distance = -1
972 , bool use_parallel = true
973 );
974
975
1000 template <typename return_type = double, class N, class V>
1002 const N& node,
1003 const V& direction,
1004 float max_distance = -1.0f, int mesh_id = -0.1f)
1005 {
1006 return Intersect<return_type>(node[0], node[1], node[2], direction[0], direction[1], direction[2], max_distance, mesh_id);
1007 }
1008
1040 template <typename return_type = double, typename numeric1 = double, typename numeric2 = double>
1042 numeric1 x, numeric1 y, numeric1 z,
1043 numeric2 dx, numeric2 dy, numeric2 dz,
1044 float distance = -1.0f, int mesh_id = -1)
1045 {
1046 // create output value
1047 HitStruct<return_type> out_struct;
1048
1049 // Cast the ray
1050 auto result = Intersect_IMPL(
1051 x,y,z,
1052 dx,dy,dz, distance, mesh_id
1053 );
1054
1055 // If an intersection occured, update the struct.
1056 if (DidIntersect(result.hit.geomID))
1057 {
1058 // Use a precise ray intersection if required
1059 if (!(this->use_precise))
1060 out_struct.distance = result.ray.tfar;
1061 else
1063 result.hit.geomID,
1064 result.hit.primID,
1065 Vector3D(x,y,z),
1066 Vector3D(dx,dy,dz)
1067 );
1068 out_struct.meshid = result.hit.geomID;
1069 }
1070
1071 return out_struct;
1072 }
1073
1074
1097 template <typename N, typename V, typename return_type>
1099 const N& node,
1100 const V& direction,
1101 return_type& out_distance,
1102 int& out_meshid,
1103 float max_distance = -1.0f)
1104 {
1105 HitStruct<return_type> result = Intersect<return_type>(node, direction, max_distance);
1106 if (result.DidHit()) {
1107 out_distance = result.distance;
1108 out_meshid = result.meshid;
1109 return true;
1110 }
1111 else
1112 return false;
1113 }
1114
1140 template <typename return_type, typename N, typename V>
1141 inline std::vector<HitStruct<return_type>> Intersections(
1142 const N & nodes,
1143 const V & directions,
1144 float max_distance = -1.0f,
1145 const bool use_parallel = false)
1146 {
1147 const int n = nodes.size();
1148
1149 std::vector<HitStruct<return_type>> results (nodes.size());
1150
1151 #pragma omp parallel for schedule(dynamic, 256) if (use_parallel)
1152 for (int i = 0; i < n; i++) {// Use custom triangle intesection if required
1153 const auto& node = nodes[i];
1154 const auto& direction = directions[i];
1155 results[i] = Intersect<return_type>(node, direction);
1156 }
1157 return results;
1158 }
1159
1185 template <typename N, typename V>
1187 const N& origin,
1188 const V& direction,
1189 float max_distance = -1.0f,
1190 int mesh_id = -1
1191 ) {
1192 return Occluded_IMPL(
1193 origin[0], origin[1], origin[2],
1194 direction[0], direction[1], direction[2],
1195 max_distance, mesh_id
1196 );
1197 }
1198
1199
1232 template <typename numeric1, typename numeric2, typename dist_type = float>
1234 numeric1 x, numeric1 y, numeric1 z,
1235 numeric2 dx, numeric2 dy, numeric2 dz,
1236 dist_type max_distance = -1.0,
1237 int mesh_id = -1
1238 ) {
1239 return Occluded_IMPL(
1240 x,y,z,
1241 dx,dy,dz,
1242 max_distance, mesh_id
1243 );
1244 }
1245
1248
1274 void operator=(const EmbreeRayTracer& ERT2);
1275
1277
1301 };
1302
1323 const Vector3D& origin,
1324 const Vector3D& direction,
1325 const Vector3D& v1,
1326 const Vector3D& v2,
1327 const Vector3D& v3);
1328}
1329#endif
Cast rays to determine if and where they intersect geometry.
A vertex. Used internally in Embree.
A triangle. Used internally in Embree.
bool DidIntersect(int mesh_id)
Definition: HitStruct.h:23
double RayTriangleIntersection(const Vector3D &origin, const Vector3D &direction, const Vector3D &v1, const Vector3D &v2, const Vector3D &v3)
Determine the distance between a ray's origin and it's point of intersection with a triangle.
Manipulate and load geometry from disk.
Definition: meshinfo.cpp:21
A collection of vertices and indices representing geometry.
Definition: meshinfo.h:124
Vector3D operator*(const double &a) const
Vector3D operator-(const Vector3D &v2) const
Vector3D::Vector3D(double x, double y, double z)
A wrapper for Intel's Embree Library.
RTCIntersectContext context
Context to cast rays within.
std::vector< char > PointIntersections(std::vector< std::array< float, 3 > > &origins, std::vector< std::array< float, 3 > > &directions, bool use_parallel=true, float max_distance=-1, int mesh_id=-1)
Cast multiple rays and recieve hitpoints in return.
bool use_precise
If true, use custom triangle intersection intersection instead of embree's.
void SetupScene()
Performs all the necessary operations to set up the scene.
double CalculatePreciseDistance(unsigned int geom_id, unsigned int prim_id, const Vector3D &origin, const Vector3D &direction) const
Calculate the distance from origin to the point of intersection using an algorithm with higher precis...
~EmbreeRayTracer()
Custom destructor to ensure cleanup of embree resources.
std::vector< RTCGeometry > geometry
bool Occluded(const N &origin, const V &direction, float max_distance=-1.0f, int mesh_id=-1)
Determine if there is an intersection with any geometry.
RTCDevice device
All objects in Embree are created from this. https://www.embree.org/api.html#device-object.
std::array< Vector3D, 3 > GetTriangle(unsigned int geomID, unsigned int primID) const
Get the vertices for a specific triangle in a mesh.
Vertex * Vertices
Vertex buffer. Is used in multiple places but contents are dumped.
bool AddMesh(std::vector< std::array< float, 3 > > &Mesh, int ID, bool Commit=false)
Add a new mesh to this raytracer's BVH with the specified ID.
Triangle * triangles
Triangle buffer. Is used in multiple places, but contents are dumped.
int InsertGeom(RTCGeometry &geom, int id=-1)
Attach geometry to the current scene.
void operator=(const EmbreeRayTracer &ERT2)
Increment reference counters to prevent destruction when a copy is made.
RTCScene scene
Container for a set of geometries, and the BVH. https://www.embree.org/api.html#scene-object.
bool IntersectOutputArguments(const N &node, const V &direction, return_type &out_distance, int &out_meshid, float max_distance=-1.0f)
Cast a ray from origin in direction and update the parameters instead of returning a hitstruct.
RTCGeometry ConstructGeometryFromBuffers(std::vector< Triangle > &tris, std::vector< Vertex > &verts)
Create a new instance of RTCGeometry from a triangle and vertex buffer.
bool PointIntersection(std::array< float, 3 > &origin, const std::array< float, 3 > &dir, float distance=-1, int mesh_id=-1)
Cast a ray and overwrite the origin with the hitpoint if it intersects any geometry.
bool Occluded_IMPL(float x, float y, float z, float dx, float dy, float dz, float distance=-1, int mesh_id=-1)
Implementation for fundamental occlusion ray intersection.
RTCRayHit Intersect_IMPL(float x, float y, float z, float dx, float dy, float dz, float max_distance=-1, int mesh_id=-1)
Implementation for fundamental ray intersection.
bool Occluded(numeric1 x, numeric1 y, numeric1 z, numeric2 dx, numeric2 dy, numeric2 dz, dist_type max_distance=-1.0, int mesh_id=-1)
Determine if there is an intersection with any geometry.
HitStruct< return_type > Intersect(const N &node, const V &direction, float max_distance=-1.0f, int mesh_id=-0.1f)
Cast a ray from origin in direction.
HitStruct< return_type > Intersect(numeric1 x, numeric1 y, numeric1 z, numeric2 dx, numeric2 dy, numeric2 dz, float distance=-1.0f, int mesh_id=-1)
Cast a ray from origin in direction.
std::vector< char > Occlusions(const std::vector< std::array< float, 3 > > &origins, const std::vector< std::array< float, 3 > > &directions, float max_distance=-1, bool use_parallel=true)
Cast multiple occlusion rays in parallel.
std::vector< HitStruct< return_type > > Intersections(const N &nodes, const V &directions, float max_distance=-1.0f, const bool use_parallel=false)
Cast multiple rays in parallel.
A simple hit struct to carry all relevant information about hits.
Definition: HitStruct.h:7
bool DidHit() const
Determine whether or not this hitstruct contains a hit.
Definition: HitStruct.h:17
numeric_type distance
Distance from the origin point to the hit point. Set to -1 if no hit was recorded.
Definition: HitStruct.h:8
int meshid
The ID of the hit mesh. Set to -1 if no hit was recorded.
Definition: HitStruct.h:9