42 #include <gtest/gtest.h> 65 static std::array<S, 6> static_extents{ {0, 0, 0, 10, 10, 10} };
66 return static_extents;
73 return static_solver1;
80 return static_solver2;
100 const auto volume = 4.0 / 3.0 * pi * radius * radius * radius;
107 test_sphere_shape<double>();
110 template <
typename S>
123 S dt = 1.0 / (N - 1);
128 std::vector<bool> result1(N);
129 for(
int i = 0; i < N; ++i)
147 std::vector<bool> result2(N);
149 for(
int i = 0; i < N; ++i)
165 for(std::size_t i = 0; i < result1.size(); ++i)
174 test_gjkcache<double>();
177 template <
typename Shape1,
typename Shape2>
184 bool check_opposite_normal,
185 typename Shape1::S tol)
187 std::cout <<
"Disagreement between " << comparison_type
188 <<
" and expected_" << comparison_type <<
" for " 192 <<
"tf1.linear: \n" << tf1.linear() << std::endl
193 <<
"tf1.translation: " << tf1.translation().transpose() << std::endl
194 <<
"tf2.linear: \n" << tf2.linear() << std::endl
195 <<
"tf2.translation: " << tf2.translation().transpose() << std::endl
196 <<
"expected_" << comparison_type <<
": " << expected_contact_or_normal
197 <<
"actual_" << comparison_type <<
" : " << actual_contact_or_normal << std::endl;
199 if (check_opposite_normal)
200 std::cout <<
" or " << -expected_contact_or_normal;
202 std::cout << std::endl
203 <<
"difference: " << (actual_contact_or_normal - expected_contact_or_normal).norm() << std::endl
204 <<
"tolerance: " << tol << std::endl;
207 template <
typename Shape1,
typename Shape2>
213 typename Shape1::S actual_depth,
214 typename Shape1::S tol)
216 std::cout <<
"Disagreement between " << comparison_type
217 <<
" and expected_" << comparison_type <<
" for " 221 <<
"tf1.linear: \n" << tf1.linear() << std::endl
222 <<
"tf1.translation: " << tf1.translation().transpose() << std::endl
223 <<
"tf2.linear: \n" << tf2.linear() << std::endl
224 <<
"tf2.translation: " << tf2.translation().transpose() << std::endl
225 <<
"expected_depth: " << expected_depth << std::endl
226 <<
"actual_depth : " << actual_depth << std::endl
227 <<
"difference: " << std::abs(actual_depth - expected_depth) << std::endl
228 <<
"tolerance: " << tol << std::endl;
231 template <
typename Shape1,
typename Shape2>
236 bool check_position =
false,
237 bool check_depth =
false,
238 bool check_normal =
false,
239 bool check_opposite_normal =
false,
240 typename Shape1::S tol = 1e-9)
250 bool contact_equal = actual.
pos.isApprox(expected.
pos, tol);
264 bool normal_equal = actual.
normal.isApprox(expected.
normal, tol);
266 if (!normal_equal && check_opposite_normal)
267 normal_equal = actual.
normal.isApprox(-expected.
normal, tol);
276 template <
typename Shape1,
typename Shape2>
282 bool check_position =
false,
283 bool check_depth =
false,
284 bool check_normal =
false,
285 bool check_opposite_normal =
false,
286 typename Shape1::S tol = 1e-9)
288 using S =
typename Shape1::S;
291 bool sameNumContacts = (actual_contacts.size() == expected_contacts.size());
293 if (!sameNumContacts)
296 <<
"===== [ geometric shape collision test failure report ] ======\n" 302 <<
"tf1.linear : \n" << tf1.linear() <<
"\n" 303 <<
"tf1.translation: " << tf1.translation().transpose() <<
"\n" 307 <<
"tf2.linear : \n" << tf2.linear() <<
"\n" 308 <<
"tf2.translation: " << tf2.translation().transpose() <<
"\n" 310 <<
"The numbers of expected contacts '" 311 << expected_contacts.size()
312 <<
"' and the number of actual contacts '" 313 << actual_contacts.size()
314 <<
"' are not equal.\n" 320 const size_t numContacts = actual_contacts.size();
322 std::vector<int> index_to_actual_contacts(numContacts, -1);
323 std::vector<int> index_to_expected_contacts(numContacts, -1);
325 bool foundAll =
true;
326 for (
size_t i = 0; i < numContacts; ++i)
331 for (
size_t j = 0; j < numContacts; ++j)
333 if (index_to_expected_contacts[j] != -1)
339 s1, tf1, s2, tf2, solver_type,
343 check_normal, check_opposite_normal,
348 index_to_actual_contacts[i] = j;
349 index_to_expected_contacts[j] = i;
354 if (index_to_actual_contacts[i] == -1)
361 <<
"===== [ geometric shape collision test failure report ] ======\n" 367 <<
"tf1.linear : \n" << tf1.linear() <<
"\n" 368 <<
"tf1.translation: " << tf1.translation().transpose() <<
"\n" 372 <<
"tf2.linear : \n" << tf2.linear() <<
"\n" 373 <<
"tf2.translation: " << tf2.translation().transpose() <<
"\n" 375 <<
"[ Expected Contacts: " << numContacts <<
" ]\n";
376 for (
size_t i = 0; i < numContacts; ++i)
380 std::cout <<
"(" << i <<
") pos: " << expected.
pos.transpose() <<
", " 381 <<
"normal: " << expected.
normal.transpose() <<
", " 384 if (index_to_actual_contacts[i] != -1)
385 std::cout <<
"found, actual (" << index_to_actual_contacts[i] <<
")\n";
387 std::cout <<
"not found!\n";
390 <<
"[ Actual Contacts: " << numContacts <<
" ]\n";
391 for (
size_t i = 0; i < numContacts; ++i)
395 std::cout <<
"(" << i <<
") pos: " << actual.
pos.transpose() <<
", " 396 <<
"normal: " << actual.
normal.transpose() <<
", " 399 if (index_to_expected_contacts[i] != -1)
400 std::cout <<
"found, expected (" << index_to_expected_contacts[i] <<
")\n";
402 std::cout <<
"not found!\n";
411 template <
typename S>
415 contacts.resize(numContacts);
417 for (
size_t i = 0; i < numContacts; ++i)
421 contacts[i].pos = cnt.pos;
422 contacts[i].normal = cnt.normal;
423 contacts[i].penetration_depth = cnt.penetration_depth;
427 template <
typename Shape1,
typename Shape2>
434 bool check_position =
true,
435 bool check_depth =
true,
436 bool check_normal =
true,
437 bool check_opposite_normal =
false,
438 typename Shape1::S tol = 1e-9)
440 using S =
typename Shape1::S;
447 std::vector<ContactPoint<S>> actual_contacts;
456 res = solver1<S>().shapeIntersect(s1, tf1, s2, tf2,
nullptr);
460 res = solver2<S>().shapeIntersect(s1, tf1, s2, tf2,
nullptr);
464 std::cerr <<
"Invalid GJK solver. Test aborted." << std::endl;
472 res = solver1<S>().shapeIntersect(s1, tf1, s2, tf2, &actual_contacts);
476 res = solver2<S>().shapeIntersect(s1, tf1, s2, tf2, &actual_contacts);
480 std::cerr <<
"Invalid GJK solver. Test aborted." << std::endl;
487 expected_contacts, actual_contacts,
490 check_normal, check_opposite_normal,
499 res = (
collide(&s1, tf1, &s2, tf2, request, result) > 0);
505 res = (
collide(&s1, tf1, &s2, tf2, request, result) > 0);
511 expected_contacts, actual_contacts,
514 check_normal, check_opposite_normal,
543 template <
typename S>
555 std::vector<ContactPoint<S>> contacts;
568 contacts[0].normal << 1, 0, 0;
569 contacts[0].pos << 20, 0, 0;
570 contacts[0].penetration_depth = 0.0;
584 contacts[0].normal << 1, 0, 0;
585 contacts[0].pos << 20.0 - 0.1 * 20.0/(20.0 + 10.0), 0, 0;
586 contacts[0].penetration_depth = 0.1;
592 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
593 contacts[0].pos = transform * Vector3<S>(20.0 - 0.1 * 20.0/(20.0 + 10.0), 0, 0);
594 contacts[0].penetration_depth = 0.1;
600 contacts[0].normal.setZero();
601 contacts[0].pos.setZero();
602 contacts[0].penetration_depth = 20.0 + 10.0;
608 contacts[0].normal.setZero();
610 contacts[0].penetration_depth = 20.0 + 10.0;
616 contacts[0].normal << -1, 0, 0;
617 contacts[0].pos << -20.0 + 0.1 * 20.0/(20.0 + 10.0), 0, 0;
618 contacts[0].penetration_depth = 0.1;
624 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
625 contacts[0].pos = transform * Vector3<S>(-20.0 + 0.1 * 20.0/(20.0 + 10.0), 0, 0);
626 contacts[0].penetration_depth = 0.1;
632 contacts[0].normal << -1, 0, 0;
633 contacts[0].pos << -20, 0, 0;
634 contacts[0].penetration_depth = 0.0;
646 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_spheresphere)
649 test_shapeIntersection_spheresphere<double>();
652 template <
typename S>
655 return c1[2] < c2[2];
658 template <
typename S>
661 return cp1.
pos[2] < cp2.
pos[2];
688 template <
typename Derived>
691 using S =
typename Derived::RealScalar;
697 std::vector<Vector3<S>> vertices(8);
698 vertices[0] << 1, 1, 1;
699 vertices[1] << 1, 1, -1;
700 vertices[2] << 1, -1, 1;
701 vertices[3] << 1, -1, -1;
702 vertices[4] << -1, 1, 1;
703 vertices[5] << -1, 1, -1;
704 vertices[6] << -1, -1, 1;
705 vertices[7] << -1, -1, -1;
707 for (
int i = 0; i < 8; ++i)
709 vertices[i][0] *= 0.5 * s2.
side[0];
710 vertices[i][1] *= 0.5 * s2.
side[1];
711 vertices[i][2] *= 0.5 * s2.
side[2];
717 std::vector<ContactPoint<S>> contacts;
720 bool res = solver1<S>().shapeIntersect(s1, tf1, s2, tf2, &contacts);
724 for (
int i = 0; i < 8; ++i)
725 vertices[i] = tf2 * vertices[i];
728 std::sort(vertices.begin(), vertices.end(), compareContactPointds1<S>);
729 std::sort(contacts.begin(), contacts.end(), compareContactPointds2<S>);
732 size_t numContacts = contacts.size();
733 numContacts =
std::min(static_cast<size_t>(1), numContacts);
736 for (
size_t i = 0; i < numContacts; ++i)
740 Vector3<S> contact_pos(vertices[i]);
743 <<
"\n\tExpected: " << contact_pos
744 <<
"\n\tFound: " << contacts[i].pos;
745 EXPECT_TRUE(Vector3<S>(0, 0, 1).isApprox(contacts[i].normal));
749 template <
typename S>
761 std::vector<ContactPoint<S>> contacts;
769 contacts[0].normal << 1, 0, 0;
770 contacts[1].normal << 1, 0, 0;
771 contacts[2].normal << 1, 0, 0;
772 contacts[3].normal << 1, 0, 0;
779 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
780 contacts[1].normal = transform.linear() *
Vector3<S>(1, 0, 0);
781 contacts[2].normal = transform.linear() *
Vector3<S>(1, 0, 0);
782 contacts[3].normal = transform.linear() *
Vector3<S>(1, 0, 0);
788 contacts[0].normal = Vector3<S>(1, 0, 0);
789 contacts[1].normal = Vector3<S>(1, 0, 0);
790 contacts[2].normal = Vector3<S>(1, 0, 0);
791 contacts[3].normal = Vector3<S>(1, 0, 0);
801 contacts[0].normal = Vector3<S>(1, 0, 0);
802 contacts[1].normal = Vector3<S>(1, 0, 0);
803 contacts[2].normal = Vector3<S>(1, 0, 0);
804 contacts[3].normal = Vector3<S>(1, 0, 0);
810 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
811 contacts[1].normal = transform.linear() * Vector3<S>(1, 0, 0);
812 contacts[2].normal = transform.linear() * Vector3<S>(1, 0, 0);
813 contacts[3].normal = transform.linear() * Vector3<S>(1, 0, 0);
817 #if !defined(FCL_OS_MACOS) || !defined(NDEBUG) 819 for (
uint32 i = 0; i < numTests; ++i)
831 test_shapeIntersection_boxbox<double>();
834 template <
typename S>
838 const bool collides =
true;
839 const bool check_position =
true;
840 const bool check_depth =
true;
841 const bool check_normal =
true;
842 const bool check_opposite_normal =
false;
853 std::vector<ContactPoint<S>> contacts;
862 contacts[0].normal << -1, 0, 0;
864 !check_position, !check_depth, check_normal);
870 !check_position, !check_depth, !check_normal);
877 !check_position, !check_depth, !check_normal);
886 contacts[0].normal << 1, 0, 0;
888 !check_position, !check_depth, check_normal);
893 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
895 !check_position, !check_depth, check_normal,
896 !check_opposite_normal, 1e-4);
899 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_spherebox)
902 test_shapeIntersection_spherebox<double>();
905 template <
typename S>
917 std::vector<ContactPoint<S>> contacts;
934 contacts[0].normal << 1, 0, 0;
940 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
946 contacts[0].normal << 1, 0, 0;
953 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
965 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_spherecapsule)
968 test_shapeIntersection_spherecapsule<double>();
971 template <
typename S>
985 transform.linear() = R;
986 transform.translation() << 8.40188, 3.94383, 7.83099;
988 std::vector<ContactPoint<S>> contacts;
1005 contacts[0].normal << 1, 0, 0;
1009 #if !defined(FCL_OS_MACOS) || !defined(NDEBUG) 1015 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
1016 testShapeIntersection(s1, tf1, s2, tf2,
GST_LIBCCD,
true, contacts,
false,
false,
true,
false, 1e-5);
1028 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_cylindercylinder)
1031 test_shapeIntersection_cylindercylinder<double>();
1034 template <
typename S>
1046 std::vector<ContactPoint<S>> contacts;
1063 contacts[0].normal << 1, 0, 0;
1069 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
1070 testShapeIntersection(s1, tf1, s2, tf2,
GST_LIBCCD,
true, contacts,
false,
false,
true,
false, 5e-5);
1083 contacts[0].normal << 0, 0, 1;
1089 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
1090 testShapeIntersection(s1, tf1, s2, tf2,
GST_LIBCCD,
true, contacts,
false,
false,
true,
false, 1e-5);
1096 test_shapeIntersection_conecone<double>();
1099 template <
typename S>
1111 std::vector<ContactPoint<S>> contacts;
1128 contacts[0].normal << 1, 0, 0;
1129 testShapeIntersection(s1, tf1, s2, tf2,
GST_LIBCCD,
true, contacts,
false,
false,
true,
false, 0.061);
1134 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
1135 testShapeIntersection(s1, tf1, s2, tf2,
GST_LIBCCD,
true, contacts,
false,
false,
true,
false, 0.46);
1148 contacts[0].normal << 0, 0, 1;
1154 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
1155 testShapeIntersection(s1, tf1, s2, tf2,
GST_LIBCCD,
true, contacts,
false,
false,
true,
false, 1e-4);
1162 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 10.01)));
1169 test_shapeIntersection_cylindercone<double>();
1172 template <
typename S>
1185 std::vector<ContactPoint<S>> contacts;
1242 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_ellipsoidellipsoid)
1245 test_shapeIntersection_ellipsoidellipsoid<double>();
1248 template <
typename S>
1263 res = solver1<S>().shapeTriangleIntersect(s,
Transform3<S>::Identity(), t[0], t[1], t[2],
nullptr,
nullptr,
nullptr);
1266 res = solver1<S>().shapeTriangleIntersect(s, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
1271 t[1] << 9.9, -20, 0;
1273 res = solver1<S>().shapeTriangleIntersect(s,
Transform3<S>::Identity(), t[0], t[1], t[2],
nullptr,
nullptr,
nullptr);
1276 res = solver1<S>().shapeTriangleIntersect(s, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
1279 res = solver1<S>().shapeTriangleIntersect(s,
Transform3<S>::Identity(), t[0], t[1], t[2],
nullptr,
nullptr, &normal);
1281 EXPECT_TRUE(normal.isApprox(
Vector3<S>(1, 0, 0), 1e-9));
1283 res = solver1<S>().shapeTriangleIntersect(s, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr, &normal);
1285 EXPECT_TRUE(normal.isApprox(transform.linear() *
Vector3<S>(1, 0, 0), 1e-9));
1288 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_spheretriangle)
1291 test_shapeIntersection_spheretriangle<double>();
1294 template <
typename S>
1314 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
1325 #if !defined(FCL_OS_MACOS) || !defined(NDEBUG) 1326 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
1332 EXPECT_TRUE(normal.isApprox(
Vector3<S>(1, 0, 0), 1e-9));
1335 #if !defined(FCL_OS_MACOS) || !defined(NDEBUG) 1336 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr, &normal);
1338 EXPECT_TRUE(normal.isApprox(transform.linear() *
Vector3<S>(1, 0, 0), 1e-9));
1342 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_halfspacetriangle)
1345 test_shapeIntersection_halfspacetriangle<double>();
1348 template <
typename S>
1368 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
1373 t[1] << -0.1, -20, 0;
1374 t[2] << -0.1, 20, 0;
1378 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
1383 EXPECT_TRUE(normal.isApprox(
Vector3<S>(1, 0, 0), 1e-9));
1385 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr, &normal);
1387 EXPECT_TRUE(normal.isApprox(transform.linear() *
Vector3<S>(1, 0, 0), 1e-9));
1390 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_planetriangle)
1393 test_shapeIntersection_planetriangle<double>();
1396 template <
typename S>
1408 std::vector<ContactPoint<S>> contacts;
1413 contacts[0].pos << -5, 0, 0;
1414 contacts[0].penetration_depth = 10;
1415 contacts[0].normal << -1, 0, 0;
1421 contacts[0].pos = transform *
Vector3<S>(-5, 0, 0);
1422 contacts[0].penetration_depth = 10;
1423 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
1429 contacts[0].pos << -2.5, 0, 0;
1430 contacts[0].penetration_depth = 15;
1431 contacts[0].normal << -1, 0, 0;
1437 contacts[0].pos = transform * Vector3<S>(-2.5, 0, 0);
1438 contacts[0].penetration_depth = 15;
1439 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
1445 contacts[0].pos << -7.5, 0, 0;
1446 contacts[0].penetration_depth = 5;
1447 contacts[0].normal << -1, 0, 0;
1453 contacts[0].pos = transform * Vector3<S>(-7.5, 0, 0);
1454 contacts[0].penetration_depth = 5;
1455 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
1469 contacts[0].pos << 0.05, 0, 0;
1470 contacts[0].penetration_depth = 20.1;
1471 contacts[0].normal << -1, 0, 0;
1477 contacts[0].pos = transform * Vector3<S>(0.05, 0, 0);
1478 contacts[0].penetration_depth = 20.1;
1479 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
1483 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_halfspacesphere)
1486 test_shapeIntersection_halfspacesphere<double>();
1489 template <
typename S>
1501 std::vector<ContactPoint<S>> contacts;
1506 contacts[0].pos.setZero();
1507 contacts[0].penetration_depth = 10;
1508 contacts[0].normal << 1, 0, 0;
1509 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
1514 contacts[0].pos = transform *
Vector3<S>(0, 0, 0);
1515 contacts[0].penetration_depth = 10;
1516 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
1517 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
1522 contacts[0].pos << 5, 0, 0;
1523 contacts[0].penetration_depth = 5;
1524 contacts[0].normal << 1, 0, 0;
1530 contacts[0].pos = transform * Vector3<S>(5, 0, 0);
1531 contacts[0].penetration_depth = 5;
1532 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
1538 contacts[0].pos << -5, 0, 0;
1539 contacts[0].penetration_depth = 5;
1540 contacts[0].normal << -1, 0, 0;
1546 contacts[0].pos = transform * Vector3<S>(-5, 0, 0);
1547 contacts[0].penetration_depth = 5;
1548 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
1571 test_shapeIntersection_planesphere<double>();
1574 template <
typename S>
1586 std::vector<ContactPoint<S>> contacts;
1591 contacts[0].pos << -1.25, 0, 0;
1592 contacts[0].penetration_depth = 2.5;
1593 contacts[0].normal << -1, 0, 0;
1599 contacts[0].pos = transform *
Vector3<S>(-1.25, 0, 0);
1600 contacts[0].penetration_depth = 2.5;
1601 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1607 contacts[0].pos << -0.625, 0, 0;
1608 contacts[0].penetration_depth = 3.75;
1609 contacts[0].normal << -1, 0, 0;
1615 contacts[0].pos = transform *
Vector3<S>(-0.625, 0, 0);
1616 contacts[0].penetration_depth = 3.75;
1617 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1623 contacts[0].pos << -1.875, 0, 0;
1624 contacts[0].penetration_depth = 1.25;
1625 contacts[0].normal << -1, 0, 0;
1631 contacts[0].pos = transform *
Vector3<S>(-1.875, 0, 0);
1632 contacts[0].penetration_depth = 1.25;
1633 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1639 contacts[0].pos << 0.005, 0, 0;
1640 contacts[0].penetration_depth = 5.01;
1641 contacts[0].normal << -1, 0, 0;
1647 contacts[0].pos = transform *
Vector3<S>(0.005, 0, 0);
1648 contacts[0].penetration_depth = 5.01;
1649 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1669 test_shapeIntersection_halfspacebox<double>();
1672 template <
typename S>
1684 std::vector<ContactPoint<S>> contacts;
1689 contacts[0].pos << 0, 0, 0;
1690 contacts[0].penetration_depth = 2.5;
1691 contacts[0].normal << 1, 0, 0;
1692 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
1697 contacts[0].pos = transform *
Vector3<S>(0, 0, 0);
1698 contacts[0].penetration_depth = 2.5;
1699 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
1700 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
1705 contacts[0].pos << 1.25, 0, 0;
1706 contacts[0].penetration_depth = 1.25;
1707 contacts[0].normal << 1, 0, 0;
1713 contacts[0].pos = transform * Vector3<S>(1.25, 0, 0);
1714 contacts[0].penetration_depth = 1.25;
1715 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
1721 contacts[0].pos << -1.25, 0, 0;
1722 contacts[0].penetration_depth = 1.25;
1723 contacts[0].normal << -1, 0, 0;
1729 contacts[0].pos = transform * Vector3<S>(-1.25, 0, 0);
1730 contacts[0].penetration_depth = 1.25;
1731 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
1759 test_shapeIntersection_planebox<double>();
1762 template <
typename S>
1774 std::vector<ContactPoint<S>> contacts;
1779 contacts[0].pos << -2.5, 0, 0;
1780 contacts[0].penetration_depth = 5.0;
1781 contacts[0].normal << -1, 0, 0;
1787 contacts[0].pos = transform *
Vector3<S>(-2.5, 0, 0);
1788 contacts[0].penetration_depth = 5.0;
1789 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1795 contacts[0].pos << -1.875, 0, 0;
1796 contacts[0].penetration_depth = 6.25;
1797 contacts[0].normal << -1, 0, 0;
1803 contacts[0].pos = transform *
Vector3<S>(-1.875, 0, 0);
1804 contacts[0].penetration_depth = 6.25;
1805 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1811 contacts[0].pos << -3.125, 0, 0;
1812 contacts[0].penetration_depth = 3.75;
1813 contacts[0].normal << -1, 0, 0;
1819 contacts[0].pos = transform *
Vector3<S>(-3.125, 0, 0);
1820 contacts[0].penetration_depth = 3.75;
1821 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1827 contacts[0].pos << 0.005, 0, 0;
1828 contacts[0].penetration_depth = 10.01;
1829 contacts[0].normal << -1, 0, 0;
1835 contacts[0].pos = transform *
Vector3<S>(0.005, 0, 0);
1836 contacts[0].penetration_depth = 10.01;
1837 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
1856 contacts[0].pos << 0, -5.0, 0;
1857 contacts[0].penetration_depth = 10.0;
1858 contacts[0].normal << 0, -1, 0;
1864 contacts[0].pos = transform * Vector3<S>(0, -5.0, 0);
1865 contacts[0].penetration_depth = 10.0;
1866 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
1872 contacts[0].pos << 0, -4.375, 0;
1873 contacts[0].penetration_depth = 11.25;
1874 contacts[0].normal << 0, -1, 0;
1880 contacts[0].pos = transform * Vector3<S>(0, -4.375, 0);
1881 contacts[0].penetration_depth = 11.25;
1882 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
1888 contacts[0].pos << 0, -5.625, 0;
1889 contacts[0].penetration_depth = 8.75;
1890 contacts[0].normal << 0, -1, 0;
1896 contacts[0].pos = transform * Vector3<S>(0, -5.625, 0);
1897 contacts[0].penetration_depth = 8.75;
1898 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
1904 contacts[0].pos << 0, 0.005, 0;
1905 contacts[0].penetration_depth = 20.01;
1906 contacts[0].normal << 0, -1, 0;
1912 contacts[0].pos = transform * Vector3<S>(0, 0.005, 0);
1913 contacts[0].penetration_depth = 20.01;
1914 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
1933 contacts[0].pos << 0, 0, -10.0;
1934 contacts[0].penetration_depth = 20.0;
1935 contacts[0].normal << 0, 0, -1;
1941 contacts[0].pos = transform * Vector3<S>(0, 0, -10.0);
1942 contacts[0].penetration_depth = 20.0;
1943 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
1949 contacts[0].pos << 0, 0, -9.375;
1950 contacts[0].penetration_depth = 21.25;
1951 contacts[0].normal << 0, 0, -1;
1957 contacts[0].pos = transform * Vector3<S>(0, 0, -9.375);
1958 contacts[0].penetration_depth = 21.25;
1959 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
1965 contacts[0].pos << 0, 0, -10.625;
1966 contacts[0].penetration_depth = 18.75;
1967 contacts[0].normal << 0, 0, -1;
1971 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -1.25)));
1973 contacts[0].pos = transform * Vector3<S>(0, 0, -10.625);
1974 contacts[0].penetration_depth = 18.75;
1975 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
1981 contacts[0].pos << 0, 0, 0.005;
1982 contacts[0].penetration_depth = 40.01;
1983 contacts[0].normal << 0, 0, -1;
1987 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 20.01)));
1989 contacts[0].pos = transform * Vector3<S>(0, 0, 0.005);
1990 contacts[0].penetration_depth = 40.01;
1991 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
1999 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -20.01)));
2003 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_halfspaceellipsoid)
2006 test_shapeIntersection_halfspaceellipsoid<double>();
2009 template <
typename S>
2021 std::vector<ContactPoint<S>> contacts;
2026 contacts[0].pos << 0, 0, 0;
2027 contacts[0].penetration_depth = 5.0;
2028 contacts[0].normal << -1, 0, 0;
2029 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2034 contacts[0].pos = transform *
Vector3<S>(0, 0, 0);
2035 contacts[0].penetration_depth = 5.0;
2036 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
2037 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2042 contacts[0].pos << 1.25, 0, 0;
2043 contacts[0].penetration_depth = 3.75;
2044 contacts[0].normal << 1, 0, 0;
2050 contacts[0].pos = transform * Vector3<S>(1.25, 0, 0);
2051 contacts[0].penetration_depth = 3.75;
2052 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
2058 contacts[0].pos << -1.25, 0, 0;
2059 contacts[0].penetration_depth = 3.75;
2060 contacts[0].normal << -1, 0, 0;
2066 contacts[0].pos = transform * Vector3<S>(-1.25, 0, 0);
2067 contacts[0].penetration_depth = 3.75;
2068 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
2090 hs =
Plane<S>(Vector3<S>(0, 1, 0), 0);
2095 contacts[0].pos << 0, 0.0, 0;
2096 contacts[0].penetration_depth = 10.0;
2097 contacts[0].normal << 0, -1, 0;
2098 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2103 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
2104 contacts[0].penetration_depth = 10.0;
2105 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2106 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2111 contacts[0].pos << 0, 1.25, 0;
2112 contacts[0].penetration_depth = 8.75;
2113 contacts[0].normal << 0, 1, 0;
2119 contacts[0].pos = transform * Vector3<S>(0, 1.25, 0);
2120 contacts[0].penetration_depth = 8.75;
2121 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
2127 contacts[0].pos << 0, -1.25, 0;
2128 contacts[0].penetration_depth = 8.75;
2129 contacts[0].normal << 0, -1, 0;
2135 contacts[0].pos = transform * Vector3<S>(0, -1.25, 0);
2136 contacts[0].penetration_depth = 8.75;
2137 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2159 hs =
Plane<S>(Vector3<S>(0, 0, 1), 0);
2164 contacts[0].pos << 0, 0, 0;
2165 contacts[0].penetration_depth = 20.0;
2166 contacts[0].normal << 0, 0, -1;
2167 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2172 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
2173 contacts[0].penetration_depth = 20.0;
2174 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2175 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2180 contacts[0].pos << 0, 0, 1.25;
2181 contacts[0].penetration_depth = 18.75;
2182 contacts[0].normal << 0, 0, 1;
2188 contacts[0].pos = transform * Vector3<S>(0, 0, 1.25);
2189 contacts[0].penetration_depth = 18.75;
2190 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
2196 contacts[0].pos << 0, 0, -1.25;
2197 contacts[0].penetration_depth = 18.75;
2198 contacts[0].normal << 0, 0, -1;
2202 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -1.25)));
2204 contacts[0].pos = transform * Vector3<S>(0, 0, -1.25);
2205 contacts[0].penetration_depth = 18.75;
2206 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2214 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 20.01)));
2222 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -20.01)));
2226 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_planeellipsoid)
2229 test_shapeIntersection_planeellipsoid<double>();
2232 template <
typename S>
2244 std::vector<ContactPoint<S>> contacts;
2249 contacts[0].pos << -2.5, 0, 0;
2250 contacts[0].penetration_depth = 5;
2251 contacts[0].normal << -1, 0, 0;
2257 contacts[0].pos = transform *
Vector3<S>(-2.5, 0, 0);
2258 contacts[0].penetration_depth = 5;
2259 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2265 contacts[0].pos << -1.25, 0, 0;
2266 contacts[0].penetration_depth = 7.5;
2267 contacts[0].normal << -1, 0, 0;
2273 contacts[0].pos = transform *
Vector3<S>(-1.25, 0, 0);
2274 contacts[0].penetration_depth = 7.5;
2275 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2281 contacts[0].pos << -3.75, 0, 0;
2282 contacts[0].penetration_depth = 2.5;
2283 contacts[0].normal << -1, 0, 0;
2289 contacts[0].pos = transform *
Vector3<S>(-3.75, 0, 0);
2290 contacts[0].penetration_depth = 2.5;
2291 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2297 contacts[0].pos << 0.05, 0, 0;
2298 contacts[0].penetration_depth = 10.1;
2299 contacts[0].normal << -1, 0, 0;
2305 contacts[0].pos = transform *
Vector3<S>(0.05, 0, 0);
2306 contacts[0].penetration_depth = 10.1;
2307 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2326 contacts[0].pos << 0, -2.5, 0;
2327 contacts[0].penetration_depth = 5;
2328 contacts[0].normal << 0, -1, 0;
2334 contacts[0].pos = transform * Vector3<S>(0, -2.5, 0);
2335 contacts[0].penetration_depth = 5;
2336 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2342 contacts[0].pos << 0, -1.25, 0;
2343 contacts[0].penetration_depth = 7.5;
2344 contacts[0].normal << 0, -1, 0;
2350 contacts[0].pos = transform * Vector3<S>(0, -1.25, 0);
2351 contacts[0].penetration_depth = 7.5;
2352 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2358 contacts[0].pos << 0, -3.75, 0;
2359 contacts[0].penetration_depth = 2.5;
2360 contacts[0].normal << 0, -1, 0;
2366 contacts[0].pos = transform * Vector3<S>(0, -3.75, 0);
2367 contacts[0].penetration_depth = 2.5;
2368 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2374 contacts[0].pos << 0, 0.05, 0;
2375 contacts[0].penetration_depth = 10.1;
2376 contacts[0].normal << 0, -1, 0;
2382 contacts[0].pos = transform * Vector3<S>(0, 0.05, 0);
2383 contacts[0].penetration_depth = 10.1;
2384 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2403 contacts[0].pos << 0, 0, -5;
2404 contacts[0].penetration_depth = 10;
2405 contacts[0].normal << 0, 0, -1;
2411 contacts[0].pos = transform * Vector3<S>(0, 0, -5);
2412 contacts[0].penetration_depth = 10;
2413 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2419 contacts[0].pos << 0, 0, -3.75;
2420 contacts[0].penetration_depth = 12.5;
2421 contacts[0].normal << 0, 0, -1;
2427 contacts[0].pos = transform * Vector3<S>(0, 0, -3.75);
2428 contacts[0].penetration_depth = 12.5;
2429 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2435 contacts[0].pos << 0, 0, -6.25;
2436 contacts[0].penetration_depth = 7.5;
2437 contacts[0].normal << 0, 0, -1;
2441 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -2.5)));
2443 contacts[0].pos = transform * Vector3<S>(0, 0, -6.25);
2444 contacts[0].penetration_depth = 7.5;
2445 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2451 contacts[0].pos << 0, 0, 0.05;
2452 contacts[0].penetration_depth = 20.1;
2453 contacts[0].normal << 0, 0, -1;
2457 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 10.1)));
2459 contacts[0].pos = transform * Vector3<S>(0, 0, 0.05);
2460 contacts[0].penetration_depth = 20.1;
2461 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2469 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -10.1)));
2473 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_halfspacecapsule)
2476 test_shapeIntersection_halfspacecapsule<double>();
2479 template <
typename S>
2491 std::vector<ContactPoint<S>> contacts;
2496 contacts[0].pos << 0, 0, 0;
2497 contacts[0].penetration_depth = 5;
2498 contacts[0].normal << 1, 0, 0;
2499 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2504 contacts[0].pos = transform *
Vector3<S>(0, 0, 0);
2505 contacts[0].penetration_depth = 5;
2506 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
2507 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2512 contacts[0].pos << 2.5, 0, 0;
2513 contacts[0].penetration_depth = 2.5;
2514 contacts[0].normal << 1, 0, 0;
2520 contacts[0].pos = transform * Vector3<S>(2.5, 0, 0);
2521 contacts[0].penetration_depth = 2.5;
2522 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
2528 contacts[0].pos << -2.5, 0, 0;
2529 contacts[0].penetration_depth = 2.5;
2530 contacts[0].normal << -1, 0, 0;
2536 contacts[0].pos = transform * Vector3<S>(-2.5, 0, 0);
2537 contacts[0].penetration_depth = 2.5;
2538 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
2560 hs =
Plane<S>(Vector3<S>(0, 1, 0), 0);
2565 contacts[0].pos << 0, 0, 0;
2566 contacts[0].penetration_depth = 5;
2567 contacts[0].normal << 0, 1, 0;
2568 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2573 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
2574 contacts[0].penetration_depth = 5;
2575 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
2576 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2581 contacts[0].pos << 0, 2.5, 0;
2582 contacts[0].penetration_depth = 2.5;
2583 contacts[0].normal << 0, 1, 0;
2589 contacts[0].pos = transform * Vector3<S>(0, 2.5, 0);
2590 contacts[0].penetration_depth = 2.5;
2591 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
2597 contacts[0].pos << 0, -2.5, 0;
2598 contacts[0].penetration_depth = 2.5;
2599 contacts[0].normal << 0, -1, 0;
2605 contacts[0].pos = transform * Vector3<S>(0, -2.5, 0);
2606 contacts[0].penetration_depth = 2.5;
2607 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2629 hs =
Plane<S>(Vector3<S>(0, 0, 1), 0);
2634 contacts[0].pos << 0, 0, 0;
2635 contacts[0].penetration_depth = 10;
2636 contacts[0].normal << 0, 0, 1;
2637 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2642 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
2643 contacts[0].penetration_depth = 10;
2644 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
2645 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2650 contacts[0].pos << 0, 0, 2.5;
2651 contacts[0].penetration_depth = 7.5;
2652 contacts[0].normal << 0, 0, 1;
2658 contacts[0].pos = transform * Vector3<S>(0, 0, 2.5);
2659 contacts[0].penetration_depth = 7.5;
2660 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
2666 contacts[0].pos << 0, 0, -2.5;
2667 contacts[0].penetration_depth = 7.5;
2668 contacts[0].normal << 0, 0, -1;
2672 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -2.5)));
2674 contacts[0].pos = transform * Vector3<S>(0, 0, -2.5);
2675 contacts[0].penetration_depth = 7.5;
2676 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2684 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 10.1)));
2692 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -10.1)));
2699 test_shapeIntersection_planecapsule<double>();
2702 template <
typename S>
2714 std::vector<ContactPoint<S>> contacts;
2719 contacts[0].pos << -2.5, 0, 0;
2720 contacts[0].penetration_depth = 5;
2721 contacts[0].normal << -1, 0, 0;
2727 contacts[0].pos = transform *
Vector3<S>(-2.5, 0, 0);
2728 contacts[0].penetration_depth = 5;
2729 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2735 contacts[0].pos << -1.25, 0, 0;
2736 contacts[0].penetration_depth = 7.5;
2737 contacts[0].normal << -1, 0, 0;
2743 contacts[0].pos = transform *
Vector3<S>(-1.25, 0, 0);
2744 contacts[0].penetration_depth = 7.5;
2745 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2751 contacts[0].pos << -3.75, 0, 0;
2752 contacts[0].penetration_depth = 2.5;
2753 contacts[0].normal << -1, 0, 0;
2759 contacts[0].pos = transform *
Vector3<S>(-3.75, 0, 0);
2760 contacts[0].penetration_depth = 2.5;
2761 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2767 contacts[0].pos << 0.05, 0, 0;
2768 contacts[0].penetration_depth = 10.1;
2769 contacts[0].normal << -1, 0, 0;
2775 contacts[0].pos = transform *
Vector3<S>(0.05, 0, 0);
2776 contacts[0].penetration_depth = 10.1;
2777 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
2796 contacts[0].pos << 0, -2.5, 0;
2797 contacts[0].penetration_depth = 5;
2798 contacts[0].normal << 0, -1, 0;
2804 contacts[0].pos = transform * Vector3<S>(0, -2.5, 0);
2805 contacts[0].penetration_depth = 5;
2806 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2812 contacts[0].pos << 0, -1.25, 0;
2813 contacts[0].penetration_depth = 7.5;
2814 contacts[0].normal << 0, -1, 0;
2820 contacts[0].pos = transform * Vector3<S>(0, -1.25, 0);
2821 contacts[0].penetration_depth = 7.5;
2822 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2828 contacts[0].pos << 0, -3.75, 0;
2829 contacts[0].penetration_depth = 2.5;
2830 contacts[0].normal << 0, -1, 0;
2836 contacts[0].pos = transform * Vector3<S>(0, -3.75, 0);
2837 contacts[0].penetration_depth = 2.5;
2838 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2844 contacts[0].pos << 0, 0.05, 0;
2845 contacts[0].penetration_depth = 10.1;
2846 contacts[0].normal << 0, -1, 0;
2852 contacts[0].pos = transform * Vector3<S>(0, 0.05, 0);
2853 contacts[0].penetration_depth = 10.1;
2854 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
2873 contacts[0].pos << 0, 0, -2.5;
2874 contacts[0].penetration_depth = 5;
2875 contacts[0].normal << 0, 0, -1;
2881 contacts[0].pos = transform * Vector3<S>(0, 0, -2.5);
2882 contacts[0].penetration_depth = 5;
2883 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2889 contacts[0].pos << 0, 0, -1.25;
2890 contacts[0].penetration_depth = 7.5;
2891 contacts[0].normal << 0, 0, -1;
2897 contacts[0].pos = transform * Vector3<S>(0, 0, -1.25);
2898 contacts[0].penetration_depth = 7.5;
2899 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2905 contacts[0].pos << 0, 0, -3.75;
2906 contacts[0].penetration_depth = 2.5;
2907 contacts[0].normal << 0, 0, -1;
2911 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -2.5)));
2913 contacts[0].pos = transform * Vector3<S>(0, 0, -3.75);
2914 contacts[0].penetration_depth = 2.5;
2915 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2921 contacts[0].pos << 0, 0, 0.05;
2922 contacts[0].penetration_depth = 10.1;
2923 contacts[0].normal << 0, 0, -1;
2927 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 5.1)));
2929 contacts[0].pos = transform * Vector3<S>(0, 0, 0.05);
2930 contacts[0].penetration_depth = 10.1;
2931 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
2939 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -5.1)));
2943 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_halfspacecylinder)
2946 test_shapeIntersection_halfspacecylinder<double>();
2949 template <
typename S>
2961 std::vector<ContactPoint<S>> contacts;
2966 contacts[0].pos << 0, 0, 0;
2967 contacts[0].penetration_depth = 5;
2968 contacts[0].normal << 1, 0, 0;
2969 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2974 contacts[0].pos = transform *
Vector3<S>(0, 0, 0);
2975 contacts[0].penetration_depth = 5;
2976 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
2977 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
2982 contacts[0].pos << 2.5, 0, 0;
2983 contacts[0].penetration_depth = 2.5;
2984 contacts[0].normal << 1, 0, 0;
2990 contacts[0].pos = transform * Vector3<S>(2.5, 0, 0);
2991 contacts[0].penetration_depth = 2.5;
2992 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
2998 contacts[0].pos << -2.5, 0, 0;
2999 contacts[0].penetration_depth = 2.5;
3000 contacts[0].normal << -1, 0, 0;
3006 contacts[0].pos = transform * Vector3<S>(-2.5, 0, 0);
3007 contacts[0].penetration_depth = 2.5;
3008 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
3030 hs =
Plane<S>(Vector3<S>(0, 1, 0), 0);
3035 contacts[0].pos << 0, 0, 0;
3036 contacts[0].penetration_depth = 5;
3037 contacts[0].normal << 0, 1, 0;
3038 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3043 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
3044 contacts[0].penetration_depth = 5;
3045 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
3046 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3051 contacts[0].pos << 0, 2.5, 0;
3052 contacts[0].penetration_depth = 2.5;
3053 contacts[0].normal << 0, 1, 0;
3059 contacts[0].pos = transform * Vector3<S>(0, 2.5, 0);
3060 contacts[0].penetration_depth = 2.5;
3061 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
3067 contacts[0].pos << 0, -2.5, 0;
3068 contacts[0].penetration_depth = 2.5;
3069 contacts[0].normal << 0, -1, 0;
3075 contacts[0].pos = transform * Vector3<S>(0, -2.5, 0);
3076 contacts[0].penetration_depth = 2.5;
3077 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
3099 hs =
Plane<S>(Vector3<S>(0, 0, 1), 0);
3104 contacts[0].pos << 0, 0, 0;
3105 contacts[0].penetration_depth = 5;
3106 contacts[0].normal << 0, 0, 1;
3107 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3112 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
3113 contacts[0].penetration_depth = 5;
3114 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
3115 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3120 contacts[0].pos << 0, 0, 2.5;
3121 contacts[0].penetration_depth = 2.5;
3122 contacts[0].normal << 0, 0, 1;
3128 contacts[0].pos = transform * Vector3<S>(0, 0, 2.5);
3129 contacts[0].penetration_depth = 2.5;
3130 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
3136 contacts[0].pos << 0, 0, -2.5;
3137 contacts[0].penetration_depth = 2.5;
3138 contacts[0].normal << 0, 0, -1;
3142 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -2.5)));
3144 contacts[0].pos = transform * Vector3<S>(0, 0, -2.5);
3145 contacts[0].penetration_depth = 2.5;
3146 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
3154 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 10.1)));
3162 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -10.1)));
3166 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_planecylinder)
3169 test_shapeIntersection_planecylinder<double>();
3172 template <
typename S>
3184 std::vector<ContactPoint<S>> contacts;
3189 contacts[0].pos << -2.5, 0, -5;
3190 contacts[0].penetration_depth = 5;
3191 contacts[0].normal << -1, 0, 0;
3197 contacts[0].pos = transform *
Vector3<S>(-2.5, 0, -5);
3198 contacts[0].penetration_depth = 5;
3199 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
3205 contacts[0].pos << -1.25, 0, -5;
3206 contacts[0].penetration_depth = 7.5;
3207 contacts[0].normal << -1, 0, 0;
3213 contacts[0].pos = transform *
Vector3<S>(-1.25, 0, -5);
3214 contacts[0].penetration_depth = 7.5;
3215 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
3221 contacts[0].pos << -3.75, 0, -5;
3222 contacts[0].penetration_depth = 2.5;
3223 contacts[0].normal << -1, 0, 0;
3229 contacts[0].pos = transform *
Vector3<S>(-3.75, 0, -5);
3230 contacts[0].penetration_depth = 2.5;
3231 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
3237 contacts[0].pos << 0.05, 0, -5;
3238 contacts[0].penetration_depth = 10.1;
3239 contacts[0].normal << -1, 0, 0;
3245 contacts[0].pos = transform *
Vector3<S>(0.05, 0, -5);
3246 contacts[0].penetration_depth = 10.1;
3247 contacts[0].normal = transform.linear() *
Vector3<S>(-1, 0, 0);
3266 contacts[0].pos << 0, -2.5, -5;
3267 contacts[0].penetration_depth = 5;
3268 contacts[0].normal << 0, -1, 0;
3274 contacts[0].pos = transform * Vector3<S>(0, -2.5, -5);
3275 contacts[0].penetration_depth = 5;
3276 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
3282 contacts[0].pos << 0, -1.25, -5;
3283 contacts[0].penetration_depth = 7.5;
3284 contacts[0].normal << 0, -1, 0;
3290 contacts[0].pos = transform * Vector3<S>(0, -1.25, -5);
3291 contacts[0].penetration_depth = 7.5;
3292 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
3298 contacts[0].pos << 0, -3.75, -5;
3299 contacts[0].penetration_depth = 2.5;
3300 contacts[0].normal << 0, -1, 0;
3306 contacts[0].pos = transform * Vector3<S>(0, -3.75, -5);
3307 contacts[0].penetration_depth = 2.5;
3308 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
3314 contacts[0].pos << 0, 0.05, -5;
3315 contacts[0].penetration_depth = 10.1;
3316 contacts[0].normal << 0, -1, 0;
3322 contacts[0].pos = transform * Vector3<S>(0, 0.05, -5);
3323 contacts[0].penetration_depth = 10.1;
3324 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
3343 contacts[0].pos << 0, 0, -2.5;
3344 contacts[0].penetration_depth = 5;
3345 contacts[0].normal << 0, 0, -1;
3351 contacts[0].pos = transform * Vector3<S>(0, 0, -2.5);
3352 contacts[0].penetration_depth = 5;
3353 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
3359 contacts[0].pos << 0, 0, -1.25;
3360 contacts[0].penetration_depth = 7.5;
3361 contacts[0].normal << 0, 0, -1;
3367 contacts[0].pos = transform * Vector3<S>(0, 0, -1.25);
3368 contacts[0].penetration_depth = 7.5;
3369 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
3375 contacts[0].pos << 0, 0, -3.75;
3376 contacts[0].penetration_depth= 2.5;
3377 contacts[0].normal << 0, 0, -1;
3381 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -2.5)));
3383 contacts[0].pos = transform * Vector3<S>(0, 0, -3.75);
3384 contacts[0].penetration_depth = 2.5;
3385 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
3391 contacts[0].pos << 0, 0, 0.05;
3392 contacts[0].penetration_depth = 10.1;
3393 contacts[0].normal << 0, 0, -1;
3397 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 5.1)));
3399 contacts[0].pos = transform * Vector3<S>(0, 0, 0.05);
3400 contacts[0].penetration_depth = 10.1;
3401 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
3409 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -5.1)));
3413 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersection_halfspacecone)
3416 test_shapeIntersection_halfspacecone<double>();
3419 template <
typename S>
3431 std::vector<ContactPoint<S>> contacts;
3436 contacts[0].pos << 0, 0, 0;
3437 contacts[0].penetration_depth = 5;
3438 contacts[0].normal << 1, 0, 0;
3439 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3444 contacts[0].pos = transform *
Vector3<S>(0, 0, 0);
3445 contacts[0].penetration_depth = 5;
3446 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
3447 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3452 contacts[0].pos << 2.5, 0, -2.5;
3453 contacts[0].penetration_depth = 2.5;
3454 contacts[0].normal << 1, 0, 0;
3460 contacts[0].pos = transform * Vector3<S>(2.5, 0, -2.5);
3461 contacts[0].penetration_depth = 2.5;
3462 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
3468 contacts[0].pos << -2.5, 0, -2.5;
3469 contacts[0].penetration_depth = 2.5;
3470 contacts[0].normal << -1, 0, 0;
3476 contacts[0].pos = transform * Vector3<S>(-2.5, 0, -2.5);
3477 contacts[0].penetration_depth = 2.5;
3478 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
3500 hs =
Plane<S>(Vector3<S>(0, 1, 0), 0);
3505 contacts[0].pos << 0, 0, 0;
3506 contacts[0].penetration_depth = 5;
3507 contacts[0].normal << 0, 1, 0;
3508 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3513 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
3514 contacts[0].penetration_depth = 5;
3515 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
3516 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3521 contacts[0].pos << 0, 2.5, -2.5;
3522 contacts[0].penetration_depth = 2.5;
3523 contacts[0].normal << 0, 1, 0;
3529 contacts[0].pos = transform * Vector3<S>(0, 2.5, -2.5);
3530 contacts[0].penetration_depth = 2.5;
3531 contacts[0].normal = transform.linear() * Vector3<S>(0, 1, 0);
3537 contacts[0].pos << 0, -2.5, -2.5;
3538 contacts[0].penetration_depth = 2.5;
3539 contacts[0].normal << 0, -1, 0;
3545 contacts[0].pos = transform * Vector3<S>(0, -2.5, -2.5);
3546 contacts[0].penetration_depth = 2.5;
3547 contacts[0].normal = transform.linear() * Vector3<S>(0, -1, 0);
3569 hs =
Plane<S>(Vector3<S>(0, 0, 1), 0);
3574 contacts[0].pos << 0, 0, 0;
3575 contacts[0].penetration_depth = 5;
3576 contacts[0].normal << 0, 0, 1;
3577 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3582 contacts[0].pos = transform * Vector3<S>(0, 0, 0);
3583 contacts[0].penetration_depth = 5;
3584 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
3585 testShapeIntersection(s, tf1, hs, tf2,
GST_LIBCCD,
true, contacts,
true,
true,
true,
true);
3590 contacts[0].pos << 0, 0, 2.5;
3591 contacts[0].penetration_depth = 2.5;
3592 contacts[0].normal << 0, 0, 1;
3598 contacts[0].pos = transform * Vector3<S>(0, 0, 2.5);
3599 contacts[0].penetration_depth = 2.5;
3600 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, 1);
3606 contacts[0].pos << 0, 0, -2.5;
3607 contacts[0].penetration_depth = 2.5;
3608 contacts[0].normal << 0, 0, -1;
3612 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -2.5)));
3614 contacts[0].pos = transform * Vector3<S>(0, 0, -2.5);
3615 contacts[0].penetration_depth = 2.5;
3616 contacts[0].normal = transform.linear() * Vector3<S>(0, 0, -1);
3624 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 10.1)));
3632 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, -10.1)));
3639 test_shapeIntersection_planecone<double>();
3666 template <
typename S>
3695 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3699 EXPECT_TRUE(dist < 0);
3705 EXPECT_TRUE(fabs(dist - 10) < 0.1);
3709 EXPECT_TRUE(fabs(dist - 0.1) < 0.06);
3713 EXPECT_TRUE(dist < 0);
3717 EXPECT_TRUE(fabs(dist - 10) < 0.1);
3721 EXPECT_TRUE(fabs(dist - 0.1) < 0.1);
3725 EXPECT_TRUE(dist < 0);
3732 test_shapeDistance_spheresphere<double>();
3735 template <
typename S>
3752 res = solver1<S>().shapeDistance(s1, transform, s2, transform, &dist);
3753 EXPECT_TRUE(dist < 0);
3757 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3761 EXPECT_TRUE(fabs(dist - 10.1) < 0.001);
3765 EXPECT_TRUE(fabs(dist - 10.2) < 0.001);
3769 EXPECT_TRUE(fabs(dist - 0.1 * 1.414) < 0.001);
3773 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3777 EXPECT_TRUE(fabs(dist - 10.1) < 0.001);
3781 EXPECT_TRUE(fabs(dist - 10.1) < 0.001);
3785 EXPECT_TRUE(fabs(dist - 0.1 * 1.414) < 0.001);
3790 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3794 EXPECT_TRUE(fabs(dist - 5) < 0.001);
3798 EXPECT_TRUE(fabs(dist - 5) < 0.001);
3805 test_shapeDistance_boxbox<double>();
3808 template <
typename S>
3824 res = solver1<S>().shapeDistance(s1, transform, s2, transform, &dist);
3825 EXPECT_TRUE(dist < 0);
3829 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3833 EXPECT_TRUE(fabs(dist - 0.1) < 0.05);
3837 EXPECT_TRUE(fabs(dist - 17.5) < 0.001);
3841 EXPECT_TRUE(fabs(dist - 17.5) < 0.001);
3848 test_shapeDistance_boxsphere<double>();
3851 template <
typename S>
3867 res = solver1<S>().shapeDistance(s1, transform, s2, transform, &dist);
3868 EXPECT_TRUE(dist < 0);
3872 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3876 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3880 EXPECT_TRUE(fabs(dist - 30) < 0.001);
3884 EXPECT_TRUE(fabs(dist - 30) < 0.001);
3891 test_shapeDistance_cylindercylinder<double>();
3894 template <
typename S>
3910 res = solver1<S>().shapeDistance(s1, transform, s2, transform, &dist);
3911 EXPECT_TRUE(dist < 0);
3915 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3919 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
3923 EXPECT_TRUE(fabs(dist - 30) < 1);
3927 EXPECT_TRUE(fabs(dist - 30) < 1);
3934 test_shapeDistance_conecone<double>();
3937 template <
typename S>
3953 res = solver1<S>().shapeDistance(s1, transform, s2, transform, &dist);
3954 EXPECT_TRUE(dist < 0);
3958 EXPECT_TRUE(fabs(dist - 0.1) < 0.01);
3962 EXPECT_TRUE(fabs(dist - 0.1) < 0.02);
3966 EXPECT_TRUE(fabs(dist - 30) < 0.01);
3970 EXPECT_TRUE(fabs(dist - 30) < 0.1);
3977 test_shapeDistance_conecylinder<double>();
3980 template <
typename S>
4010 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4014 EXPECT_TRUE(dist < 0);
4019 EXPECT_TRUE(fabs(dist - 10) < 0.001);
4023 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4027 EXPECT_TRUE(dist < 0);
4031 EXPECT_TRUE(fabs(dist - 10) < 0.001);
4035 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4039 EXPECT_TRUE(dist < 0);
4043 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeDistance_ellipsoidellipsoid)
4046 test_shapeDistance_ellipsoidellipsoid<double>();
4073 template <
typename S>
4085 std::vector<ContactPoint<S>> contacts;
4098 contacts[0].normal << 1, 0, 0;
4099 contacts[0].pos << 20, 0, 0;
4100 contacts[0].penetration_depth = 0.0;
4114 contacts[0].normal << 1, 0, 0;
4115 contacts[0].pos << 20.0 - 0.1 * 20.0/(20.0 + 10.0), 0, 0;
4116 contacts[0].penetration_depth = 0.1;
4122 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
4123 contacts[0].pos = transform * Vector3<S>(20.0 - 0.1 * 20.0/(20.0 + 10.0), 0, 0);
4124 contacts[0].penetration_depth = 0.1;
4130 contacts[0].normal.setZero();
4131 contacts[0].pos.setZero();
4132 contacts[0].penetration_depth = 20.0 + 10.0;
4138 contacts[0].normal.setZero();
4140 contacts[0].penetration_depth = 20.0 + 10.0;
4146 contacts[0].normal << -1, 0, 0;
4147 contacts[0].pos << -20.0 + 0.1 * 20.0/(20.0 + 10.0), 0, 0;
4148 contacts[0].penetration_depth = 0.1;
4154 contacts[0].normal = transform.linear() * Vector3<S>(-1, 0, 0);
4155 contacts[0].pos = transform * Vector3<S>(-20.0 + 0.1 * 20.0/(20.0 + 10.0), 0, 0);
4156 contacts[0].penetration_depth = 0.1;
4162 contacts[0].normal << -1, 0, 0;
4163 contacts[0].pos << -20, 0, 0;
4164 contacts[0].penetration_depth = 0.0;
4176 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_spheresphere)
4179 test_shapeIntersectionGJK_spheresphere<double>();
4182 template <
typename S>
4194 std::vector<ContactPoint<S>> contacts;
4202 contacts[0].normal << 1, 0, 0;
4203 contacts[1].normal << 1, 0, 0;
4204 contacts[2].normal << 1, 0, 0;
4205 contacts[3].normal << 1, 0, 0;
4212 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
4213 contacts[1].normal = transform.linear() *
Vector3<S>(1, 0, 0);
4214 contacts[2].normal = transform.linear() *
Vector3<S>(1, 0, 0);
4215 contacts[3].normal = transform.linear() *
Vector3<S>(1, 0, 0);
4221 contacts[0].normal = Vector3<S>(1, 0, 0);
4222 contacts[1].normal = Vector3<S>(1, 0, 0);
4223 contacts[2].normal = Vector3<S>(1, 0, 0);
4224 contacts[3].normal = Vector3<S>(1, 0, 0);
4234 contacts[0].normal = Vector3<S>(1, 0, 0);
4235 contacts[1].normal = Vector3<S>(1, 0, 0);
4236 contacts[2].normal = Vector3<S>(1, 0, 0);
4237 contacts[3].normal = Vector3<S>(1, 0, 0);
4243 contacts[0].normal = transform.linear() * Vector3<S>(1, 0, 0);
4244 contacts[1].normal = transform.linear() * Vector3<S>(1, 0, 0);
4245 contacts[2].normal = transform.linear() * Vector3<S>(1, 0, 0);
4246 contacts[3].normal = transform.linear() * Vector3<S>(1, 0, 0);
4253 test_shapeIntersectionGJK_boxbox<double>();
4256 template <
typename S>
4268 std::vector<ContactPoint<S>> contacts;
4285 contacts[0].normal << 1, 0, 0;
4319 contacts[0].normal << 1, 0, 0;
4320 testShapeIntersection(s1, tf1, s2, tf2,
GST_INDEP,
true, contacts,
false,
false,
true,
false, 1e-2);
4333 test_shapeIntersectionGJK_spherebox<double>();
4336 template <
typename S>
4348 std::vector<ContactPoint<S>> contacts;
4365 contacts[0].normal << 1, 0, 0;
4371 contacts[0].normal = transform.linear() *
Vector3<S>(1, 0, 0);
4377 contacts[0].normal << 1, 0, 0;
4385 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_spherecapsule)
4388 test_shapeIntersectionGJK_spherecapsule<double>();
4391 template <
typename S>
4403 std::vector<ContactPoint<S>> contacts;
4420 contacts[0].normal << 1, 0, 0;
4421 testShapeIntersection(s1, tf1, s2, tf2,
GST_INDEP,
true, contacts,
false,
false,
true,
false, 3e-1);
4433 contacts[0].normal << 1, 0, 0;
4441 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_cylindercylinder)
4444 test_shapeIntersectionGJK_cylindercylinder<double>();
4447 template <
typename S>
4459 std::vector<ContactPoint<S>> contacts;
4476 contacts[0].normal << 1, 0, 0;
4477 testShapeIntersection(s1, tf1, s2, tf2,
GST_INDEP,
true, contacts,
false,
false,
true,
false, 5.7e-1);
4497 contacts[0].normal << 0, 0, 1;
4511 test_shapeIntersectionGJK_conecone<double>();
4514 template <
typename S>
4526 std::vector<ContactPoint<S>> contacts;
4562 contacts[0].normal << 0, 0, 1;
4575 contacts[0].normal << 0, 0, 1;
4579 tf2 = transform * Transform3<S>(
Translation3<S>(Vector3<S>(0, 0, 10.1)));
4583 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_cylindercone)
4586 test_shapeIntersectionGJK_cylindercone<double>();
4589 template <
typename S>
4602 std::vector<ContactPoint<S>> contacts;
4661 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_ellipsoidellipsoid)
4664 test_shapeIntersectionGJK_ellipsoidellipsoid<double>();
4667 template <
typename S>
4684 res = solver2<S>().shapeTriangleIntersect(s,
Transform3<S>::Identity(), t[0], t[1], t[2],
nullptr,
nullptr,
nullptr);
4687 res = solver2<S>().shapeTriangleIntersect(s, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
4691 t[1] << 9.9, -20, 0;
4693 res = solver2<S>().shapeTriangleIntersect(s,
Transform3<S>::Identity(), t[0], t[1], t[2],
nullptr,
nullptr,
nullptr);
4696 res = solver2<S>().shapeTriangleIntersect(s, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
4699 res = solver2<S>().shapeTriangleIntersect(s,
Transform3<S>::Identity(), t[0], t[1], t[2],
nullptr,
nullptr, &normal);
4701 EXPECT_TRUE(normal.isApprox(
Vector3<S>(1, 0, 0), 1e-9));
4703 res = solver2<S>().shapeTriangleIntersect(s, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr, &normal);
4705 EXPECT_TRUE(normal.isApprox(transform.linear() *
Vector3<S>(1, 0, 0), 1e-9));
4708 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_spheretriangle)
4711 test_shapeIntersectionGJK_spheretriangle<double>();
4714 template <
typename S>
4734 res = solver2<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
4739 t[1] << -0.1, -20, 0;
4740 t[2] << -0.1, 20, 0;
4744 res = solver2<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
4749 EXPECT_TRUE(normal.isApprox(
Vector3<S>(1, 0, 0), 1e-9));
4751 res = solver2<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr, &normal);
4753 EXPECT_TRUE(normal.isApprox(transform.linear() *
Vector3<S>(1, 0, 0), 1e-9));
4756 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_halfspacetriangle)
4759 test_shapeIntersectionGJK_halfspacetriangle<double>();
4762 template <
typename S>
4782 res = solver1<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
4787 t[1] << -0.1, -20, 0;
4788 t[2] << -0.1, 20, 0;
4792 res = solver2<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr,
nullptr);
4797 EXPECT_TRUE(normal.isApprox(
Vector3<S>(1, 0, 0), 1e-9));
4799 res = solver2<S>().shapeTriangleIntersect(hs, transform, t[0], t[1], t[2], transform,
nullptr,
nullptr, &normal);
4801 EXPECT_TRUE(normal.isApprox(transform.linear() *
Vector3<S>(1, 0, 0), 1e-9));
4804 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeIntersectionGJK_planetriangle)
4807 test_shapeIntersectionGJK_planetriangle<double>();
4834 template <
typename S>
4863 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4867 EXPECT_TRUE(dist < 0);
4872 EXPECT_TRUE(fabs(dist - 10) < 0.001);
4876 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4880 EXPECT_TRUE(dist < 0);
4884 EXPECT_TRUE(fabs(dist - 10) < 0.001);
4888 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4892 EXPECT_TRUE(dist < 0);
4899 test_shapeDistanceGJK_spheresphere<double>();
4902 template <
typename S>
4918 res = solver2<S>().shapeDistance(s1, transform, s2, transform, &dist);
4919 EXPECT_TRUE(dist < 0);
4923 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4927 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
4931 EXPECT_TRUE(fabs(dist - 5) < 0.001);
4935 EXPECT_TRUE(fabs(dist - 5) < 0.001);
4942 test_shapeDistanceGJK_boxbox<double>();
4945 template <
typename S>
4961 res = solver2<S>().shapeDistance(s1, transform, s2, transform, &dist);
4962 EXPECT_TRUE(dist < 0);
4966 EXPECT_TRUE(fabs(dist - 0.1) < 0.01);
4970 EXPECT_TRUE(fabs(dist - 0.1) < 0.01);
4974 EXPECT_TRUE(fabs(dist - 17.5) < 0.001);
4978 EXPECT_TRUE(fabs(dist - 17.5) < 0.001);
4985 test_shapeDistanceGJK_boxsphere<double>();
4988 template <
typename S>
5004 res = solver2<S>().shapeDistance(s1, transform, s2, transform, &dist);
5005 EXPECT_TRUE(dist < 0);
5009 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5013 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5017 EXPECT_TRUE(fabs(dist - 30) < 0.001);
5021 EXPECT_TRUE(fabs(dist - 30) < 0.001);
5025 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeDistanceGJK_cylindercylinder)
5028 test_shapeDistanceGJK_cylindercylinder<double>();
5031 template <
typename S>
5047 res = solver2<S>().shapeDistance(s1, transform, s2, transform, &dist);
5048 EXPECT_TRUE(dist < 0);
5052 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5056 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5060 EXPECT_TRUE(fabs(dist - 30) < 0.001);
5064 EXPECT_TRUE(fabs(dist - 30) < 0.001);
5071 test_shapeDistanceGJK_conecone<double>();
5074 template <
typename S>
5103 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5107 EXPECT_TRUE(dist < 0);
5111 EXPECT_TRUE(fabs(dist - 10) < 0.001);
5115 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5119 EXPECT_TRUE(dist < 0);
5123 EXPECT_TRUE(fabs(dist - 10) < 0.001);
5127 EXPECT_TRUE(fabs(dist - 0.1) < 0.001);
5131 EXPECT_TRUE(dist < 0);
5135 GTEST_TEST(FCL_GEOMETRIC_SHAPES, shapeDistanceGJK_ellipsoidellipsoid)
5138 test_shapeDistanceGJK_ellipsoidellipsoid<double>();
5141 template<
typename Shape1,
typename Shape2>
5144 using S =
typename Shape2::S;
5149 std::vector<ContactPoint<S>> contactsA;
5150 std::vector<ContactPoint<S>> contactsB;
5155 const double tol = 1e-6;
5157 resA = solver1<S>().shapeIntersect(s1, tf1, s2, tf2, &contactsA);
5158 resB = solver1<S>().shapeIntersect(s2, tf2, s1, tf1, &contactsB);
5161 for (
size_t i = 0; i < contactsB.size(); ++i)
5162 contactsB[i].normal = -contactsB[i].normal;
5167 contactsA, contactsB,
5168 true,
true,
true,
false, tol));
5170 resA = solver2<S>().shapeIntersect(s1, tf1, s2, tf2, &contactsA);
5171 resB = solver2<S>().shapeIntersect(s2, tf2, s1, tf1, &contactsB);
5174 for (
size_t i = 0; i < contactsB.size(); ++i)
5175 contactsB[i].normal = -contactsB[i].normal;
5180 contactsA, contactsB,
5181 true,
true,
true,
false, tol));
5184 template <
typename S>
5244 GTEST_TEST(FCL_GEOMETRIC_SHAPES, reversibleShapeIntersection_allshapes)
5247 test_reversibleShapeIntersection_allshapes<double>();
5250 template<
typename Shape1,
typename Shape2>
5253 using S =
typename Shape2::S;
5268 const double tol = 1e-6;
5270 resA = solver1<S>().shapeDistance(s1, tf1, s2, tf2, &distA, &p1A, &p2A);
5271 resB = solver1<S>().shapeDistance(s2, tf2, s1, tf1, &distB, &p1B, &p2B);
5279 resA = solver2<S>().shapeDistance(s1, tf1, s2, tf2, &distA, &p1A, &p2A);
5280 resB = solver2<S>().shapeDistance(s2, tf2, s1, tf1, &distB, &p1B, &p2B);
5289 template <
typename S>
5349 GTEST_TEST(FCL_GEOMETRIC_SHAPES, reversibleShapeDistance_allshapes)
5352 test_reversibleShapeDistance_allshapes<double>();
5358 ::testing::InitGoogleTest(&argc, argv);
5359 return RUN_ALL_TESTS();
Vector3< S > cached_gjk_guess
The initial guess to use in the GJK algorithm.
void testReversibleShapeIntersection(const Shape1 &s1, const Shape2 &s2, typename Shape2::S distance)
size_t numContacts() const
number of contacts found
void test_shapeIntersection_halfspacecylinder()
std::array< S, 6 > & extents()
double getElapsedTime()
get elapsed time in milli-second
detail::GJKSolver_libccd< S > & solver1()
Half Space: this is equivalent to the Planed in ODE. The separation plane is defined as n * x = d...
size_t num_max_contacts
The maximum number of contacts that can be returned.
void test_shapeIntersectionGJK_spherebox()
void test_shapeDistanceGJK_cylindercylinder()
void test_shapeIntersectionGJK_conecone()
Eigen::Quaternion< S > Quaternion
template Halfspace< double > transform(const Halfspace< double > &a, const Transform3< double > &tf)
void test_shapeIntersection_halfspaceellipsoid()
Eigen::Transform< S, 3, Eigen::Isometry > Transform3
void test_shapeIntersection_planebox()
bool compareContactPointds1(const Vector3< S > &c1, const Vector3< S > &c2)
void generateRandomTransform(S extents[6], Transform3< S > &transform)
Generate one random transform whose translation is constrained by extents and rotation without constr...
void eulerToMatrix(S a, S b, S c, Matrix3< S > &R)
void test_shapeIntersection_spheretriangle()
void stop()
stop the timer
void test_reversibleShapeDistance_allshapes()
void test_shapeDistanceGJK_conecone()
const Contact< S > & getContact(size_t i) const
get the i-th contact calculated
Center at zero point ellipsoid.
S gjk_tolerance
the threshold used in GJK to stop iteration
void test_shapeIntersection_spheresphere()
void test_shapeIntersectionGJK_spheresphere()
void printComparisonError(const std::string &comparison_type, const Shape1 &s1, const Transform3< typename Shape1::S > &tf1, const Shape2 &s2, const Transform3< typename Shape1::S > &tf2, GJKSolverType solver_type, const Vector3< typename Shape1::S > &expected_contact_or_normal, const Vector3< typename Shape1::S > &actual_contact_or_normal, bool check_opposite_normal, typename Shape1::S tol)
Eigen::Matrix< S, 3, 3 > Matrix3
S distance(const Eigen::MatrixBase< DerivedA > &R0, const Eigen::MatrixBase< DerivedB > &T0, const kIOS< S > &b1, const kIOS< S > &b2, Vector3< S > *P, Vector3< S > *Q)
Approximate distance between two kIOS bounding volumes.
#define EXPECT_NEAR(a, b, prec)
void test_shapeDistance_spheresphere()
void test_shapeDistance_conecone()
Eigen::Matrix< S, 3, 1 > Vector3
detail::GJKSolver_indep< S > & solver2()
void testShapeIntersection(const Shape1 &s1, const Transform3< typename Shape1::S > &tf1, const Shape2 &s2, const Transform3< typename Shape1::S > &tf2, GJKSolverType solver_type, bool expected_res, const std::vector< ContactPoint< typename Shape1::S >> &expected_contacts=std::vector< ContactPoint< typename Shape1::S >>(), bool check_position=true, bool check_depth=true, bool check_normal=true, bool check_opposite_normal=false, typename Shape1::S tol=1e-9)
void test_shapeIntersection_halfspacetriangle()
Eigen::AngleAxis< S > AngleAxis
void test_shapeDistanceGJK_ellipsoidellipsoid()
GJKSolverType gjk_solver_type
Enumeration indicating the GJK solver implementation to use.
void test_shapeIntersection_ellipsoidellipsoid()
#define EXPECT_FALSE(args)
void test_shapeIntersection_cylindercylinder()
void test_shapeIntersection_halfspacesphere()
void test_shapeIntersection_spherebox()
void getCurrentTransform(Transform3< S > &tf_) const override
Vector3< S > cached_gjk_guess
collision and distance solver based on libccd library.
void test_shapeIntersectionGJK_cylindercylinder()
template FCL_EXPORT std::size_t collide(const CollisionObject< double > *o1, const CollisionObject< double > *o2, const CollisionRequest< double > &request, CollisionResult< double > &result)
bool enable_contact
If true, contact information (e.g., normal, penetration depth, and contact position) will be returned...
void test_shapeIntersection_halfspacecone()
void test_shapeIntersection_boxbox()
Parameters for performing collision request.
void test_shapeDistanceGJK_boxbox()
std::string getGJKSolverName(GJKSolverType solver_type)
bool integrate(S dt) const override
Integrate the motion from 0 to dt.
void test_shapeIntersection_cylindercone()
std::string getNodeTypeName(NODE_TYPE node_type)
Center at zero point, axis aligned box.
static constexpr S pi()
The mathematical constant pi.
Vector3< S > side
box side length
Eigen::Translation< S, 3 > Translation3
void test_shapeDistance_conecylinder()
void test_shapeIntersectionGJK_planetriangle()
void test_shapeIntersection_planecylinder()
void test_shapeIntersection_halfspacecapsule()
void test_shapeDistanceGJK_boxsphere()
void test_shapeIntersection_planecapsule()
bool enable_cached_gjk_guess
If true, uses the provided initial guess for the GJK algorithm.
bool compareContactPointds2(const ContactPoint< S > &cp1, const ContactPoint< S > &cp2)
void test_shapeIntersection_planesphere()
void test_shapeIntersection_planetriangle()
int main(int argc, char *argv[])
void getContactPointdsFromResult(std::vector< ContactPoint< S >> &contacts, const CollisionResult< S > &result)
void test_shapeIntersectionGJK_cylindercone()
void test_shapeIntersectionGJK_spherecapsule()
void test_shapeIntersectionGJK_halfspacetriangle()
collision and distance solver based on GJK algorithm implemented in fcl (rewritten the code from the ...
void test_shapeIntersection_halfspacebox()
void test_shapeDistance_boxbox()
bool isCollision() const
return binary collision result
void test_shapeDistance_cylindercylinder()
Center at zero point sphere.
void testReversibleShapeDistance(const Shape1 &s1, const Shape2 &s2, typename Shape2::S distance)
void test_shapeIntersection_planecone()
S epa_tolerance
the threshold used in EPA to stop iteration
#define EXPECT_TRUE(args)
void test_reversibleShapeIntersection_allshapes()
void testBoxBoxContactPointds(const Eigen::MatrixBase< Derived > &R)
GJKSolverType
Type of narrow phase GJK solver.
S computeVolume() const override
compute the volume
void test_shapeDistanceGJK_spheresphere()
void test_shapeIntersection_planeellipsoid()
void test_shapeIntersectionGJK_boxbox()
void test_shapeIntersection_spherecapsule()
void test_shapeIntersectionGJK_spheretriangle()
GTEST_TEST(FCL_GEOMETRIC_SHAPES, sphere_shape)
void test_shapeDistance_boxsphere()
bool inspectContactPointds(const Shape1 &s1, const Transform3< typename Shape1::S > &tf1, const Shape2 &s2, const Transform3< typename Shape1::S > &tf2, GJKSolverType solver_type, const std::vector< ContactPoint< typename Shape1::S >> &expected_contacts, const std::vector< ContactPoint< typename Shape1::S >> &actual_contacts, bool check_position=false, bool check_depth=false, bool check_normal=false, bool check_opposite_normal=false, typename Shape1::S tol=1e-9)
void clear()
clear the results obtained
void test_shapeDistance_ellipsoidellipsoid()
bool checkContactPointds(const Shape1 &s1, const Transform3< typename Shape1::S > &tf1, const Shape2 &s2, const Transform3< typename Shape1::S > &tf2, GJKSolverType solver_type, const ContactPoint< typename Shape1::S > &expected, const ContactPoint< typename Shape1::S > &actual, bool check_position=false, bool check_depth=false, bool check_normal=false, bool check_opposite_normal=false, typename Shape1::S tol=1e-9)
void test_shapeIntersection_conecone()
void test_shapeIntersectionGJK_ellipsoidellipsoid()