55 support = triangle->
c;
57 support = triangle->
a;
60 support = triangle->
c;
62 support = triangle->
b;
85 Vec3f v(a2 * dir[0], b2 * dir[1], c2 * dir[2]);
108 if (dir.head<2>().isZero()) {
113 support[2] = -inflate * h;
116 FCL_REAL zdist = dir[0] * dir[0] + dir[1] * dir[1];
117 FCL_REAL len = zdist + dir[2] * dir[2];
118 zdist = std::sqrt(zdist);
122 support.head<2>() = rad * dir.head<2>();
127 len = std::sqrt(len);
128 FCL_REAL sin_a = r / std::sqrt(r * r + 4 * h * h);
130 if (dir[2] > len * sin_a)
134 support.head<2>() = rad * dir.head<2>();
148 if (dir.head<2>() == Eigen::Matrix<FCL_REAL, 2, 1>::Zero()) half_h *=
inflate;
153 support[2] = -half_h;
158 if (dir.head<2>() == Eigen::Matrix<FCL_REAL, 2, 1>::Zero())
161 support.head<2>() = dir.head<2>().normalized() *
r;
162 assert(fabs(support[0] * dir[1] - support[1] * dir[0]) <
170 Vec3f& support,
int& hint,
172 assert(data != NULL);
177 if (hint < 0 || hint >= (
int)convex->
num_points) hint = 0;
178 FCL_REAL maxdot = pts[hint].dot(dir);
179 std::vector<int8_t>& visited = data->
visited;
181 visited[
static_cast<std::size_t
>(hint)] =
true;
184 bool found =
true, loose_check =
true;
188 for (
int in = 0; in < n.
count(); ++in) {
189 const unsigned int ip = n[in];
190 if (visited[ip])
continue;
192 const FCL_REAL dot = pts[ip].dot(dir);
197 }
else if (loose_check && dot == maxdot)
201 hint =
static_cast<int>(ip);
211 Vec3f& support,
int& hint,
217 for (
int i = 1; i < (int)convex->
num_points; ++i) {
239 Vec3f& support,
int& hint,
242 support, hint, data);
246 Vec3f& support,
int& hint,
252 #define CALL_GET_SHAPE_SUPPORT(ShapeType) \ 254 static_cast<const ShapeType*>(shape), \ 255 (shape_traits<ShapeType>::NeedNormalizedDir && !dirIsNormalized) \ 298 #undef CALL_GET_SHAPE_SUPPORT 300 template <
typename Shape0,
typename Shape1,
bool TransformIsIdentity>
306 if (TransformIsIdentity)
309 getShapeSupport(s1, -oR1.transpose() * dir, support1, hint[1], &(data[1]));
310 support1 = oR1 * support1 + ot1;
314 template <
typename Shape0,
typename Shape1,
bool TransformIsIdentity>
316 bool dirIsNormalized,
Vec3f& support0,
Vec3f& support1,
325 assert(!NeedNormalizedDir || !dirIsNormalized ||
326 fabs(dir.squaredNorm() - 1) < 1e-6);
328 assert(!NeedNormalizedDir || dirIsNormalized ||
329 fabs(dir.normalized().squaredNorm() - 1) < 1e-6);
331 assert(NeedNormalizedDir || dir.cwiseAbs().maxCoeff() >= 1e-6);
333 getSupportTpl<Shape0, Shape1, TransformIsIdentity>(
334 static_cast<const Shape0*
>(md.
shapes[0]),
335 static_cast<const Shape1*>(md.
shapes[1]), md.
oR1, md.
ot1,
336 (NeedNormalizedDir && !dirIsNormalized) ? dir.normalized() : dir,
337 support0, support1, hint, data);
340 template <
typename Shape0>
342 const ShapeBase* s1,
bool identity, Eigen::Array<FCL_REAL, 1, 2>& inflation,
343 int linear_log_convex_threshold) {
348 return getSupportFuncTpl<Shape0, TriangleP, true>;
350 return getSupportFuncTpl<Shape0, TriangleP, false>;
353 return getSupportFuncTpl<Shape0, Box, true>;
355 return getSupportFuncTpl<Shape0, Box, false>;
357 inflation[1] =
static_cast<const Sphere*
>(s1)->radius;
359 return getSupportFuncTpl<Shape0, Sphere, true>;
361 return getSupportFuncTpl<Shape0, Sphere, false>;
364 return getSupportFuncTpl<Shape0, Ellipsoid, true>;
366 return getSupportFuncTpl<Shape0, Ellipsoid, false>;
368 inflation[1] =
static_cast<const Capsule*
>(s1)->radius;
370 return getSupportFuncTpl<Shape0, Capsule, true>;
372 return getSupportFuncTpl<Shape0, Capsule, false>;
375 return getSupportFuncTpl<Shape0, Cone, true>;
377 return getSupportFuncTpl<Shape0, Cone, false>;
380 return getSupportFuncTpl<Shape0, Cylinder, true>;
382 return getSupportFuncTpl<Shape0, Cylinder, false>;
384 if ((
int)
static_cast<const ConvexBase*
>(s1)->num_points >
385 linear_log_convex_threshold) {
387 return getSupportFuncTpl<Shape0, LargeConvex, true>;
389 return getSupportFuncTpl<Shape0, LargeConvex, false>;
392 return getSupportFuncTpl<Shape0, SmallConvex, true>;
394 return getSupportFuncTpl<Shape0, SmallConvex, false>;
397 throw std::logic_error(
"Unsupported geometric shape");
403 Eigen::Array<FCL_REAL, 1, 2>& inflation,
int linear_log_convex_threshold) {
407 return makeGetSupportFunction1<TriangleP>(s1, identity, inflation,
408 linear_log_convex_threshold);
411 return makeGetSupportFunction1<Box>(s1, identity, inflation,
412 linear_log_convex_threshold);
415 inflation[0] =
static_cast<const Sphere*
>(s0)->radius;
416 return makeGetSupportFunction1<Sphere>(s1, identity, inflation,
417 linear_log_convex_threshold);
420 return makeGetSupportFunction1<Ellipsoid>(s1, identity, inflation,
421 linear_log_convex_threshold);
424 inflation[0] =
static_cast<const Capsule*
>(s0)->radius;
425 return makeGetSupportFunction1<Capsule>(s1, identity, inflation,
426 linear_log_convex_threshold);
429 return makeGetSupportFunction1<Cone>(s1, identity, inflation,
430 linear_log_convex_threshold);
433 return makeGetSupportFunction1<Cylinder>(s1, identity, inflation,
434 linear_log_convex_threshold);
437 if ((
int)
static_cast<const ConvexBase*
>(s0)->num_points >
438 linear_log_convex_threshold)
439 return makeGetSupportFunction1<LargeConvex>(
440 s1, identity, inflation, linear_log_convex_threshold);
442 return makeGetSupportFunction1<SmallConvex>(
443 s1, identity, inflation, linear_log_convex_threshold);
446 throw std::logic_error(
"Unsupported geometric shape");
477 throw std::logic_error(
"Unsupported geometric shape");
483 bool& normalize_support_direction) {
493 normalize_support_direction);
499 bool identity = (oR1.isIdentity() && ot1.isZero());
502 linear_log_convex_threshold);
509 normalize_support_direction);
515 linear_log_convex_threshold);
521 distance_upper_bound = (std::numeric_limits<FCL_REAL>::max)();
536 assert(vs[i]->w.isApprox(vs[i]->
w0 - vs[i]->
w1));
539 Project::ProjectResult projection;
540 switch (simplex.
rank) {
546 const Vec3f &
a = vs[0]->
w, a0 = vs[0]->
w0, a1 = vs[0]->
w1,
b = vs[1]->
w,
547 b0 = vs[1]->
w0, b1 = vs[1]->
w1;
556 lb = N.squaredNorm();
564 w0 = la * a0 + lb * b0;
565 w1 = la * a1 + lb * b1;
572 projection = Project::projectTriangleOrigin(vs[0]->w, vs[1]->w, vs[2]->w);
575 projection = Project::projectTetrahedraOrigin(vs[0]->w, vs[1]->w,
579 throw std::logic_error(
"The simplex rank must be in [ 1, 4 ]");
584 w0 += projection.parameterization[i] * vs[i]->
w0;
585 w1 += projection.parameterization[i] * vs[i]->
w1;
591 template <
bool Separated>
593 const Eigen::Array<FCL_REAL, 1, 2>& I(shape.
inflation);
594 Eigen::Array<bool, 1, 2>
inflate(I > 0);
595 if (!inflate.any())
return;
600 if (inflate[0]) w0[0] += I[0] * (Separated ? -1 : 1);
601 if (inflate[1]) w1[0] += I[1] * (Separated ? 1 : -1);
607 if (inflate[0]) w0 -= I[0] * w;
608 if (inflate[1]) w1 += I[1] * w;
610 if (inflate[0]) w0 += I[0] * w;
611 if (inflate[1]) w1 -= I[1] * w;
619 if (!res)
return false;
620 details::inflate<true>(shape, w0, w1);
629 const FCL_REAL upper_bound = distance_upper_bound + inflation;
631 free_v[0] = &store_v[0];
632 free_v[1] = &store_v[1];
633 free_v[2] = &store_v[2];
634 free_v[3] = &store_v[3];
641 simplices[0].rank = 0;
642 support_hint = supportHint;
645 if (rl < tolerance) {
646 ray =
Vec3f(-1, 0, 0);
657 bool normalize_support_direction = shape->normalize_support_direction;
660 Simplex& curr_simplex = simplices[current];
661 Simplex& next_simplex = simplices[next];
678 switch (current_gjk_variant) {
686 if (normalize_support_direction) {
688 y = momentum * ray + (1 - momentum) * w;
694 assert(y_norm > tolerance);
695 dir = momentum * dir / dir.norm() + (1 - momentum) * y / y_norm;
698 y = momentum * ray + (1 - momentum) * w;
699 dir = momentum * dir + (1 - momentum) * y;
704 throw std::logic_error(
"Invalid momentum variant.");
707 appendVertex(curr_simplex, -dir,
false,
715 FCL_REAL omega = dir.dot(w) / dir.norm();
716 if (omega > upper_bound) {
718 status = EarlyStopped;
724 FCL_REAL frank_wolfe_duality_gap = 2 * ray.dot(ray - w);
725 if (frank_wolfe_duality_gap - tolerance <= 0) {
726 removeVertex(simplices[current]);
734 bool cv_check_passed = checkConvergence(w, rl, alpha, omega);
738 if (iterations > 0 && cv_check_passed) {
739 if (iterations > 0) removeVertex(simplices[current]);
748 if (
distance < tolerance) status = Inside;
755 switch (curr_simplex.
rank) {
757 assert(iterations == 0);
760 next_simplex.
rank = 1;
764 inside = projectLineOrigin(curr_simplex, next_simplex);
767 inside = projectTriangleOrigin(curr_simplex, next_simplex);
770 inside = projectTetrahedraOrigin(curr_simplex, next_simplex);
773 throw std::logic_error(
"Invalid simplex rank");
775 assert(nfree + next_simplex.
rank == 4);
777 if (!inside) rl = ray.norm();
778 if (inside || rl == 0) {
784 status = ((++iterations) < max_iterations) ? status : Failed;
786 }
while (status == Valid);
788 simplex = &simplices[current];
789 assert(simplex->rank > 0 && simplex->rank < 5);
802 switch (convergence_criterion) {
805 alpha = std::max(alpha, omega);
808 switch (convergence_criterion_type) {
810 throw std::logic_error(
"VDB convergence criterion is relative.");
813 check_passed = (diff - tolerance * rl) <= 0;
816 throw std::logic_error(
"Invalid convergence criterion type.");
822 diff = 2 * ray.dot(ray - w);
823 switch (convergence_criterion_type) {
825 check_passed = (diff - tolerance) <= 0;
828 check_passed = ((diff / tolerance * rl) - tolerance * rl) <= 0;
831 throw std::logic_error(
"Invalid convergence criterion type.");
837 alpha = std::max(alpha, omega);
839 diff = rl * rl - alpha * alpha;
840 switch (convergence_criterion_type) {
842 check_passed = (diff - tolerance) <= 0;
845 check_passed = ((diff / tolerance * rl) - tolerance * rl) <= 0;
848 throw std::logic_error(
"Invalid convergence criterion type.");
853 throw std::logic_error(
"Invalid convergence criterion.");
859 free_v[nfree++] = simplex.
vertex[--simplex.
rank];
864 simplex.
vertex[simplex.
rank] = free_v[--nfree];
871 switch (simplex->rank) {
873 for (
int i = 0; i < 3; ++i) {
875 appendVertex(*simplex, axis,
true, hint);
876 if (encloseOrigin())
return true;
877 removeVertex(*simplex);
879 appendVertex(*simplex, -axis,
true, hint);
880 if (encloseOrigin())
return true;
881 removeVertex(*simplex);
886 Vec3f d = simplex->vertex[1]->w - simplex->vertex[0]->w;
887 for (
int i = 0; i < 3; ++i) {
889 Vec3f p = d.cross(axis);
891 appendVertex(*simplex, p,
false, hint);
892 if (encloseOrigin())
return true;
893 removeVertex(*simplex);
894 appendVertex(*simplex, -p,
false, hint);
895 if (encloseOrigin())
return true;
896 removeVertex(*simplex);
903 (simplex->vertex[1]->w - simplex->vertex[0]->w)
904 .cross(simplex->vertex[2]->w - simplex->vertex[0]->w);
905 if (!axis.isZero()) {
906 appendVertex(*simplex, axis,
false, hint);
907 if (encloseOrigin())
return true;
908 removeVertex(*simplex);
909 appendVertex(*simplex, -axis,
false, hint);
910 if (encloseOrigin())
return true;
911 removeVertex(*simplex);
915 if (std::abs(
triple(simplex->vertex[0]->w - simplex->vertex[3]->w,
916 simplex->vertex[1]->w - simplex->vertex[3]->w,
917 simplex->vertex[2]->w - simplex->vertex[3]->w)) > 0)
938 ray = AB.dot(B) * A + ABdotAO * B;
945 ray /= AB.squaredNorm();
970 ray = -ABCdotAO / ABC.squaredNorm() * ABC;
980 const Vec3f AB = B - A;
982 assert(d <= AB.squaredNorm());
991 free_v[nfree++] = current.
vertex[
b];
996 free_v[nfree++] = current.
vertex[
b];
1008 const Vec3f AB =
B - A, AC = C - A, ABC = AB.cross(AC);
1010 FCL_REAL edgeAC2o = ABC.cross(AC).dot(-A);
1011 if (edgeAC2o >= 0) {
1013 if (towardsC >= 0) {
1015 free_v[nfree++] = current.
vertex[
b];
1021 free_v[nfree++] = current.
vertex[
b];
1024 free_v[nfree++] = current.
vertex[
c];
1027 FCL_REAL edgeAB2o = AB.cross(ABC).dot(-A);
1028 if (edgeAB2o >= 0) {
1033 free_v[nfree++] = current.
vertex[
b];
1036 free_v[nfree++] = current.
vertex[
c];
1051 const FCL_REAL aa = A.squaredNorm();
1070 const Vec3f a_cross_b = A.cross(B);
1071 const Vec3f a_cross_c = A.cross(C);
1076 #define REGION_INSIDE() \ 1078 next.vertex[0] = current.vertex[d]; \ 1079 next.vertex[1] = current.vertex[c]; \ 1080 next.vertex[2] = current.vertex[b]; \ 1081 next.vertex[3] = current.vertex[a]; \ 1086 if (-D.dot(a_cross_b) <= 0) {
1087 if (ba * da_ba + bd * ba_aa - bb * da_aa <=
1090 assert(da * da_ba + dd * ba_aa - db * da_aa <=
1092 if (ba * ba_ca + bb * ca_aa - bc * ba_aa <=
1096 -C.dot(a_cross_b), next, ray);
1097 free_v[nfree++] = current.
vertex[d];
1101 free_v[nfree++] = current.
vertex[
c];
1102 free_v[nfree++] = current.
vertex[d];
1105 if (ba * ba_ca + bb * ca_aa - bc * ba_aa <=
1107 if (ca * ba_ca + cb * ca_aa - cc * ba_aa <=
1109 if (ca * ca_da + cc * da_aa - cd * ca_aa <=
1113 -D.dot(a_cross_c), next, ray);
1114 free_v[nfree++] = current.
vertex[
b];
1118 free_v[nfree++] = current.
vertex[
b];
1119 free_v[nfree++] = current.
vertex[d];
1124 -C.dot(a_cross_b), next, ray);
1125 free_v[nfree++] = current.
vertex[d];
1130 free_v[nfree++] = current.
vertex[
c];
1131 free_v[nfree++] = current.
vertex[d];
1135 if (da * da_ba + dd * ba_aa - db * da_aa <=
1139 D.dot(a_cross_b), next, ray);
1140 free_v[nfree++] = current.
vertex[
c];
1142 if (ca * ca_da + cc * da_aa - cd * ca_aa <=
1144 if (da * ca_da + dc * da_aa - dd * ca_aa <=
1148 free_v[nfree++] = current.
vertex[
b];
1149 free_v[nfree++] = current.
vertex[
c];
1153 -D.dot(a_cross_c), next, ray);
1154 free_v[nfree++] = current.
vertex[
b];
1157 if (da * ca_da + dc * da_aa - dd * ca_aa <=
1161 free_v[nfree++] = current.
vertex[
b];
1162 free_v[nfree++] = current.
vertex[
c];
1166 free_v[nfree++] = current.
vertex[
b];
1167 free_v[nfree++] = current.
vertex[d];
1173 if (C.dot(a_cross_b) <= 0) {
1174 if (ba * ba_ca + bb * ca_aa - bc * ba_aa <=
1176 if (ca * ba_ca + cb * ca_aa - cc * ba_aa <=
1178 if (ca * ca_da + cc * da_aa - cd * ca_aa <=
1182 -D.dot(a_cross_c), next, ray);
1183 free_v[nfree++] = current.
vertex[
b];
1187 free_v[nfree++] = current.
vertex[
b];
1188 free_v[nfree++] = current.
vertex[d];
1193 -C.dot(a_cross_b), next, ray);
1194 free_v[nfree++] = current.
vertex[d];
1199 free_v[nfree++] = current.
vertex[
c];
1200 free_v[nfree++] = current.
vertex[d];
1203 if (D.dot(a_cross_c) <= 0) {
1204 if (ca * ca_da + cc * da_aa - cd * ca_aa <=
1206 if (da * ca_da + dc * da_aa - dd * ca_aa <=
1210 free_v[nfree++] = current.
vertex[
b];
1211 free_v[nfree++] = current.
vertex[
c];
1215 -D.dot(a_cross_c), next, ray);
1216 free_v[nfree++] = current.
vertex[
b];
1222 free_v[nfree++] = current.
vertex[
b];
1223 free_v[nfree++] = current.
vertex[d];
1227 free_v[nfree++] = current.
vertex[
b];
1228 free_v[nfree++] = current.
vertex[
c];
1239 if (D.dot(a_cross_c) <= 0) {
1241 if (ca * ca_da + cc * da_aa - cd * ca_aa <=
1243 if (da * ca_da + dc * da_aa - dd * ca_aa <=
1245 if (da * da_ba + dd * ba_aa - db * da_aa <=
1249 D.dot(a_cross_b), next, ray);
1250 free_v[nfree++] = current.
vertex[
c];
1254 free_v[nfree++] = current.
vertex[
b];
1255 free_v[nfree++] = current.
vertex[
c];
1260 -D.dot(a_cross_c), next, ray);
1261 free_v[nfree++] = current.
vertex[
b];
1264 assert(!(da * ca_da + dc * da_aa - dd * ca_aa <=
1267 if (ca * ba_ca + cb * ca_aa - cc * ba_aa <=
1271 free_v[nfree++] = current.
vertex[
b];
1272 free_v[nfree++] = current.
vertex[d];
1276 -C.dot(a_cross_b), next, ray);
1277 free_v[nfree++] = current.
vertex[d];
1281 if (ca * ba_ca + cb * ca_aa - cc * ba_aa <=
1283 if (ca * ca_da + cc * da_aa - cd * ca_aa <=
1285 assert(!(da * ca_da + dc * da_aa - dd * ca_aa <=
1290 -D.dot(a_cross_c), next, ray);
1291 free_v[nfree++] = current.
vertex[
b];
1295 free_v[nfree++] = current.
vertex[
b];
1296 free_v[nfree++] = current.
vertex[d];
1299 if (C.dot(a_cross_b) <=
1301 assert(ba * ba_ca + bb * ca_aa - bc * ba_aa <=
1306 -C.dot(a_cross_b), next, ray);
1307 free_v[nfree++] = current.
vertex[d];
1309 assert(!(da * ca_da + dc * da_aa - dd * ca_aa <=
1314 -D.dot(a_cross_c), next, ray);
1315 free_v[nfree++] = current.
vertex[
b];
1320 if (C.dot(a_cross_b) <= 0) {
1321 if (ca * ba_ca + cb * ca_aa - cc * ba_aa <=
1325 free_v[nfree++] = current.
vertex[
b];
1326 free_v[nfree++] = current.
vertex[d];
1328 assert(ba * ba_ca + bb * ca_aa - bc * ba_aa <=
1333 -C.dot(a_cross_b), next, ray);
1334 free_v[nfree++] = current.
vertex[d];
1337 if (-D.dot(a_cross_b) <= 0) {
1338 if (da * da_ba + dd * ba_aa - db * da_aa <=
1342 D.dot(a_cross_b), next, ray);
1343 free_v[nfree++] = current.
vertex[
c];
1347 free_v[nfree++] = current.
vertex[
b];
1348 free_v[nfree++] = current.
vertex[
c];
1358 if (-D.dot(a_cross_b) <= 0) {
1359 if (da * ca_da + dc * da_aa - dd * ca_aa <=
1361 if (da * da_ba + dd * ba_aa - db * da_aa <=
1363 assert(!(ba * da_ba + bd * ba_aa - bb * da_aa <=
1368 D.dot(a_cross_b), next, ray);
1369 free_v[nfree++] = current.
vertex[
c];
1373 free_v[nfree++] = current.
vertex[
b];
1374 free_v[nfree++] = current.
vertex[
c];
1377 if (D.dot(a_cross_c) <=
1379 assert(ca * ca_da + cc * da_aa - cd * ca_aa <=
1384 -D.dot(a_cross_c), next, ray);
1385 free_v[nfree++] = current.
vertex[
b];
1387 if (C.dot(a_cross_b) <=
1389 assert(!(ba * ba_ca + bb * ca_aa - bc * ba_aa <=
1394 D.dot(a_cross_b), next, ray);
1395 free_v[nfree++] = current.
vertex[
c];
1399 D.dot(a_cross_b), next, ray);
1400 free_v[nfree++] = current.
vertex[
c];
1405 if (D.dot(a_cross_c) <= 0) {
1406 if (da * ca_da + dc * da_aa - dd * ca_aa <=
1410 free_v[nfree++] = current.
vertex[
b];
1411 free_v[nfree++] = current.
vertex[
c];
1413 assert(ca * ca_da + cc * da_aa - cd * ca_aa <=
1418 -D.dot(a_cross_c), next, ray);
1419 free_v[nfree++] = current.
vertex[
b];
1429 free_v[nfree++] = current.
vertex[
b];
1430 free_v[nfree++] = current.
vertex[
c];
1431 free_v[nfree++] = current.
vertex[d];
1436 #undef REGION_INSIDE 1441 sv_store =
new SimplexV[max_vertex_num];
1442 fc_store =
new SimplexF[max_face_num];
1444 normal =
Vec3f(0, 0, 0);
1447 for (
size_t i = 0; i < max_face_num; ++i)
1448 stock.append(&fc_store[max_face_num - i - 1]);
1454 Vec3f n_ab = ab.cross(face->
n);
1467 else if (b_dot_ab < 0)
1470 dist = std::sqrt(std::max(
1471 a->
w.squaredNorm() - a_dot_ab * a_dot_ab / ab.squaredNorm(), 0.));
1490 face->
n = (b->
w - a->
w).cross(c->
w - a->
w);
1496 if (!(getEdgeDist(face, a, b, face->
d) ||
1497 getEdgeDist(face, b, c, face->
d) ||
1498 getEdgeDist(face, c, a, face->
d))) {
1499 face->
d = a->
w.dot(face->
n);
1502 if (forced || face->
d >= -tolerance)
1507 status = Degenerated;
1514 status = stock.root ? OutOfVertices : OutOfFaces;
1522 for (
SimplexF* f = minf->
l[1]; f; f = f->
l[1]) {
1559 if (hull.count == 4) {
1564 size_t iterations = 0;
1567 bind(tetrahedron[0], 0, tetrahedron[1], 0);
1568 bind(tetrahedron[0], 1, tetrahedron[2], 0);
1569 bind(tetrahedron[0], 2, tetrahedron[3], 0);
1570 bind(tetrahedron[1], 1, tetrahedron[3], 2);
1571 bind(tetrahedron[1], 2, tetrahedron[2], 1);
1572 bind(tetrahedron[2], 2, tetrahedron[3], 1);
1575 for (; iterations < max_iterations; ++iterations) {
1576 if (nextsv >= max_vertex_num) {
1577 status = OutOfVertices;
1584 best->
pass = ++pass;
1589 if (wdist <= tolerance) {
1590 status = AccuracyReached;
1593 for (
size_t j = 0; (j < 3) && valid; ++j)
1594 valid &= expand(pass, w, best->
f[j], best->
e[j], horizon);
1596 if (!valid || horizon.
nf < 3) {
1598 assert(!(status & Valid));
1602 bind(horizon.
ff, 2, horizon.
cf, 1);
1612 result.vertex[0] = outer.
vertex[0];
1613 result.vertex[1] = outer.
vertex[1];
1614 result.vertex[2] = outer.
vertex[2];
1631 normal =
Vec3f(1, 0, 0);
1634 result.vertex[0] = simplex.
vertex[0];
1641 static const size_t nexti[] = {1, 2, 0};
1642 static const size_t previ[] = {2, 0, 1};
1644 if (f->
pass == pass) {
1645 status = InvalidHull;
1649 const size_t e1 = nexti[e];
1667 bind(nf, 2, horizon.
cf, 1);
1680 const size_t e2 = previ[e];
1682 if (expand(pass, w, f->
f[e1], f->
e[e1], horizon) &&
1683 expand(pass, w, f->
f[e2], f->
e[e2], horizon)) {
1693 if (!res)
return false;
1694 details::inflate<false>(shape, w0, w1);
SimplexF * findBest()
Find the best polytope face to split.
Vec3f halfSide
box side half-length
SimplexF * newFace(SimplexV *a, SimplexV *b, SimplexV *vertex, bool forced)
SimplexV * vertex[4]
simplex vertex
MinkowskiDiff::GetSupportFunction makeGetSupportFunction1(const ShapeBase *s1, bool identity, Eigen::Array< FCL_REAL, 1, 2 > &inflation, int linear_log_convex_threshold)
void getSupportTpl(const Shape0 *s0, const Shape1 *s1, const Matrix3f &oR1, const Vec3f &ot1, const Vec3f &dir, Vec3f &support0, Vec3f &support1, support_func_guess_t &hint, MinkowskiDiff::ShapeData data[2])
support_func_guess_t support_hint
void getShapeSupportLinear(const ConvexBase *convex, const Vec3f &dir, Vec3f &support, int &hint, MinkowskiDiff::ShapeData *)
Ellipsoid centered at point zero.
void(* GetSupportFunction)(const MinkowskiDiff &minkowskiDiff, const Vec3f &dir, bool dirIsNormalized, Vec3f &support0, Vec3f &support1, support_func_guess_t &hint, ShapeData data[2])
void getNormalizeSupportDirectionFromShapes(const ShapeBase *shape0, const ShapeBase *shape1, bool &normalize_support_direction)
GJKVariant
Variant to use for the GJK algorithm.
FCL_REAL halfLength
Half Length along z axis.
Cylinder along Z axis. The cylinder is defined at its centroid.
bool originToTriangle(const GJK::Simplex ¤t, GJK::vertex_id_t a, GJK::vertex_id_t b, GJK::vertex_id_t c, const Vec3f &ABC, const FCL_REAL &ABCdotAO, GJK::Simplex &next, Vec3f &ray)
std::vector< int8_t > visited
void appendVertex(Simplex &simplex, const Vec3f &v, bool isNormalized, support_func_guess_t &hint)
append one vertex to the simplex
bool encloseOrigin()
whether the simplex enclose the origin
FCL_REAL getTolerance()
Get GJK tolerance.
#define CALL_GET_SHAPE_SUPPORT(ShapeType)
void removeVertex(Simplex &simplex)
discard one vertex from the simplex
Eigen::Matrix< FCL_REAL, 3, 3 > Matrix3f
Vec3f getSupport(const ShapeBase *shape, const Vec3f &dir, bool dirIsNormalized, int &hint)
the support function for shape
void getShapeSupportLog(const ConvexBase *convex, const Vec3f &dir, Vec3f &support, int &hint, MinkowskiDiff::ShapeData *data)
bool getNormalizeSupportDirection(const ShapeBase *shape)
bool getClosestPoints(const MinkowskiDiff &shape, Vec3f &w0, Vec3f &w1)
void set(const ShapeBase *shape0, const ShapeBase *shape1)
Vec3f w
support vector (i.e., the furthest point on the shape along the support direction) ...
Minkowski difference class of two shapes.
bool projectTetrahedraOrigin(const Simplex ¤t, Simplex &next)
Project origin (0) onto tetrahedron a-b-c-d See projectLineOrigin for an explanation on simplex proje...
void getShapeSupport(const TriangleP *triangle, const Vec3f &dir, Vec3f &support, int &, MinkowskiDiff::ShapeData *)
Base class for all basic geometric shapes.
bool getClosestPoints(const MinkowskiDiff &shape, Vec3f &w0, Vec3f &w1)
Vec3f getGuessFromSimplex() const
get the guess from current simplex
virtual NODE_TYPE getNodeType() const
get the node type
HPP_FCL_DLLAPI FCL_REAL distance(const Matrix3f &R0, const Vec3f &T0, const kIOS &b1, const kIOS &b2, Vec3f *P=NULL, Vec3f *Q=NULL)
Approximate distance between two kIOS bounding volumes.
FCL_REAL radius
Radius of the cone.
bool projectLineOrigin(const Simplex ¤t, Simplex &next)
Project origin (0) onto line a-b For a detailed explanation of how to efficiently project onto a simp...
#define HPP_FCL_UNUSED_VARIABLE(var)
Vec3f ot1
translation from shape1 to shape0 such that .
Center at zero point, axis aligned box.
bool projectTriangleOrigin(const Simplex ¤t, Simplex &next)
Project origin (0) onto triangle a-b-c See projectLineOrigin for an explanation on simplex projection...
bool checkConvergence(const Vec3f &w, const FCL_REAL &rl, FCL_REAL &alpha, const FCL_REAL &omega)
Convergence check used to stop GJK when shapes are not in collision.
Status
Status of the GJK algorithm: Valid: GJK converged and the shapes are not in collision. Inside: GJK converged and the shapes are in collision. Failed: GJK did not converge.
Array2d inflation
The radius of the sphere swepted volume. The 2 values correspond to the inflation of shape 0 and shap...
Simplex * getSimplex() const
get the underlying simplex using in GJK, can be used for cache in next iteration
Triangle stores the points instead of only indices of points.
Eigen::Vector2i support_func_guess_t
void originToPoint(const GJK::Simplex ¤t, GJK::vertex_id_t a, const Vec3f &A, GJK::Simplex &next, Vec3f &ray)
Cone The base of the cone is at and the top is at .
Vec3f w0
support vector for shape 0 and 1.
unsigned char vertex_id_t
FCL_REAL radius
Radius of the cylinder.
MinkowskiDiff::GetSupportFunction makeGetSupportFunction0(const ShapeBase *s0, const ShapeBase *s1, bool identity, Eigen::Array< FCL_REAL, 1, 2 > &inflation, int linear_log_convex_threshold)
Center at zero point sphere.
Capsule It is where is the distance between the point x and the capsule segment AB...
size_t select(const NodeBase< BV > &query, const NodeBase< BV > &node1, const NodeBase< BV > &node2)
select from node1 and node2 which is close to a given query. 0 for node1 and 1 for node2 ...
Base for convex polytope.
const ShapeBase * shapes[2]
points to two shapes
unsigned char const & count() const
bool getEdgeDist(SimplexF *face, SimplexV *a, SimplexV *b, FCL_REAL &dist)
Status evaluate(GJK &gjk, const Vec3f &guess)
void setZero(std::vector< MatType, Eigen::aligned_allocator< MatType > > &Ms)
void inflate(const MinkowskiDiff &shape, Vec3f &w0, Vec3f &w1)
Inflate the points.
FCL_REAL halfLength
Half Length along z axis.
vertex_id_t rank
size of simplex (number of vertices)
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
Vec3f radii
Radii of the Ellipsoid (such that on boundary: x^2/rx^2 + y^2/ry^2.
void getSupportFuncTpl(const MinkowskiDiff &md, const Vec3f &dir, bool dirIsNormalized, Vec3f &support0, Vec3f &support1, support_func_guess_t &hint, MinkowskiDiff::ShapeData data[2])
Matrix3f oR1
rotation from shape1 to shape0 such that .
void originToSegment(const GJK::Simplex ¤t, GJK::vertex_id_t a, GJK::vertex_id_t b, const Vec3f &A, const Vec3f &B, const Vec3f &AB, const FCL_REAL &ABdotAO, GJK::Simplex &next, Vec3f &ray)
bool getClosestPoints(const GJK::Simplex &simplex, Vec3f &w0, Vec3f &w1)
bool expand(size_t pass, SimplexV *w, SimplexF *f, size_t e, SimplexHorizon &horizon)
the goal is to add a face connecting vertex w and face edge f[e]
void getSupport(const Vec3f &d, bool dIsNormalized, SimplexV &sv, support_func_guess_t &hint) const
apply the support function along a direction, the result is return in sv
static Derived::Scalar triple(const Eigen::MatrixBase< Derived > &x, const Eigen::MatrixBase< Derived > &y, const Eigen::MatrixBase< Derived > &z)
FCL_REAL halfLength
Half Length along z axis.
Vec3f * points
An array of the points of the polygon.
Status evaluate(const MinkowskiDiff &shape, const Vec3f &guess, const support_func_guess_t &supportHint=support_func_guess_t::Zero())
GJK algorithm, given the initial value guess.