38 #include <boost/mpl/vector.hpp>
40 #define BOOST_TEST_MODULE COAL_COLLISION
41 #include <boost/test/included/unit_test.hpp>
44 #include <boost/assign/list_of.hpp>
62 #include "../src/collision_node.h"
68 #include "fcl_resources/config.h"
71 namespace utf = boost::unit_test::framework;
76 CoalScalar r_extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
77 std::vector<Transform3s> rotate_transform;
85 convertBV(aabb1, rotate_transform[0], obb1);
93 std::vector<Transform3s> transforms;
96 for (std::size_t i = 0; i < transforms.size(); ++i) {
110 bool overlap_obb = obb1.
overlap(obb2);
117 ShapeShapeCollide<Box, Box>(&box1, box1_tf, &box2, box2_tf, &solver,
121 BOOST_CHECK(overlap_obb == overlap_box);
126 CoalScalar r_extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
127 std::vector<Transform3s> rotate_transform;
135 convertBV(aabb1, rotate_transform[0], obb1);
138 constructBox(aabb1, rotate_transform[0], box1, box1_tf);
141 std::size_t n = 1000;
143 std::vector<Transform3s> transforms;
146 for (std::size_t i = 0; i < transforms.size(); ++i) {
155 bool overlap_obb = obb1.
overlap(obb2);
158 ShapeShapeCollide<Box, Sphere>(&box1, box1_tf, &
sphere, transforms[i],
159 &solver, request, result);
163 BOOST_CHECK(overlap_obb >= overlap_sphere);
170 bool overlap_obb = obb1.
overlap(obb2);
174 ShapeShapeCollide<Box, Capsule>(&box1, box1_tf, &capsule, transforms[i],
175 &solver, request, result);
177 BOOST_CHECK(overlap_obb >= overlap_capsule);
181 Cone cone(len, 2 * len);
184 bool overlap_obb = obb1.
overlap(obb2);
187 ShapeShapeCollide<Box, Cone>(&box1, box1_tf, &cone, transforms[i],
188 &solver, request, result);
190 BOOST_CHECK(overlap_obb >= overlap_cone);
195 computeBV(cylinder, transforms[i], obb2);
197 bool overlap_obb = obb1.
overlap(obb2);
200 ShapeShapeCollide<Box, Cylinder>(&box1, box1_tf, &cylinder, transforms[i],
201 &solver, request, result);
203 BOOST_CHECK(overlap_obb >= overlap_cylinder);
210 std::size_t n = 1000;
212 std::vector<Transform3s> transforms;
222 for (std::size_t i = 0; i < transforms.size(); ++i) {
227 AABB aabb2 =
translate(aabb, transforms[i].getTranslation());
232 bool overlap_aabb = aabb1.
overlap(aabb2);
233 bool overlap_obb = obb1.
overlap(obb2);
234 if (overlap_aabb != overlap_obb) {
235 std::cout << aabb1.
min_ <<
" " << aabb1.
max_ << std::endl;
236 std::cout << aabb2.
min_ <<
" " << aabb2.
max_ << std::endl;
237 std::cout << obb1.
To <<
" " << obb1.
extent <<
" " << obb1.
axes
239 std::cout << obb2.
To <<
" " << obb2.
extent <<
" " << obb2.
axes
243 BOOST_CHECK(overlap_aabb == overlap_obb);
245 std::cout << std::endl;
251 #define BENCHMARK(stream) \
252 if (bench_stream != NULL) { \
253 *bench_stream << (bs_nl ? "" : ", ") << stream; \
256 #define BENCHMARK_HEADER(stream) \
260 #define BENCHMARK_NEXT() \
261 if (bench_stream != NULL && !bs_nl) { \
262 *bench_stream << '\n'; \
273 #define BV_STR_SPECIALIZATION(bv) \
275 const char* str<bv>() { \
278 template <
typename BV>
289 template <
typename T>
293 enum { IS_IMPLEMENTED =
true };
303 template <
typename BV,
bool Oriented,
bool recursive>
306 template <
short N,
bool recursive>
308 enum { IS_IMPLEMENTED =
false };
317 : transforms(_transforms),
319 enable_statistics(false),
337 static const char*
t[] = {
"",
349 template <
typename BV>
350 void query(
const std::vector<Transform3s>& transforms,
352 std::vector<Contacts_t>& contacts) {
356 if (enable_statistics) {
366 typedef shared_ptr<BVH_t> BVHPtr_t;
368 BVHPtr_t model1(
new BVH_t), model2(
new BVH_t);
379 const std::size_t N = transforms.size();
381 contacts.resize(3 * N);
384 BOOST_TEST_MESSAGE(getindent() <<
"BV: " << str<BV>() <<
" oriented");
387 for (std::size_t i = 0; i < transforms.size(); ++i) {
392 MeshCollisionTraversalNode<BV, 0> node(request);
393 node.enable_statistics = enable_statistics;
397 BOOST_REQUIRE(success);
399 collide(&node, request, local_result);
406 if (enable_statistics) {
407 BOOST_TEST_MESSAGE(getindent() <<
"statistics: " << node.num_bv_tests
408 <<
" " << node.num_leaf_tests);
409 BOOST_TEST_MESSAGE(getindent()
421 std::sort(contacts[i].begin(), contacts[i].end());
428 BOOST_TEST_MESSAGE(getindent() <<
"BV: " << str<BV>());
431 for (std::size_t i = 0; i < transforms.size(); ++i) {
436 MeshCollisionTraversalNode<BV, RelativeTransformationIsIdentity> node(
438 node.enable_statistics = enable_statistics;
440 BVH_t* model1_tmp =
new BVH_t(*model1);
442 BVH_t* model2_tmp =
new BVH_t(*model2);
445 bool success =
initialize(node, *model1_tmp, tf1_tmp, *model2_tmp,
446 tf2_tmp, local_result,
true,
true);
447 BOOST_REQUIRE(success);
449 collide(&node, request, local_result);
457 if (enable_statistics) {
458 BOOST_TEST_MESSAGE(getindent() <<
"statistics: " << node.num_bv_tests
459 <<
" " << node.num_leaf_tests);
460 BOOST_TEST_MESSAGE(getindent()
472 std::sort(contacts[i + N].begin(), contacts[i + N].end());
479 BOOST_TEST_MESSAGE(getindent()
480 <<
"BV: " << str<BV>() <<
" oriented non-recursive");
483 for (std::size_t i = 0; i < transforms.size(); ++i) {
488 MeshCollisionTraversalNode<BV, 0> node(request);
489 node.enable_statistics = enable_statistics;
493 BOOST_REQUIRE(success);
495 collide(&node, request, local_result, NULL,
false);
501 if (enable_statistics) {
502 BOOST_TEST_MESSAGE(getindent() <<
"statistics: " << node.num_bv_tests
503 <<
" " << node.num_leaf_tests);
504 BOOST_TEST_MESSAGE(getindent()
516 std::sort(contacts[i + 2 * N].begin(), contacts[i + 2 * N].end());
524 for (std::size_t i = i0; i < i1; ++i) {
527 contacts_ref[i].begin(), contacts_ref[i].end(), contacts[i].begin(),
529 std::inserter(in_ref_but_not_in_i, in_ref_but_not_in_i.begin()));
530 if (!in_ref_but_not_in_i.empty()) {
531 for (std::size_t j = 0; j < in_ref_but_not_in_i.size(); ++j) {
534 false,
"Missed contacts: " << in_ref_but_not_in_i[j].b1 <<
", "
535 << in_ref_but_not_in_i[j].b2);
538 false,
"Missed contacts: " << in_ref_but_not_in_i[j].b1 <<
", "
539 << in_ref_but_not_in_i[j].b2);
546 contacts[i].begin(), contacts[i].end(), contacts_ref[i].begin(),
547 contacts_ref[i].end(),
548 std::inserter(in_i_but_not_in_ref, in_i_but_not_in_ref.begin()));
550 if (!in_i_but_not_in_ref.empty()) {
551 for (std::size_t j = 0; j < in_i_but_not_in_ref.size(); ++j) {
554 false,
"False contacts: " << in_i_but_not_in_ref[j].b1 <<
", "
555 << in_i_but_not_in_ref[j].b2);
558 false,
"False contacts: " << in_i_but_not_in_ref[j].b1 <<
", "
559 << in_i_but_not_in_ref[j].b2);
566 template <
typename BV>
568 if (benchmark)
return;
569 const std::size_t N = transforms.size();
571 BOOST_REQUIRE_EQUAL(contacts.size(), 3 * N);
572 BOOST_REQUIRE_EQUAL(contacts.size(), contacts_ref.size());
575 BOOST_TEST_MESSAGE(getindent() <<
"BV: " << str<BV>() <<
" oriented");
577 check_contacts(0, N,
false);
581 BOOST_TEST_MESSAGE(getindent() <<
"BV: " << str<BV>());
583 check_contacts(N, 2 * N,
true);
587 BOOST_TEST_MESSAGE(getindent()
588 <<
"BV: " << str<BV>() <<
" oriented non-recursive");
590 check_contacts(2 * N, 3 * N,
false);
595 template <
typename BV>
598 BOOST_TEST_MESSAGE(getindent() <<
"splitMethod: " <<
splitMethods[i]);
601 (isInit ? contacts : contacts_ref));
602 if (isInit) check<BV>();
626 std::vector<Transform3s> transforms;
628 #ifndef NDEBUG // if debug mode
633 n =
getNbRun(utf::master_test_suite().argc, utf::master_test_suite().argv, n);
637 Eigen::IOFormat f(Eigen::FullPrecision, 0,
", ",
",",
"",
"",
"(",
")");
638 for (std::size_t i = 0; i < transforms.size(); ++i) {
640 "q" << i <<
"=" << transforms[i].getTranslation().format(f) <<
"+"
641 << transforms[i].getQuatRotation().coeffs().format(f));
650 runner.enable_statistics =
true;
651 boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> >(runner);
657 std::vector<Transform3s> transforms;
664 n =
getNbRun(utf::master_test_suite().argc, utf::master_test_suite().argv, n);
668 Eigen::IOFormat f(Eigen::FullPrecision, 0,
", ",
",",
"",
"",
"(",
")");
669 for (std::size_t i = 0; i < transforms.size(); ++i) {
671 "q" << i <<
"=" << transforms[i].getTranslation().format(f) <<
"+"
672 << transforms[i].getQuatRotation().coeffs().format(f));
680 std::ofstream ofs(
"./collision.benchmark.csv", std::ofstream::out);
687 boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> >(runner1);
692 runner2.enable_statistics =
false;
693 runner2.benchmark =
true;
694 boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> >(runner2);