EmbreeIntersector.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <test_common.h>
  2. #include <igl/embree/EmbreeIntersector.h>
  3. TEST_CASE("EmbreeIntersector: cube", "[igl/embree]")
  4. {
  5. IGL_PUSH_FPE;
  6. //The allowed error for this test
  7. const double epsilon = 1e-6;
  8. Eigen::MatrixXd V;
  9. Eigen::MatrixXi F;
  10. // This is a cube of dimensions 1.0x1.0x1.0
  11. igl::read_triangle_mesh(test_common::data_path("cube.obj"), V, F);
  12. // Initialize embree
  13. igl::embree::EmbreeIntersector embree;
  14. embree.init(V.cast<float>(),F.cast<int>());
  15. // These are not expected to be exact if the hit is on a vertex of edge.
  16. const int expected_id[] = {4,8,5,2,7,0};
  17. const float expected_u[] = {0.5,0.5,0.5,0.5,0.5,0.5};
  18. const float expected_v[] = {0.5,0.0,0.0,0.0,0.5,0.0};
  19. Eigen::MatrixXd hit_P(6,3);
  20. for (int dim=0; dim<6; ++dim)
  21. {
  22. hit_P.row(dim) =
  23. V.row(F(expected_id[dim],0))*(1.f - expected_u[dim] - expected_v[dim])+
  24. V.row(F(expected_id[dim],1))*expected_u[dim] +
  25. V.row(F(expected_id[dim],2))*expected_v[dim];
  26. }
  27. const auto test_hit = [&](const bool hitP, const igl::Hit<float>& hit, const int dim)
  28. {
  29. CHECK(hitP);
  30. if(hitP)
  31. {
  32. const Eigen::RowVectorXd hit_p =
  33. V.row(F(hit.id,0))*(1.f - hit.u - hit.v) +
  34. V.row(F(hit.id,1))*hit.u +
  35. V.row(F(hit.id,2))*hit.v;
  36. // hits will be along diagonal edge so expected_id may be different
  37. test_common::assert_near(hit_P.row(dim),hit_p,epsilon);
  38. }
  39. };
  40. // Shoot ray from inside out
  41. for (int dim=0; dim<6; ++dim)
  42. {
  43. Eigen::Vector3f pos(0,0,0);
  44. Eigen::Vector3f dir(0,0,0);
  45. // test each dimension, pos and neg
  46. dir[dim/2] = dim%2 ? -1 : 1;
  47. igl::Hit<float> hit;
  48. bool hitP = embree.intersectRay(pos, dir, hit);
  49. test_hit(hitP,hit,dim);
  50. }
  51. // Shoot ray from outside in
  52. for (int dim=0; dim<6; ++dim)
  53. {
  54. Eigen::Vector3f dir(0,0,0);
  55. // test each dimension, pos and neg
  56. dir[dim/2] = dim%2 ? 1 : -1;
  57. Eigen::Vector3f pos = -dir;
  58. igl::Hit<float> hit;
  59. bool hitP = embree.intersectRay(pos, dir, hit);
  60. test_hit(hitP,hit,dim);
  61. }
  62. // Rays that miss
  63. for (int dim=0; dim<6; ++dim)
  64. {
  65. Eigen::Vector3f pos(0,0,0);
  66. Eigen::Vector3f dir(0,0,0);
  67. // test each dimension, pos and neg
  68. dir[dim/2] = dim%2 ? -1 : 1;
  69. pos[(dim/2+1)%3] = dir[dim/2];
  70. igl::Hit<float> hit;
  71. bool hitP = embree.intersectRay(pos, dir, hit);
  72. CHECK_FALSE(hitP);
  73. }
  74. // intersect beam
  75. {
  76. Eigen::Vector3f pos(1.75,0.25,0);
  77. Eigen::Vector3f dir(-1,0,0);
  78. igl::Hit<float> hit;
  79. bool hitP = embree.intersectBeam(pos, dir, hit);
  80. CHECK(hitP);
  81. REQUIRE(hit.t == Approx(1.25).margin(epsilon));
  82. REQUIRE(hit.id == 4);
  83. REQUIRE(hit.u == Approx(0.5).margin(epsilon));
  84. REQUIRE(hit.v == Approx(0.25).margin(epsilon));
  85. }
  86. IGL_POP_FPE;
  87. }