Intel® Embree Ray Tracing Kernels
Discussion forum on the open source ray tracing kernels for fast photo-realistic rendering on Intel® CPU(s)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
288 Discussions

Is it possible to use Embree for intersection computation in 2D ?

ImperatorS79
Beginner
977 Views

I see there is RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE, but despite all my attemps, I do not maange to make it work.  Here is my last attempt:

 

#include <array>
#include <vector>
#include <string>
#include <stdexcept>
#include <iostream>
#include <limits>
#include <embree4/rtcore.h>

std::string translateEmbreeError(RTCError error)
{
switch(error)
{
case RTC_ERROR_NONE:
return "no error occured";
case RTC_ERROR_INVALID_ARGUMENT:
return "an unknown error has occured";
case RTC_ERROR_INVALID_OPERATION:
return "the operation is not allowed for the specified object";
case RTC_ERROR_OUT_OF_MEMORY:
return "there is not enough memory left to complete the operation";
case RTC_ERROR_UNSUPPORTED_CPU:
return "the CPU is not supported as it does not support the lowest ISA Embree is compiled for";
case RTC_ERROR_CANCELLED:
return "the operation got canceled by a memory monitor callback or progress monitor callback function";
default:
return "unknown error";
}
}

struct RayQueryContext
{
RTCRayQueryContext context;
unsigned int skipFacet;
};

void intersectionFilter(const RTCFilterFunctionNArguments* args);

int main()
{
RTCDevice device = rtcNewDevice("set_affinity=1");
if(device == NULL)
throw std::runtime_error("failed to create embree device: " + translateEmbreeError(rtcGetDeviceError(NULL)));

RTCScene scene = rtcNewScene(device);
RTCError error = rtcGetDeviceError(device);
if(scene == NULL)
throw std::runtime_error("failed to create embree scene: " + translateEmbreeError(error));

rtcSetSceneFlags(scene, RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS | RTC_SCENE_FLAG_ROBUST);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
throw std::runtime_error("failed to set embree scene flags: " + translateEmbreeError(error));

RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE);
error = rtcGetDeviceError(device);
if(geom == NULL)
throw std::runtime_error("failed to create embree geometry: " + translateEmbreeError(error));

rtcSetGeometryEnableFilterFunctionFromArguments(geom, true);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
throw std::runtime_error("failed to set embree geometry flags: " + translateEmbreeError(error));

std::vector<std::array<double, 3>> points = {
{0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f},
{1.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
{0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}
};

float* vb = static_cast<float*>(rtcSetNewGeometryBuffer(geom,
RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT4, 4*sizeof(float), points.size()));

const size_t segmentsCount = points.size()/2;

for(std::size_t s = 0 ; s < segmentsCount ; ++s)
{
//First point of segment
vb[8*s + 0] = points[2*s + 0][0];
vb[8*s + 1] = points[2*s + 0][1];
vb[8*s + 2] = 0.0f;
vb[8*s + 3] = 0.1f;
//Second point of segment
vb[8*s + 4] = points[2*s + 1][0];
vb[8*s + 5] = points[2*s + 1][1];
vb[8*s + 6] = 0.0f;
vb[8*s + 7] = 0.1f;
}

unsigned int* ib = static_cast<unsigned int*>(rtcSetNewGeometryBuffer(geom,
RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, sizeof(unsigned int), segmentsCount));

for(std::size_t s = 0 ; s < segmentsCount ; ++s)
ib[s] = 2*s;

rtcCommitGeometry(geom);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
throw std::runtime_error("failed to commit embree geometry: " + translateEmbreeError(error));

rtcAttachGeometry(scene, geom);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
throw std::runtime_error("failed to attach embree geometry: " + translateEmbreeError(error));

rtcReleaseGeometry(geom);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
throw std::runtime_error("failed to release embree geoemtry: " + translateEmbreeError(error));

rtcCommitScene(scene);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
throw std::runtime_error("failed to commit embree scene: " + translateEmbreeError(error));
 
RTCRayHit rayHit;
rayHit.ray.org_x = 0.5f; rayHit.ray.org_y = 1.0f; rayHit.ray.org_z = 0.0f;
rayHit.ray.dir_x = 0.0f; rayHit.ray.dir_y = -1.0f; rayHit.ray.dir_z = 0.0f;
rayHit.ray.tnear = 0.0f;
rayHit.ray.tfar = std::numeric_limits<float>::infinity();
rayHit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
 
unsigned int facetToSkip = 3000;

RayQueryContext context;
context.skipFacet = facetToSkip;
rtcInitRayQueryContext(&context.context);

RTCIntersectArguments args;
rtcInitIntersectArguments(&args);
args.context = &context.context;
args.filter = intersectionFilter;
 
rtcIntersect1(scene, &rayHit, &args);
if(rayHit.hit.geomID == RTC_INVALID_GEOMETRY_ID)
throw std::runtime_error("You did not intersect while you should ?");

rtcReleaseScene(scene);
error = rtcGetDeviceError(device);
if(error != RTC_ERROR_NONE)
std::cerr << "failed to delete embree scene: " + translateEmbreeError(error) << std::endl;

rtcReleaseDevice(device);

return 0;
}

void intersectionFilter(const RTCFilterFunctionNArguments* args)
{
//When Using rtcIntersect1, only one ray to filter
RTCHit* pHit = reinterpret_cast<RTCHit*>(args->hit);
RayQueryContext* context = reinterpret_cast<RayQueryContext*>(args->context);

unsigned int skipFacetUInt = context->skipFacet;

if(pHit->primID == skipFacetUInt)
args->valid[0] = 0;
else
args->valid[0] = -1;
}
 

 

0 Kudos
1 Reply
SvenW_Intel
Moderator
787 Views

Please initialize all rayHit.ray members, in particular rayHit.ray.mask = -1 should be set, otherwise ray mask is likely 0 and no geometry will be hit.

0 Kudos
Reply