47 #define CALL_GET_SHAPE_SUPPORT(ShapeType) \
48 getShapeSupport<_SupportOptions>(static_cast<const ShapeType*>(shape), dir, \
49 support, hint, support_data)
50 template <
int _SupportOptions>
88 #undef CALL_GET_SHAPE_SUPPORT
92 template COAL_DLLAPI
Vec3s getSupport<SupportOptions::NoSweptSphere>(
const ShapeBase*,
const Vec3s&,
int&);
94 template COAL_DLLAPI
Vec3s getSupport<SupportOptions::WithSweptSphere>(
const ShapeBase*,
const Vec3s&,
int&);
98 #define getShapeSupportTplInstantiation(ShapeType) \
99 template COAL_DLLAPI void getShapeSupport<SupportOptions::NoSweptSphere>( \
100 const ShapeType* shape_, const Vec3s& dir, Vec3s& support, int& hint, \
101 ShapeSupportData& support_data); \
103 template COAL_DLLAPI void getShapeSupport<SupportOptions::WithSweptSphere>( \
104 const ShapeType* shape_, const Vec3s& dir, Vec3s& support, int& hint, \
105 ShapeSupportData& support_data);
108 template <
int _SupportOptions>
110 Vec3s& support,
int& ,
117 support = triangle->
c;
119 support = triangle->
a;
123 support = triangle->
c;
125 support = triangle->
b;
136 template <
int _SupportOptions>
143 Eigen::NumTraits<CoalScalar>::dummy_precision();
144 Vec3s support1 = (dir.array() > dummy_precision).
select(
box->halfSide, 0);
147 support.noalias() = support1 + support2;
150 support +=
box->getSweptSphereRadius() * dir.normalized();
156 template <
int _SupportOptions>
158 Vec3s& support,
int& ,
162 (
sphere->radius +
sphere->getSweptSphereRadius()) * dir.normalized();
173 template <
int _SupportOptions>
175 Vec3s& support,
int& ,
181 Vec3s v(a2 * dir[0], b2 * dir[1],
c2 * dir[2]);
194 template <
int _SupportOptions>
196 Vec3s& support,
int& ,
199 Eigen::NumTraits<CoalScalar>::dummy_precision();
201 if (dir[2] > dummy_precision) {
203 }
else if (dir[2] < -dummy_precision) {
215 template <
int _SupportOptions>
219 Eigen::NumTraits<CoalScalar>::dummy_precision();
228 if (dir.head<2>().isZero(dummy_precision)) {
230 if (dir[2] > dummy_precision) {
236 CoalScalar zdist = dir[0] * dir[0] + dir[1] * dir[1];
238 zdist = std::sqrt(zdist);
242 support.head<2>() = rad * dir.head<2>();
245 len = std::sqrt(len);
248 if (dir[2] > len * sin_a)
252 support.head<2>() = rad * dir.head<2>();
265 template <
int _SupportOptions>
269 Eigen::NumTraits<CoalScalar>::dummy_precision();
277 const bool dir_is_aligned_with_z = dir.head<2>().isZero(dummy_precision);
278 if (dir_is_aligned_with_z) half_h *=
inflate;
280 if (dir[2] > dummy_precision) {
282 }
else if (dir[2] < -dummy_precision) {
283 support[2] = -half_h;
289 if (dir_is_aligned_with_z) {
292 support.head<2>() = dir.head<2>().normalized() *
r;
295 assert(fabs(support[0] * dir[1] - support[1] * dir[0]) <
305 template <
int _SupportOptions>
307 Vec3s& support,
int& hint,
309 assert(convex->
neighbors !=
nullptr &&
"Convex has no neighbors.");
313 const double use_warm_start_threshold = 0.9;
314 Vec3s dir_normalized = dir.normalized();
315 if (!support_data.
last_dir.isZero() &&
317 support_data.
last_dir.dot(dir_normalized) < use_warm_start_threshold) {
329 support_data.
last_dir = dir_normalized;
331 const std::vector<Vec3s>& pts = *(convex->
points);
332 const std::vector<ConvexBase::Neighbors>& nn = *(convex->
neighbors);
334 if (hint < 0 || hint >= (
int)convex->
num_points) {
337 CoalScalar maxdot = pts[
static_cast<size_t>(hint)].dot(dir);
338 std::vector<int8_t>& visited = support_data.
visited;
340 std::fill(visited.begin(), visited.end(),
false);
347 visited[
static_cast<std::size_t
>(hint)] =
true;
351 bool loose_check =
true;
355 for (
int in = 0; in < n.
count(); ++in) {
356 const unsigned int ip = n[in];
357 if (visited[ip])
continue;
364 }
else if (loose_check && dot == maxdot)
368 hint =
static_cast<int>(ip);
374 support = pts[
static_cast<size_t>(hint)];
382 template <
int _SupportOptions>
384 Vec3s& support,
int& hint,
386 const std::vector<Vec3s>& pts = *(convex->
points);
390 for (
int i = 1; i < (int)convex->
num_points; ++i) {
391 CoalScalar dot = pts[
static_cast<size_t>(i)].dot(dir);
398 support = pts[
static_cast<size_t>(hint)];
406 template <
int _SupportOptions>
413 getShapeSupportLog<_SupportOptions>(convex, dir, support, hint,
416 getShapeSupportLinear<_SupportOptions>(convex, dir, support, hint,
423 template <
int _SupportOptions>
425 Vec3s& support,
int& hint,
427 getShapeSupportLinear<_SupportOptions>(
428 reinterpret_cast<const ConvexBase*
>(convex), dir, support, hint,
434 template <
int _SupportOptions>
436 Vec3s& support,
int& hint,
438 getShapeSupportLog<_SupportOptions>(
439 reinterpret_cast<const ConvexBase*
>(convex), dir, support, hint,
445 #define CALL_GET_SHAPE_SUPPORT_SET(ShapeType) \
446 getShapeSupportSet<_SupportOptions>(static_cast<const ShapeType*>(shape), \
447 support_set, hint, support_data, \
448 max_num_supports, tol)
449 template <
int _SupportOptions>
483 #undef CALL_GET_SHAPE_SUPPORT
493 #define getShapeSupportSetTplInstantiation(ShapeType) \
494 template COAL_DLLAPI void getShapeSupportSet<SupportOptions::NoSweptSphere>( \
495 const ShapeType* shape_, SupportSet& support_set, int& hint, \
496 ShapeSupportData& data, size_t num_sampled_supports, CoalScalar tol); \
498 template COAL_DLLAPI void \
499 getShapeSupportSet<SupportOptions::WithSweptSphere>( \
500 const ShapeType* shape_, SupportSet& support_set, int& hint, \
501 ShapeSupportData& data, size_t num_sampled_supports, CoalScalar tol);
504 template <
int _SupportOptions>
516 getShapeSupport<SupportOptions::NoSweptSphere>(triangle, support_dir, support,
518 const CoalScalar support_value = support.dot(support_dir);
520 if (support_value - support_dir.dot(triangle->
a) < tol) {
531 if (support_value - support_dir.dot(triangle->
b) < tol) {
539 if (support_value - support_dir.dot(triangle->
c) < tol) {
551 template <
int _SupportOptions>
558 getShapeSupport<SupportOptions::NoSweptSphere>(
box, support_dir, support,
560 const CoalScalar support_value = support.dot(support_dir);
565 const std::array<Vec3s, 8> corners = {
566 Vec3s(
x,
y, z),
Vec3s(-
x,
y, z),
Vec3s(-
x, -
y, z),
Vec3s(
x, -
y, z),
567 Vec3s(
x,
y, -z),
Vec3s(-
x,
y, -z),
Vec3s(-
x, -
y, -z),
Vec3s(
x, -
y, -z),
573 for (
const Vec3s& corner : corners) {
575 if (support_value -
val < tol) {
579 box->getSweptSphereRadius() * support_dir)
581 polygon.emplace_back(p);
584 polygon.emplace_back(p);
593 template <
int _SupportOptions>
598 support_set.
points().clear();
602 getShapeSupport<_SupportOptions>(
sphere, support_dir, support, hint,
609 template <
int _SupportOptions>
613 support_set.
points().clear();
617 getShapeSupport<_SupportOptions>(ellipsoid, support_dir, support, hint,
624 template <
int _SupportOptions>
631 support_set.
points().clear();
635 getShapeSupport<SupportOptions::NoSweptSphere>(capsule, support_dir, support,
638 support_dir.dot(support + capsule->
radius * support_dir);
644 const Vec3s p1(
r * support_dir[0],
r * support_dir[1], h);
645 const Vec3s p2(
r * support_dir[0],
r * support_dir[1], -h);
646 if ((support_value - support_dir.dot(
p1) <= tol) &&
647 (support_value - support_dir.dot(p2) <= tol)) {
659 support_set.
addPoint(support + ssr_vec);
668 template <
int _SupportOptions>
672 size_t num_sampled_supports,
CoalScalar tol) {
674 support_set.
points().clear();
678 getShapeSupport<SupportOptions::NoSweptSphere>(cone, support_dir, support,
680 const CoalScalar support_value = support.dot(support_dir);
693 const Vec3s p1(
r * support_dir[0],
r * support_dir[1], z);
694 const Vec3s p2(-
r * support_dir[0], -
r * support_dir[1], z);
696 if ((support_value - support_dir.dot(
p1) <= tol) &&
697 (support_value - support_dir.dot(p2) <= tol)) {
704 for (
size_t i = 0; i < num_sampled_supports; ++i) {
706 Vec3s point_on_cone_base(
r * std::cos(theta),
r * std::sin(theta), z);
707 assert(std::abs(support_dir.dot(support - point_on_cone_base)) <= tol);
711 support_set.
addPoint(point_on_cone_base);
718 if (support_value - support_dir.dot(cone_tip) <= tol) {
726 cone->
radius * support_dir[1],
728 if (support_value - support_dir.dot(point_on_cone_base) <= tol) {
732 support_set.
addPoint(point_on_cone_base);
739 template <
int _SupportOptions>
743 size_t num_sampled_supports,
CoalScalar tol) {
745 support_set.
points().clear();
749 getShapeSupport<SupportOptions::NoSweptSphere>(cylinder, support_dir, support,
751 const CoalScalar support_value = support.dot(support_dir);
758 const Vec3s p1(
r * support_dir[0],
r * support_dir[1], z);
759 const Vec3s p2(-
r * support_dir[0], -
r * support_dir[1], z);
761 if ((support_value - support_dir.dot(
p1) <= tol) &&
762 (support_value - support_dir.dot(p2) <= tol)) {
765 for (
size_t i = 0; i < num_sampled_supports; ++i) {
767 Vec3s point_on_cone_base(
r * std::cos(theta),
r * std::sin(theta), z);
768 assert(std::abs(support_dir.dot(support - point_on_cone_base)) <= tol);
772 support_set.
addPoint(point_on_cone_base);
778 cylinder->
radius * support_dir[1],
780 if (support_value - support_dir.dot(point_on_lower_circle) <= tol) {
784 support_set.
addPoint(point_on_lower_circle);
788 cylinder->
radius * support_dir[1],
790 if (support_value - support_dir.dot(point_on_upper_circle) <= tol) {
794 support_set.
addPoint(point_on_upper_circle);
801 template <
int _SupportOptions>
809 getShapeSupport<SupportOptions::NoSweptSphere>(convex, support_dir, support,
811 const CoalScalar support_value = support_dir.dot(support);
813 const std::vector<Vec3s>& points = *(convex->
points);
817 for (
const Vec3s& point : points) {
818 const CoalScalar dot = support_dir.dot(point);
819 if (support_value - dot <= tol) {
825 polygon.emplace_back(p);
828 polygon.emplace_back(p);
837 template <
int _SupportOptions>
839 const std::vector<Vec3s>& points,
840 const std::vector<ConvexBase::Neighbors>& neighbors,
841 const CoalScalar swept_sphere_radius,
const size_t vertex_idx,
843 const Transform3s& tf, std::vector<int8_t>& visited,
847 if (visited[vertex_idx]) {
851 visited[vertex_idx] =
true;
852 const Vec3s& point = points[vertex_idx];
854 if (support_value -
val <= tol) {
859 polygon.emplace_back(p);
863 polygon.emplace_back(p);
867 for (
int i = 0; i < point_neighbors.
count(); ++i) {
868 const size_t neighbor_index = (size_t)(point_neighbors[i]);
869 convexSupportSetRecurse<_SupportOptions>(
870 points, neighbors, swept_sphere_radius, neighbor_index, support_dir,
871 support_value, tf, visited, polygon, tol);
877 template <
int _SupportOptions>
884 getShapeSupportLog<SupportOptions::NoSweptSphere>(
885 convex, support_dir, support, hint, support_data);
886 const CoalScalar support_value = support.dot(support_dir);
888 const std::vector<Vec3s>& points = *(convex->
points);
889 const std::vector<ConvexBase::Neighbors>& neighbors = *(convex->
neighbors);
891 std::vector<int8_t>& visited = support_data.
visited;
900 const size_t vertex_idx = (size_t)(hint);
901 convexSupportSetRecurse<_SupportOptions>(
902 points, neighbors, swept_sphere_radius, vertex_idx, support_dir,
903 support_value, tf, visited, polygon, tol);
909 template <
int _SupportOptions>
912 size_t num_sampled_supports ,
916 getShapeSupportSetLog<_SupportOptions>(
917 convex, support_set, hint, support_data, num_sampled_supports, tol);
919 getShapeSupportSetLinear<_SupportOptions>(
920 convex, support_set, hint, support_data, num_sampled_supports, tol);
926 template <
int _SupportOptions>
930 size_t num_sampled_supports ,
932 getShapeSupportSetLinear<_SupportOptions>(
933 reinterpret_cast<const ConvexBase*
>(convex), support_set, hint,
934 support_data, num_sampled_supports, tol);
939 template <
int _SupportOptions>
942 size_t num_sampled_supports ,
944 getShapeSupportSetLog<_SupportOptions>(
945 reinterpret_cast<const ConvexBase*
>(convex), support_set, hint,
946 support_data, num_sampled_supports, tol);
956 if (cloud.size() <= 2) {
958 for (
const Vec2s& point : cloud) {
959 cvx_hull.emplace_back(point);
964 if (cloud.size() == 3) {
969 if (cloud[0](1) > cloud[1](1)) {
970 std::swap(cloud[0], cloud[1]);
972 if (cloud[0](1) > cloud[2](1)) {
973 std::swap(cloud[0], cloud[2]);
975 const Vec2s&
a = cloud[0];
976 const Vec2s&
b = cloud[1];
977 const Vec2s&
c = cloud[2];
979 (
b(0) -
a(0)) * (
c(1) -
a(1)) - (
b(1) -
a(1)) * (
c(0) -
a(0));
981 std::swap(cloud[1], cloud[2]);
984 for (
const Vec2s& point : cloud) {
985 cvx_hull.emplace_back(point);
997 size_t support_idx = 0;
999 for (
size_t i = 1; i < cloud.size(); ++i) {
1001 if (
val < support_val) {
1006 std::swap(cloud[0], cloud[support_idx]);
1008 cvx_hull.emplace_back(cloud[0]);
1009 const Vec2s&
v = cvx_hull[0];
1015 cloud.begin() + 1, cloud.end(), [&
v](
const Vec2s&
p1,
const Vec2s& p2) {
1017 const CoalScalar det =
1018 (p1(0) - v(0)) * (p2(1) - v(1)) - (p1(1) - v(1)) * (p2(0) - v(0));
1019 if (std::abs(det) <= Eigen::NumTraits<CoalScalar>::dummy_precision()) {
1022 return ((p1 - v).squaredNorm() <= (p2 - v).squaredNorm());
1035 (p2(0) -
p1(0)) * (p3(1) -
p1(1)) - (p2(1) -
p1(1)) * (p3(0) -
p1(0));
1038 return det > Eigen::NumTraits<CoalScalar>::dummy_precision();
1045 size_t cloud_beginning_idx = 1;
1046 while (cvx_hull.size() < 3) {
1047 const Vec2s&
vec = cloud[cloud_beginning_idx];
1048 if ((cvx_hull.back() - vec).squaredNorm() >
1050 cvx_hull.emplace_back(vec);
1052 ++cloud_beginning_idx;
1059 for (
size_t i = cloud_beginning_idx; i < cloud.size(); ++i) {
1061 while (cvx_hull.size() > 1 &&
1062 !isRightSided(cvx_hull[cvx_hull.size() - 2],
1063 cvx_hull[cvx_hull.size() - 1], vec)) {
1064 cvx_hull.pop_back();
1066 cvx_hull.emplace_back(vec);