| 138 | } |
| 139 | |
| 140 | void hinge_test(typename BVHEngine::Ptr bvh, bool reordered=false, |
| 141 | const Float tol=1e-12) { |
| 142 | MatrixFr vertices(6, 3); |
| 143 | vertices << 0.0, 0.0, 0.0, |
| 144 | 0.0, 0.0, 1.0, |
| 145 | -1.0, 0.0, 0.0, |
| 146 | 0.0, -1.0, 0.0, |
| 147 | -1.0, 0.0, 1.0, |
| 148 | 0.0, -1.0, 1.0; |
| 149 | |
| 150 | MatrixIr faces(4, 3); |
| 151 | faces << 0, 1, 2, |
| 152 | 1, 0, 3, |
| 153 | 1, 4, 2, |
| 154 | 1, 3, 5; |
| 155 | |
| 156 | bvh->set_mesh(vertices, faces); |
| 157 | bvh->build(); |
| 158 | |
| 159 | const size_t N = 100; |
| 160 | MatrixFr queries(N, 3); |
| 161 | for (size_t i=0; i<N; i++) { |
| 162 | Float angle = 2*M_PI * Float(i) / Float(N); |
| 163 | queries(i,0) = cos(angle); |
| 164 | queries(i,1) = sin(angle); |
| 165 | queries(i,2) = 0.5; |
| 166 | } |
| 167 | |
| 168 | VectorF distances; |
| 169 | VectorI face_indices; |
| 170 | MatrixFr closest_points; |
| 171 | bvh->lookup(queries, distances, face_indices, closest_points); |
| 172 | |
| 173 | for (size_t i=0; i<N; i++) { |
| 174 | const auto& p = queries.row(i); |
| 175 | if (p[0] >= 0.0 && p[1] >= 0.0) { |
| 176 | // 1st quadrant. |
| 177 | ASSERT_NEAR(1.0, distances[i], tol); |
| 178 | if (!reordered) { |
| 179 | ASSERT_TRUE(face_indices[i] == 0 || face_indices[i] == 1); |
| 180 | } |
| 181 | ASSERT_NEAR(0.0, closest_points(i, 0), tol); |
| 182 | ASSERT_NEAR(0.0, closest_points(i, 1), tol); |
| 183 | ASSERT_NEAR(0.5, closest_points(i, 2), tol); |
| 184 | } else if (p[1] >= 0.0) { |
| 185 | // 2nd quadrant. |
| 186 | ASSERT_NEAR(p[1]*p[1], distances[i], tol); |
| 187 | if (!reordered) { |
| 188 | if (std::abs(p[0]) < 0.5) { |
| 189 | ASSERT_EQ(0, face_indices[i]); |
| 190 | } else if (std::abs(p[0]) > 0.5) { |
| 191 | ASSERT_EQ(2, face_indices[i]); |
| 192 | } else { |
| 193 | ASSERT_TRUE(face_indices[i] == 0 || |
| 194 | face_indices[i] == 2); |
| 195 | } |
| 196 | } |
| 197 | ASSERT_NEAR(p[0], closest_points(i, 0), tol); |