0

I have a triangle and a segment which, according to embree, they are colliding. However, when I draw this elements, it is clear they don't collide.

enter image description here

In the image, the dots on the triangle and the segment are the intersection points, computed using the barycentric coordinates and the intersection distance given by embree.

I have also tested with CGAL if the elements collide, and CGAL doesn't detect any intersection.

I have absolutely no clue on what might be happening. I have been able to create a minimal reproducible example which shows the behavior I am describing

#include <embree3/rtcore_common.h>
#include <tuple>

#include <embree3/rtcore_device.h>
#include <embree3/rtcore_geometry.h>
#include <embree3/rtcore_ray.h>
#include <embree3/rtcore_scene.h>

#include <iostream>

// To get the points exactly as we saw them on the error
float dec(int x) {
  struct U {
    union {
      int i;
      float f;
    };
  };
  U u;
  u.i = x;
  return u.f;
}

int main() {

  // Data to reproduce the issue
  auto [v0x, v0y, v0z] =
      std::make_tuple(dec(0x3e6a2c13), dec(0x3fad24ce), dec(0x3ecc9e88));
  auto [v1x, v1y, v1z] =
      std::make_tuple(dec(0x3e6e35dd), dec(0x3fad7b6a), dec(0x3eca0623));
  auto [v2x, v2y, v2z] =
      std::make_tuple(dec(0x3e692c70), dec(0x3fad7b6a), dec(0x3eca0623));

  RTCRay ray;
  ray.org_x = dec(0x3e708b43);
  ray.org_y = dec(0x3fad42a5);
  ray.org_z = dec(0x3ecbb9a0);
  ray.tfar = dec(0x3b9631f5);
  ray.dir_x = dec(0x3f137064);
  ray.dir_y = dec(0x3ec18586);
  ray.dir_z = dec(0xbf399122);
  ray.tnear = 0.0F;
  ray.mask = 0;
  ray.time = 0.0F;
  ray.flags = 0;

  // Create device and scene
  auto device = rtcNewDevice("");
  auto scene = rtcNewScene(device);
  rtcSetSceneFlags(scene, RTC_SCENE_FLAG_DYNAMIC |
                              RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION);
  rtcSetSceneBuildQuality(scene, RTC_BUILD_QUALITY_LOW);

  // Create geometry
  auto geometry = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);
  rtcSetGeometryBuildQuality(geometry, RTC_BUILD_QUALITY_REFIT);

  auto geomId = rtcAttachGeometry(scene, geometry);

  auto *vb = static_cast<float *>(
      rtcSetNewGeometryBuffer(geometry, RTC_BUFFER_TYPE_VERTEX, 0,
                              RTC_FORMAT_FLOAT3, 4 * sizeof(float), 12));

  vb[4 * 0 + 0] = v0x;
  vb[4 * 0 + 1] = v0y;
  vb[4 * 0 + 2] = v0z;

  vb[4 * 1 + 0] = v1x;
  vb[4 * 1 + 1] = v1y;
  vb[4 * 1 + 2] = v1z;

  vb[4 * 2 + 0] = v2x;
  vb[4 * 2 + 1] = v2y;
  vb[4 * 2 + 2] = v2z;

  auto *ib = static_cast<int *>(
      rtcSetNewGeometryBuffer(geometry, RTC_BUFFER_TYPE_INDEX, 0,
                              RTC_FORMAT_UINT3, 3 * sizeof(int), 3));
  ib[0] = 0;
  ib[1] = 1;
  ib[2] = 2;
  rtcCommitGeometry(geometry);

  rtcCommitScene(scene);

  // Perform the query
  RTCIntersectContext context{};
  rtcInitIntersectContext(&context);
  context.flags = RTC_INTERSECT_CONTEXT_FLAG_INCOHERENT;

  rtcOccluded1(scene, &context, &ray);
// Same behavior with rtcIntersect1

  std::cout << ray.tfar << std::endl; // -inf here means an intersection has been found
}

I have uploaded the example to gitlab in case someone wats to test it (https://gitlab.com/juanjo.casafranca/embree_issue)

jjcasmar
  • 1,387
  • 1
  • 18
  • 30

0 Answers0