1 // g++ -O0 -std=c++11 -Wall main_bug_1.cpp -o main_bug_1
2 #include "nanort.h"
3 #include <iostream>
4
5 typedef double real;
6
main(int argc,char * argv[])7 int main(int argc, char * argv[])
8 {
9 std::cout << "This program exposes a possible accuracy bug with nanort." << std::endl<<std::flush;
10 std::cout << "A slight variation on direction[0] makes nanort misses a real intersection." << std::endl<<std::flush;
11 std::cout << "Called without argument, we run a normal case where a ray creates an intersection on a single triangle" << std::endl<<std::flush;
12 std::cout << "Called with one argument, we slightty changes the direction and have a no intersection result, that is not normal" << std::endl<<std::flush;
13 bool activate_precision_bug = false;
14 if (argc>1)
15 {
16 activate_precision_bug = true;
17 }
18 real vertices[9];
19 unsigned int triangles[3] ={0,1,2};
20
21 const real xMin=-1.0, xMax=+1.0;
22 const real zMin=-3.0, zMax=+3.0;
23 vertices[3 * 0] = xMax; vertices[3 * 0 + 1] = 2.0; vertices[3 * 0 + 2] = zMin;
24 vertices[3 * 1] = xMin; vertices[3 * 1 + 1] = 2.0; vertices[3 * 1 + 2] = zMin;
25 vertices[3 * 2] = xMax; vertices[3 * 2 + 1] = 2.0; vertices[3 * 2 + 2] = zMax;
26
27 real origins[3];
28 real directions[3];
29
30 origins[0] = -0.36; origins[1] = +7.93890843; origins[2] = 1.2160368;
31 directions[1] = -8.66025404e-01; directions[2] = -0.5;
32 directions[0] = 0.0;
33 if (activate_precision_bug)
34 {
35 directions[0] = -5.30287619e-17;
36 }
37 std::cout << "directions[0] = " << directions[0] << std::endl;
38
39 nanort::BVHBuildOptions<real> build_options; // Use default option
40 nanort::TriangleMesh<real> triangle_mesh(vertices, triangles, sizeof(real) * 3);
41 nanort::TriangleSAHPred<real> triangle_pred(vertices, triangles, sizeof(real) * 3);
42 nanort::BVHAccel<real> accel;
43 build_options.cache_bbox = true;
44 int ret = accel.Build((size_t) 1, triangle_mesh, triangle_pred, build_options);
45 assert(ret);
46 nanort::Ray<real> ray;
47 nanort::TriangleIntersector<real, nanort::TriangleIntersection<real> > triangle_intersector(vertices, triangles, sizeof(real) * 3);
48 nanort::TriangleIntersection<real> isect;
49
50 ray.org[0] = origins[0];
51 ray.org[1] = origins[1];
52 ray.org[2] = origins[2];
53
54
55 const real length = sqrt(directions[0] * directions[0] +
56 directions[1] * directions[1] +
57 directions[2] * directions[2]);
58 ray.dir[0] = directions[0]/length;
59 ray.dir[1] = directions[1]/length;
60 ray.dir[2] = directions[2]/length;
61
62 ray.min_t = 0.0;
63 ray.max_t = 1.0e+30;
64
65 const bool hit = accel.Traverse(ray, triangle_intersector, &isect);
66 if (hit)
67 {
68 std::cout << "We have the expected result" << std::endl<<std::flush;
69 std::cout << "Intersection isect.u =" << isect.u << " v = " << isect.v << std::endl<<std::flush;
70 }
71 else
72 {
73 std::cout << "No intersection detected" << std::endl<<std::flush;
74 std::cout << "We get the wrong result" << std::endl<<std::flush;
75
76 }
77 return 0;
78 }
79