38 #define BOOST_TEST_MODULE FCL_DISTANCE 41 #include <boost/test/included/unit_test.hpp> 42 #include <boost/filesystem.hpp> 46 #include "../src/collision_node.h" 50 #include "fcl_resources/config.h" 53 namespace utf = boost::unit_test::framework;
58 template <
typename BV>
60 const std::vector<Triangle>& triangles1,
61 const std::vector<Vec3f>& vertices2,
62 const std::vector<Triangle>& triangles2,
67 const std::vector<Vec3f>& vertices1,
68 const std::vector<Triangle>& triangles1,
69 const std::vector<Vec3f>& vertices2,
70 const std::vector<Triangle>& triangles2,
73 template <
typename BV,
typename TraversalNode>
75 const std::vector<Vec3f>& vertices1,
76 const std::vector<Triangle>& triangles1,
77 const std::vector<Vec3f>& vertices2,
78 const std::vector<Triangle>& triangles2,
83 if (fabs(a[0] - b[0]) >
DELTA)
return false;
84 if (fabs(a[1] - b[1]) >
DELTA)
return false;
85 if (fabs(a[2] - b[2]) >
DELTA)
return false;
90 std::vector<Vec3f>
p1, p2;
91 std::vector<Triangle> t1, t2;
93 loadOBJFile((path /
"env.obj").
string().c_str(), p1, t1);
94 loadOBJFile((path /
"rob.obj").
string().c_str(), p2, t2);
96 std::vector<Transform3f> transforms;
98 #ifndef NDEBUG // if debug mode 103 n =
getNbRun(utf::master_test_suite().argc, utf::master_test_suite().argv, n);
111 for (std::size_t i = 0; i < transforms.size(); ++i) {
112 auto timer_col = std::chrono::high_resolution_clock::now();
114 col_time += std::chrono::duration_cast<std::chrono::duration<double>>(
115 std::chrono::high_resolution_clock::now() - timer_col)
118 auto timer_dist = std::chrono::high_resolution_clock::now();
119 distance_Test_Oriented<RSS, MeshDistanceTraversalNodeRSS>(
121 dis_time += std::chrono::duration_cast<std::chrono::duration<double>>(
122 std::chrono::high_resolution_clock::now() - timer_dist)
125 distance_Test_Oriented<RSS, MeshDistanceTraversalNodeRSS>(
129 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
130 BOOST_CHECK(fabs(res.distance) <
DELTA ||
131 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
134 distance_Test_Oriented<RSS, MeshDistanceTraversalNodeRSS>(
138 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
139 BOOST_CHECK(fabs(res.distance) <
DELTA ||
140 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
143 distance_Test_Oriented<RSS, MeshDistanceTraversalNodeRSS>(
146 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
147 BOOST_CHECK(fabs(res.distance) <
DELTA ||
148 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
151 distance_Test_Oriented<RSS, MeshDistanceTraversalNodeRSS>(
155 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
156 BOOST_CHECK(fabs(res.distance) <
DELTA ||
157 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
160 distance_Test_Oriented<RSS, MeshDistanceTraversalNodeRSS>(
164 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
165 BOOST_CHECK(fabs(res.distance) <
DELTA ||
166 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
169 distance_Test_Oriented<kIOS, MeshDistanceTraversalNodekIOS>(
172 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
173 BOOST_CHECK(fabs(res.distance) <
DELTA ||
174 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
177 distance_Test_Oriented<kIOS, MeshDistanceTraversalNodekIOS>(
181 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
182 BOOST_CHECK(fabs(res.distance) <
DELTA ||
183 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
186 distance_Test_Oriented<kIOS, MeshDistanceTraversalNodekIOS>(
190 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
191 BOOST_CHECK(fabs(res.distance) <
DELTA ||
192 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
195 distance_Test_Oriented<kIOS, MeshDistanceTraversalNodekIOS>(
198 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
199 BOOST_CHECK(fabs(res.distance) <
DELTA ||
200 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
203 distance_Test_Oriented<kIOS, MeshDistanceTraversalNodekIOS>(
207 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
208 BOOST_CHECK(fabs(res.distance) <
DELTA ||
209 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
212 distance_Test_Oriented<kIOS, MeshDistanceTraversalNodekIOS>(
216 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
217 BOOST_CHECK(fabs(res.distance) <
DELTA ||
218 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
221 distance_Test_Oriented<OBBRSS, MeshDistanceTraversalNodeOBBRSS>(
224 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
225 BOOST_CHECK(fabs(res.distance) <
DELTA ||
226 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
229 distance_Test_Oriented<OBBRSS, MeshDistanceTraversalNodeOBBRSS>(
233 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
234 BOOST_CHECK(fabs(res.distance) <
DELTA ||
235 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
238 distance_Test_Oriented<OBBRSS, MeshDistanceTraversalNodeOBBRSS>(
242 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
243 BOOST_CHECK(fabs(res.distance) <
DELTA ||
244 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
247 distance_Test_Oriented<OBBRSS, MeshDistanceTraversalNodeOBBRSS>(
250 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
251 BOOST_CHECK(fabs(res.distance) <
DELTA ||
252 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
255 distance_Test_Oriented<OBBRSS, MeshDistanceTraversalNodeOBBRSS>(
259 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
260 BOOST_CHECK(fabs(res.distance) <
DELTA ||
261 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
264 distance_Test_Oriented<OBBRSS, MeshDistanceTraversalNodeOBBRSS>(
268 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
269 BOOST_CHECK(fabs(res.distance) <
DELTA ||
270 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
276 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
277 BOOST_CHECK(fabs(res.distance) <
DELTA ||
278 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
284 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
285 BOOST_CHECK(fabs(res.distance) <
DELTA ||
286 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
292 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
293 BOOST_CHECK(fabs(res.distance) <
DELTA ||
294 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
300 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
301 BOOST_CHECK(fabs(res.distance) <
DELTA ||
302 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
308 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
309 BOOST_CHECK(fabs(res.distance) <
DELTA ||
310 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
316 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
317 BOOST_CHECK(fabs(res.distance) <
DELTA ||
318 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
324 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
325 BOOST_CHECK(fabs(res.distance) <
DELTA ||
326 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
332 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
333 BOOST_CHECK(fabs(res.distance) <
DELTA ||
334 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
340 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
341 BOOST_CHECK(fabs(res.distance) <
DELTA ||
342 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
348 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
349 BOOST_CHECK(fabs(res.distance) <
DELTA ||
350 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
356 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
357 BOOST_CHECK(fabs(res.distance) <
DELTA ||
358 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
364 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
365 BOOST_CHECK(fabs(res.distance) <
DELTA ||
366 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
372 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
373 BOOST_CHECK(fabs(res.distance) <
DELTA ||
374 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
380 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
381 BOOST_CHECK(fabs(res.distance) <
DELTA ||
382 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
388 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
389 BOOST_CHECK(fabs(res.distance) <
DELTA ||
390 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
396 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
397 BOOST_CHECK(fabs(res.distance) <
DELTA ||
398 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
404 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
405 BOOST_CHECK(fabs(res.distance) <
DELTA ||
406 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
412 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
413 BOOST_CHECK(fabs(res.distance) <
DELTA ||
414 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
420 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
421 BOOST_CHECK(fabs(res.distance) <
DELTA ||
422 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
428 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
429 BOOST_CHECK(fabs(res.distance) <
DELTA ||
430 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
436 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
437 BOOST_CHECK(fabs(res.distance) <
DELTA ||
438 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
444 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
445 BOOST_CHECK(fabs(res.distance) <
DELTA ||
446 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
452 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
453 BOOST_CHECK(fabs(res.distance) <
DELTA ||
454 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
460 BOOST_CHECK(fabs(res.distance - res_now.distance) <
DELTA);
461 BOOST_CHECK(fabs(res.distance) <
DELTA ||
462 (res.distance > 0 &&
nearlyEqual(res.p1, res_now.p1) &&
466 BOOST_TEST_MESSAGE(
"distance timing: " << dis_time <<
" sec");
467 BOOST_TEST_MESSAGE(
"collision timing: " << col_time <<
" sec");
470 template <
typename BV,
typename TraversalNode>
472 const std::vector<Vec3f>& vertices1,
473 const std::vector<Triangle>& triangles1,
474 const std::vector<Vec3f>& vertices2,
475 const std::vector<Triangle>& triangles2,
495 std::cout <<
"initialize error" << std::endl;
497 node.enable_statistics =
verbose;
506 distance_result.
p1 =
p1;
507 distance_result.
p2 = p2;
510 std::cout <<
"distance " << local_result.
min_distance << std::endl;
512 std::cout << p1[0] <<
" " << p1[1] <<
" " << p1[2] << std::endl;
513 std::cout << p2[0] <<
" " << p2[1] <<
" " << p2[2] << std::endl;
514 std::cout << node.num_bv_tests <<
" " << node.num_leaf_tests << std::endl;
518 template <
typename BV>
520 const std::vector<Triangle>& triangles1,
521 const std::vector<Vec3f>& vertices2,
522 const std::vector<Triangle>& triangles2,
541 MeshDistanceTraversalNode<BV> node;
545 std::cout <<
"initialize error" << std::endl;
547 node.enable_statistics =
verbose;
556 std::cout <<
"distance " << local_result.
min_distance << std::endl;
564 std::cout << node.num_bv_tests <<
" " << node.num_leaf_tests << std::endl;
569 const std::vector<Vec3f>& vertices1,
570 const std::vector<Triangle>& triangles1,
571 const std::vector<Vec3f>& vertices2,
572 const std::vector<Triangle>& triangles2,
589 MeshCollisionTraversalNodeOBB node(request);
593 BOOST_REQUIRE(success);
595 node.enable_statistics =
verbose;
597 collide(&node, request, local_result);
bool nearlyEqual(const Vec3f &a, const Vec3f &b)
request to the distance computation
void loadOBJFile(const char *filename, std::vector< Vec3f > &points, std::vector< Triangle > &triangles)
Load an obj mesh file.
Vec3f nearest_points[2]
nearest points
bool initialize(MeshCollisionTraversalNode< BV, RelativeTransformationIsIdentity > &node, BVHModel< BV > &model1, Transform3f &tf1, BVHModel< BV > &model2, Transform3f &tf2, CollisionResult &result, bool use_refit=false, bool refit_bottomup=false)
Initialize traversal node for collision between two meshes, given the current transforms.
int addSubModel(const std::vector< Vec3f > &ps, const std::vector< Triangle > &ts)
Add a set of triangles in the new BVH model.
bool collide_Test_OBB(const Transform3f &tf, const std::vector< Vec3f > &vertices1, const std::vector< Triangle > &triangles1, const std::vector< Vec3f > &vertices2, const std::vector< Triangle > &triangles2, SplitMethodType split_method, bool verbose)
size_t numContacts() const
number of contacts found
void generateRandomTransforms(FCL_REAL extents[6], std::vector< Transform3f > &transforms, std::size_t n)
Generate n random transforms whose translations are constrained by extents.
void distance_Test(const Transform3f &tf, const std::vector< Vec3f > &vertices1, const std::vector< Triangle > &triangles1, const std::vector< Vec3f > &vertices2, const std::vector< Triangle > &triangles2, SplitMethodType split_method, unsigned int qsize, DistanceRes &distance_result, bool verbose=true)
std::size_t getNbRun(const int &argc, char const *const *argv, std::size_t defaultValue)
Get the argument –nb-run from argv.
request to the collision algorithm
HPP_FCL_DLLAPI FCL_REAL distance(const Matrix3f &R0, const Vec3f &T0, const kIOS &b1, const kIOS &b2, Vec3f *P=NULL, Vec3f *Q=NULL)
Approximate distance between two kIOS bounding volumes.
int beginModel(unsigned int num_tris=0, unsigned int num_vertices=0)
Begin a new BVH model.
FCL_REAL min_distance
minimum distance between two objects. if two objects are in collision, min_distance <= 0...
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
BOOST_AUTO_TEST_CASE(mesh_distance)
SplitMethodType
Three types of split algorithms are provided in FCL as default.
HPP_FCL_DLLAPI std::size_t collide(const CollisionObject *o1, const CollisionObject *o2, const CollisionRequest &request, CollisionResult &result)
Main collision interface: given two collision objects, and the requirements for contacts, including num of max contacts, whether perform exhaustive collision (i.e., returning returning all the contact points), whether return detailed contact information (i.e., normal, contact point, depth; otherwise only contact primitive id is returned), this function performs the collision between them. Return value is the number of contacts generated between the two objects.
shared_ptr< BVSplitter< BV > > bv_splitter
Split rule to split one BV node into two children.
A class describing the split rule that splits each BV node.
void distance_Test_Oriented(const Transform3f &tf, const std::vector< Vec3f > &vertices1, const std::vector< Triangle > &triangles1, const std::vector< Vec3f > &vertices2, const std::vector< Triangle > &triangles2, SplitMethodType split_method, unsigned int qsize, DistanceRes &distance_result, bool verbose=true)
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
int endModel()
End BVH model construction, will build the bounding volume hierarchy.