You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

101 lines
2.7 KiB

#include <test_common.h>
#include <igl/embree/EmbreeIntersector.h>
TEST_CASE("EmbreeIntersector: cube", "[igl/embree]")
{
IGL_PUSH_FPE;
//The allowed error for this test
const double epsilon = 1e-6;
Eigen::MatrixXd V;
Eigen::MatrixXi F;
// This is a cube of dimensions 1.0x1.0x1.0
igl::read_triangle_mesh(test_common::data_path("cube.obj"), V, F);
// Initialize embree
igl::embree::EmbreeIntersector embree;
embree.init(V.cast<float>(),F.cast<int>());
// These are not expected to be exact if the hit is on a vertex of edge.
const int expected_id[] = {4,8,5,2,7,0};
const float expected_u[] = {0.5,0.5,0.5,0.5,0.5,0.5};
const float expected_v[] = {0.5,0.0,0.0,0.0,0.5,0.0};
Eigen::MatrixXd hit_P(6,3);
for (int dim=0; dim<6; ++dim)
{
hit_P.row(dim) =
V.row(F(expected_id[dim],0))*(1.f - expected_u[dim] - expected_v[dim])+
V.row(F(expected_id[dim],1))*expected_u[dim] +
V.row(F(expected_id[dim],2))*expected_v[dim];
}
const auto test_hit = [&](const bool hitP, const igl::Hit& hit, const int dim)
{
CHECK(hitP);
if(hitP)
{
const Eigen::RowVectorXd hit_p =
V.row(F(hit.id,0))*(1.f - hit.u - hit.v) +
V.row(F(hit.id,1))*hit.u +
V.row(F(hit.id,2))*hit.v;
// hits will be along diagonal edge so expected_id may be different
test_common::assert_near(hit_P.row(dim),hit_p,epsilon);
}
};
// Shoot ray from inside out
for (int dim=0; dim<6; ++dim)
{
Eigen::Vector3f pos(0,0,0);
Eigen::Vector3f dir(0,0,0);
// test each dimension, pos and neg
dir[dim/2] = dim%2 ? -1 : 1;
igl::Hit hit;
bool hitP = embree.intersectRay(pos, dir, hit);
test_hit(hitP,hit,dim);
}
// Shoot ray from outside in
for (int dim=0; dim<6; ++dim)
{
Eigen::Vector3f dir(0,0,0);
// test each dimension, pos and neg
dir[dim/2] = dim%2 ? 1 : -1;
Eigen::Vector3f pos = -dir;
igl::Hit hit;
bool hitP = embree.intersectRay(pos, dir, hit);
test_hit(hitP,hit,dim);
}
// Rays that miss
for (int dim=0; dim<6; ++dim)
{
Eigen::Vector3f pos(0,0,0);
Eigen::Vector3f dir(0,0,0);
// test each dimension, pos and neg
dir[dim/2] = dim%2 ? -1 : 1;
pos[(dim/2+1)%3] = dir[dim/2];
igl::Hit hit;
bool hitP = embree.intersectRay(pos, dir, hit);
CHECK_FALSE(hitP);
}
// intersect beam
{
Eigen::Vector3f pos(1.75,0.25,0);
Eigen::Vector3f dir(-1,0,0);
igl::Hit hit;
bool hitP = embree.intersectBeam(pos, dir, hit);
CHECK(hitP);
REQUIRE(hit.t == Approx(1.25).margin(epsilon));
REQUIRE(hit.id == 4);
REQUIRE(hit.u == Approx(0.5).margin(epsilon));
REQUIRE(hit.v == Approx(0.25).margin(epsilon));
}
IGL_POP_FPE;
}