diff --git a/include/xdg/constants.h b/include/xdg/constants.h index 79007d2..51b044d 100644 --- a/include/xdg/constants.h +++ b/include/xdg/constants.h @@ -67,7 +67,7 @@ static Property VOID_MATERIAL {PropertyType::MATERIAL, "void"}; enum class RayFireType { VOLUME, POINT_CONTAINMENT, ACCUMULATE_HITS, FIND_VOLUME }; // -enum class HitOrientation { NONE, EXITING, ENTERING }; +enum class HitOrientation { ANY, EXITING, ENTERING }; } // namespace xdg diff --git a/include/xdg/embree3.h b/include/xdg/embree3.h index a847db6..9cf07a1 100644 --- a/include/xdg/embree3.h +++ b/include/xdg/embree3.h @@ -14,4 +14,12 @@ inline void rtcIntersect1(RTCScene scene, RTCRayHit* rayhit) { } } +inline void rtcOccluded1(RTCScene scene, RTCRay* ray) { + { + RTCIntersectContext context; + rtcInitIntersectContext(&context); + rtcOccluded1(scene, &context, ray); + } +} + #endif // include guard \ No newline at end of file diff --git a/include/xdg/ray_tracing_interface.h b/include/xdg/ray_tracing_interface.h index aa0e848..72e4eef 100644 --- a/include/xdg/ray_tracing_interface.h +++ b/include/xdg/ray_tracing_interface.h @@ -41,6 +41,11 @@ class RayTracer { const Position& origin, double& dist); + bool occluded(MeshID volume, + const Position& origin, + const Direction& direction, + double& dist) const; + // Accessors int num_registered_volumes() const { return volume_map_.size(); } diff --git a/src/ray_tracing_interface.cpp b/src/ray_tracing_interface.cpp index 0e5a7b7..46d4d45 100644 --- a/src/ray_tracing_interface.cpp +++ b/src/ray_tracing_interface.cpp @@ -166,4 +166,30 @@ void RayTracer::closest(MeshID volume, distance = query.dradius; } +bool RayTracer::occluded(MeshID volume, + const Position& origin, + const Direction& direction, + double& distance) const +{ + RTCScene scene = volume_map_.at(volume); + + RTCDRay ray; + ray.set_org(origin); + ray.set_dir(direction); + ray.set_tfar(INFTY); + ray.set_tnear(0.0); + ray.rf_type = RayFireType::FIND_VOLUME; + ray.orientation = HitOrientation::ANY; + ray.flags = 0; + ray.mask = -1; // no mask + + // fire the ray + { + rtcOccluded1(scene, (RTCRay*)&ray); + } + + distance = ray.dtfar; + return distance != INFTY; +} + } // namespace xdg \ No newline at end of file diff --git a/src/triangle_ref.cpp b/src/triangle_ref.cpp index 8512a43..dcab7ee 100644 --- a/src/triangle_ref.cpp +++ b/src/triangle_ref.cpp @@ -96,23 +96,6 @@ void TriangleIntersectionFunc(RTCIntersectFunctionNArguments* args) { rayhit->hit.dNg[2] = normal[2]; } - -void TriangleOcclusionFunc(RTCOccludedFunctionNArguments* args) { - const GeometryUserData* user_data = (const GeometryUserData*) args->geometryUserPtr; - const MeshManager* mesh_manager = user_data->mesh_manager; - const TriangleRef& tri_ref = user_data->tri_ref_buffer[args->primID]; - - auto vertices = mesh_manager->triangle_vertices(tri_ref.triangle_id); - - // get the double precision ray from the args - RTCDRay* ray = (RTCDRay*) args->ray; - - double plucker_dist; - if (plucker_ray_tri_intersect(vertices, ray->dorg, ray->ddir, plucker_dist)) { - ray->set_tfar(-INFTY); - } -} - bool TriangleClosestFunc(RTCPointQueryFunctionArguments* args) { RTCGeometry g = rtcGetGeometry(*(RTCScene*)args->userPtr, args->geomID); // get the array of DblTri's stored on the geometry @@ -140,6 +123,22 @@ bool TriangleClosestFunc(RTCPointQueryFunctionArguments* args) { } } +void TriangleOcclusionFunc(RTCOccludedFunctionNArguments* args) { + const GeometryUserData* user_data = (const GeometryUserData*) args->geometryUserPtr; + const MeshManager* mesh_manager = user_data->mesh_manager; + const TriangleRef& tri_ref = user_data->tri_ref_buffer[args->primID]; + + auto vertices = mesh_manager->triangle_vertices(tri_ref.triangle_id); + + // get the double precision ray from the args + RTCDRay* ray = (RTCDRay*) args->ray; + + double plucker_dist; + if (plucker_ray_tri_intersect(vertices, ray->dorg, ray->ddir, plucker_dist)) { + ray->set_tfar(-INFTY); + } +} + } // namespace xdg diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3ed1ecb..8531452 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,6 +5,7 @@ TEST_NAMES test_bbox test_bvh test_closest +test_occluded test_ray_fire test_mesh_internal test_xdg_interface diff --git a/tests/test_occluded.cpp b/tests/test_occluded.cpp new file mode 100644 index 0000000..0ba0014 --- /dev/null +++ b/tests/test_occluded.cpp @@ -0,0 +1,34 @@ + +// for testing +#include + +// xdg includes +#include "xdg/mesh_manager_interface.h" +#include "xdg/ray_tracing_interface.h" + +#include "mesh_mock.h" + +using namespace xdg; + +TEST_CASE("Test Occluded") +{ + std::shared_ptr mm = std::make_shared(); + mm->init(); // this should do nothing, just good practice to call it + + std::shared_ptr rti = std::make_shared(); + rti->register_all_volumes(mm); + + // setup ray to fire that won't hit the mock model + Position r {-100.0, 0.0, 0.0}; + Direction u {1.0, 0.0, 0.0}; + double dist {0.0}; + + MeshID volume = mm->volumes()[0]; + + bool result = rti->occluded(volume, r, u, dist); + REQUIRE(result == true); + + u = {-1.0, 0.0, 0.0}; + result = rti->occluded(volume, r, u, dist); + REQUIRE(result == false); +} \ No newline at end of file