38 #ifndef FCL_NARROWPHASE_GJKSOLVERINDEP_INL_H 39 #define FCL_NARROWPHASE_GJKSOLVERINDEP_INL_H 41 #include "fcl/narrowphase/detail/gjk_solver_indep.h" 45 #include "fcl/geometry/shape/triangle_p.h" 46 #include "fcl/narrowphase/detail/convexity_based_algorithm/gjk.h" 47 #include "fcl/narrowphase/detail/convexity_based_algorithm/epa.h" 48 #include "fcl/narrowphase/detail/primitive_shape_algorithm/capsule_capsule.h" 49 #include "fcl/narrowphase/detail/primitive_shape_algorithm/sphere_capsule.h" 50 #include "fcl/narrowphase/detail/primitive_shape_algorithm/sphere_sphere.h" 51 #include "fcl/narrowphase/detail/primitive_shape_algorithm/sphere_triangle.h" 52 #include "fcl/narrowphase/detail/primitive_shape_algorithm/box_box.h" 53 #include "fcl/narrowphase/detail/primitive_shape_algorithm/halfspace.h" 54 #include "fcl/narrowphase/detail/primitive_shape_algorithm/plane.h" 64 struct GJKSolver_indep<double>;
68 template<
typename Shape1,
typename Shape2>
70 const Shape2& s2,
const Transform3<S>& tf2,
71 Vector3<S>* contact_points, S* penetration_depth, Vector3<S>* normal)
const 75 if (contact_points || penetration_depth || normal)
77 std::vector<ContactPoint<S>> contacts;
79 res = shapeIntersect(s1, tf1, s2, tf2, &contacts);
81 if (!contacts.empty())
84 const ContactPoint<S>& maxDepthContact = *std::max_element(contacts.begin(), contacts.end(), comparePenDepth<S>);
87 *contact_points = maxDepthContact.pos;
89 if (penetration_depth)
90 *penetration_depth = maxDepthContact.penetration_depth;
93 *normal = maxDepthContact.normal;
98 res = shapeIntersect(s1, tf1, s2, tf2,
nullptr);
105 template<
typename S,
typename Shape1,
typename Shape2>
111 const Transform3<S>& tf1,
113 const Transform3<S>& tf2,
116 Vector3<S> guess(1, 0, 0);
122 shape.
toshape1.noalias() = tf2.linear().transpose() * tf1.linear();
123 shape.
toshape0 = tf1.inverse(Eigen::Isometry) * tf2;
126 typename detail::GJK<S>::Status gjk_status = gjk.
evaluate(shape, -guess);
134 typename detail::EPA<S>::Status epa_status = epa.evaluate(gjk, -guess);
137 Vector3<S> w0 = Vector3<S>::Zero();
138 for(
size_t i = 0; i < epa.result.rank; ++i)
140 w0.noalias() += shape.
support(epa.result.c[i]->d, 0) * epa.result.p[i];
144 Vector3<S> normal = epa.normal;
145 Vector3<S> point = tf1 * (w0 - epa.normal*(epa.depth *0.5));
146 S depth = -epa.depth;
147 contacts->emplace_back(normal, point, depth);
164 template<
typename Shape1,
typename Shape2>
167 const Transform3<S>& tf1,
169 const Transform3<S>& tf2,
173 *
this, s1, tf1, s2, tf2, contacts);
200 #define FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT_REG(SHAPE1, SHAPE2, ALG)\ 201 template <typename S>\ 202 struct ShapeIntersectIndepImpl<S, SHAPE1<S>, SHAPE2<S>>\ 205 const GJKSolver_indep<S>& ,\ 206 const SHAPE1<S>& s1,\ 207 const Transform3<S>& tf1,\ 208 const SHAPE2<S>& s2,\ 209 const Transform3<S>& tf2,\ 210 std::vector<ContactPoint<S>>* contacts)\ 212 return ALG(s1, tf1, s2, tf2, contacts);\ 216 #define FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT_INV(SHAPE1, SHAPE2, ALG)\ 217 template <typename S>\ 218 struct ShapeIntersectIndepImpl<S, SHAPE2<S>, SHAPE1<S>>\ 221 const GJKSolver_indep<S>& ,\ 222 const SHAPE2<S>& s1,\ 223 const Transform3<S>& tf1,\ 224 const SHAPE1<S>& s2,\ 225 const Transform3<S>& tf2,\ 226 std::vector<ContactPoint<S>>* contacts)\ 228 const bool res = ALG(s2, tf2, s1, tf1, contacts);\ 229 if (contacts) flipNormal(*contacts);\ 234 #define FCL_GJK_INDEP_SHAPE_INTERSECT(SHAPE, ALG)\ 235 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT_REG(SHAPE, SHAPE, ALG) 237 #define FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(SHAPE1, SHAPE2, ALG)\ 238 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT_REG(SHAPE1, SHAPE2, ALG)\ 239 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT_INV(SHAPE1, SHAPE2, ALG) 241 FCL_GJK_INDEP_SHAPE_INTERSECT(
Sphere, detail::sphereSphereIntersect)
242 FCL_GJK_INDEP_SHAPE_INTERSECT(
Box, detail::boxBoxIntersect)
244 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Sphere,
Capsule, detail::sphereCapsuleIntersect)
246 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Sphere,
Halfspace, detail::sphereHalfspaceIntersect)
247 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Ellipsoid,
Halfspace, detail::ellipsoidHalfspaceIntersect)
248 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Box,
Halfspace, detail::boxHalfspaceIntersect)
249 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Capsule,
Halfspace, detail::capsuleHalfspaceIntersect)
250 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Cylinder,
Halfspace, detail::cylinderHalfspaceIntersect)
251 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Cone,
Halfspace, detail::coneHalfspaceIntersect)
253 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Sphere,
Plane, detail::spherePlaneIntersect)
254 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Ellipsoid,
Plane, detail::ellipsoidPlaneIntersect)
255 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Box,
Plane, detail::boxPlaneIntersect)
256 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Capsule,
Plane, detail::capsulePlaneIntersect)
257 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Cylinder,
Plane, detail::cylinderPlaneIntersect)
258 FCL_GJK_INDEP_SHAPE_SHAPE_INTERSECT(
Cone,
Plane, detail::conePlaneIntersect)
260 template <
typename S>
266 const Transform3<S>& tf1,
268 const Transform3<S>& tf2,
275 return detail::halfspaceIntersect(s1, tf1, s2, tf2, p, d, s, depth, ret);
279 template <
typename S>
285 const Transform3<S>& tf1,
287 const Transform3<S>& tf2,
290 return detail::planeIntersect(s1, tf1, s2, tf2, contacts);
294 template <
typename S>
300 const Transform3<S>& tf1,
302 const Transform3<S>& tf2,
309 return detail::planeHalfspaceIntersect(s1, tf1, s2, tf2, pl, p, d, depth, ret);
313 template <
typename S>
319 const Transform3<S>& tf1,
321 const Transform3<S>& tf2,
328 return detail::halfspacePlaneIntersect(s1, tf1, s2, tf2, pl, p, d, depth, ret);
333 template<
typename S,
typename Shape>
339 const Transform3<S>& tf,
340 const Vector3<S>& P1,
341 const Vector3<S>& P2,
342 const Vector3<S>& P3,
343 Vector3<S>* contact_points,
344 S* penetration_depth,
349 Vector3<S> guess(1, 0, 0);
356 shape.
toshape0 = tf.inverse(Eigen::Isometry);
359 typename detail::GJK<S>::Status gjk_status = gjk.
evaluate(shape, -guess);
367 typename detail::EPA<S>::Status epa_status = epa.evaluate(gjk, -guess);
370 Vector3<S> w0 = Vector3<S>::Zero();
371 for(
size_t i = 0; i < epa.result.rank; ++i)
373 w0.noalias() += shape.
support(epa.result.c[i]->d, 0) * epa.result.p[i];
375 if(penetration_depth) *penetration_depth = -epa.depth;
376 if(normal) *normal = -epa.normal;
377 if(contact_points) (*contact_points).noalias() = tf * (w0 - epa.normal*(epa.depth *0.5));
392 template<
typename Shape>
395 const Transform3<S>& tf,
396 const Vector3<S>& P1,
397 const Vector3<S>& P2,
398 const Vector3<S>& P3,
399 Vector3<S>* contact_points,
400 S* penetration_depth,
401 Vector3<S>* normal)
const 404 *
this, s, tf, P1, P2, P3, contact_points, penetration_depth, normal);
414 const Transform3<S>& tf,
415 const Vector3<S>& P1,
416 const Vector3<S>& P2,
417 const Vector3<S>& P3,
418 Vector3<S>* contact_points,
419 S* penetration_depth,
422 return detail::sphereTriangleIntersect(
423 s, tf, P1, P2, P3, contact_points, penetration_depth, normal);
429 template<
typename S,
typename Shape>
435 const Transform3<S>& tf1,
436 const Vector3<S>& P1,
437 const Vector3<S>& P2,
438 const Vector3<S>& P3,
439 const Transform3<S>& tf2,
440 Vector3<S>* contact_points,
441 S* penetration_depth,
446 Vector3<S> guess(1, 0, 0);
452 shape.
toshape1.noalias() = tf2.linear().transpose() * tf1.linear();
453 shape.
toshape0 = tf1.inverse(Eigen::Isometry) * tf2;
456 typename detail::GJK<S>::Status gjk_status = gjk.
evaluate(shape, -guess);
464 typename detail::EPA<S>::Status epa_status = epa.evaluate(gjk, -guess);
467 Vector3<S> w0 = Vector3<S>::Zero();
468 for(
size_t i = 0; i < epa.result.rank; ++i)
470 w0.noalias() += shape.
support(epa.result.c[i]->d, 0) * epa.result.p[i];
472 if(penetration_depth) *penetration_depth = -epa.depth;
473 if(normal) *normal = -epa.normal;
474 if(contact_points) (*contact_points).noalias() = tf1 * (w0 - epa.normal*(epa.depth *0.5));
489 template<
typename Shape>
492 const Transform3<S>& tf1,
493 const Vector3<S>& P1,
494 const Vector3<S>& P2,
495 const Vector3<S>& P3,
496 const Transform3<S>& tf2,
497 Vector3<S>* contact_points,
498 S* penetration_depth,
499 Vector3<S>* normal)
const 502 *
this, s, tf1, P1, P2, P3, tf2,
503 contact_points, penetration_depth, normal);
513 const Transform3<S>& tf1,
514 const Vector3<S>& P1,
515 const Vector3<S>& P2,
516 const Vector3<S>& P3,
517 const Transform3<S>& tf2,
518 Vector3<S>* contact_points,
519 S* penetration_depth,
522 return detail::sphereTriangleIntersect(
523 s, tf1, tf2 * P1, tf2 * P2, tf2 * P3,
524 contact_points, penetration_depth, normal);
535 const Transform3<S>& tf1,
536 const Vector3<S>& P1,
537 const Vector3<S>& P2,
538 const Vector3<S>& P3,
539 const Transform3<S>& tf2,
540 Vector3<S>* contact_points,
541 S* penetration_depth,
544 return detail::halfspaceTriangleIntersect(
545 s, tf1, P1, P2, P3, tf2,
546 contact_points, penetration_depth, normal);
557 const Transform3<S>& tf1,
558 const Vector3<S>& P1,
559 const Vector3<S>& P2,
560 const Vector3<S>& P3,
561 const Transform3<S>& tf2,
562 Vector3<S>* contact_points,
563 S* penetration_depth,
566 return detail::planeTriangleIntersect(
567 s, tf1, P1, P2, P3, tf2,
568 contact_points, penetration_depth, normal);
573 template<
typename S,
typename Shape1,
typename Shape2>
579 const Transform3<S>& tf1,
581 const Transform3<S>& tf2,
586 Vector3<S> guess(1, 0, 0);
592 shape.
toshape1.noalias() = tf2.linear().transpose() * tf1.linear();
593 shape.
toshape0 = tf1.inverse(Eigen::Isometry) * tf2;
596 typename detail::GJK<S>::Status gjk_status = gjk.
evaluate(shape, -guess);
601 Vector3<S> w0 = Vector3<S>::Zero();
602 Vector3<S> w1 = Vector3<S>::Zero();
603 for(
size_t i = 0; i < gjk.
getSimplex()->rank; ++i)
610 if(distance) *distance = (w0 - w1).norm();
613 if(p2) (*p2).noalias() = shape.
toshape0 * w1;
619 if(distance) *distance = -1;
626 template<
typename Shape1,
typename Shape2>
629 const Transform3<S>& tf1,
631 const Transform3<S>& tf2,
634 Vector3<S>* p2)
const 637 *
this, s1, tf1, s2, tf2, dist, p1, p2);
671 const Transform3<S>& tf1,
673 const Transform3<S>& tf2,
678 return detail::sphereCapsuleDistance(s1, tf1, s2, tf2, dist, p1, p2);
689 const Transform3<S>& tf1,
691 const Transform3<S>& tf2,
696 return detail::sphereCapsuleDistance(s2, tf2, s1, tf1, dist, p2, p1);
707 const Transform3<S>& tf1,
709 const Transform3<S>& tf2,
714 return detail::sphereSphereDistance(s1, tf1, s2, tf2, dist, p1, p2);
725 const Transform3<S>& tf1,
727 const Transform3<S>& tf2,
732 return detail::capsuleCapsuleDistance(s1, tf1, s2, tf2, dist, p1, p2);
737 template<
typename S,
typename Shape>
743 const Transform3<S>& tf,
744 const Vector3<S>& P1,
745 const Vector3<S>& P2,
746 const Vector3<S>& P3,
752 Vector3<S> guess(1, 0, 0);
759 shape.
toshape0 = tf.inverse(Eigen::Isometry);
762 typename detail::GJK<S>::Status gjk_status = gjk.
evaluate(shape, -guess);
767 Vector3<S> w0 = Vector3<S>::Zero();
768 Vector3<S> w1 = Vector3<S>::Zero();
769 for(
size_t i = 0; i < gjk.
getSimplex()->rank; ++i)
776 if(distance) *distance = (w0 - w1).norm();
778 if(p2) (*p2).noalias() = shape.
toshape0 * w1;
783 if(distance) *distance = -1;
791 template<
typename Shape>
794 const Transform3<S>& tf,
795 const Vector3<S>& P1,
796 const Vector3<S>& P2,
797 const Vector3<S>& P3,
800 Vector3<S>* p2)
const 803 *
this, s, tf, P1, P2, P3, dist, p1, p2);
813 const Transform3<S>& tf,
814 const Vector3<S>& P1,
815 const Vector3<S>& P2,
816 const Vector3<S>& P3,
821 return detail::sphereTriangleDistance(s, tf, P1, P2, P3, dist, p1, p2);
826 template<
typename S,
typename Shape>
832 const Transform3<S>& tf1,
833 const Vector3<S>& P1,
834 const Vector3<S>& P2,
835 const Vector3<S>& P3,
836 const Transform3<S>& tf2,
842 Vector3<S> guess(1, 0, 0);
848 shape.
toshape1.noalias() = tf2.linear().transpose() * tf1.linear();
849 shape.
toshape0 = tf1.inverse(Eigen::Isometry) * tf2;
852 typename detail::GJK<S>::Status gjk_status = gjk.
evaluate(shape, -guess);
857 Vector3<S> w0 = Vector3<S>::Zero();
858 Vector3<S> w1 = Vector3<S>::Zero();
859 for(
size_t i = 0; i < gjk.
getSimplex()->rank; ++i)
866 if(distance) *distance = (w0 - w1).norm();
868 if(p2) (*p2).noalias() = shape.
toshape0 * w1;
873 if(distance) *distance = -1;
881 template<
typename Shape>
884 const Transform3<S>& tf1,
885 const Vector3<S>& P1,
886 const Vector3<S>& P2,
887 const Vector3<S>& P3,
888 const Transform3<S>& tf2,
891 Vector3<S>* p2)
const 894 *
this, s, tf1, P1, P2, P3, tf2, dist, p1, p2);
904 const Transform3<S>& tf1,
905 const Vector3<S>& P1,
906 const Vector3<S>& P2,
907 const Vector3<S>& P3,
908 const Transform3<S>& tf2,
913 return detail::sphereTriangleDistance(
914 s, tf1, P1, P2, P3, tf2, dist, p1, p2);
919 template <
typename S>
922 gjk_max_iterations = 128;
923 gjk_tolerance = 1e-6;
924 epa_max_face_num = 128;
925 epa_max_vertex_num = 64;
926 epa_max_iterations = 255;
927 epa_tolerance = 1e-6;
928 enable_cached_guess =
false;
929 cached_guess = Vector3<S>(1, 0, 0);
933 template <
typename S>
936 enable_cached_guess = if_enable;
940 template <
typename S>
943 cached_guess = guess;
947 template <
typename S>
Triangle stores the points instead of only indices of points.
Definition: triangle_p.h:48
Half Space: this is equivalent to the Planed in ODE. The separation plane is defined as n * x = d; Po...
Definition: halfspace.h:55
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
Minkowski difference class of two shapes.
Definition: minkowski_diff.h:58
bool shapeTriangleDistance(const Shape &s, const Transform3< S > &tf, const Vector3< S > &P1, const Vector3< S > &P2, const Vector3< S > &P3, S *distance=nullptr, Vector3< S > *p1=nullptr, Vector3< S > *p2=nullptr) const
distance computation between one shape and a triangle
Definition: gjk_solver_indep-inl.h:792
Vector3< S > cached_guess
smart guess
Definition: gjk_solver_indep.h:171
S gjk_max_iterations
maximum number of iterations used for GJK iterations
Definition: gjk_solver_indep.h:165
class for EPA algorithm
Definition: epa.h:57
bool shapeDistance(const Shape1 &s1, const Transform3< S > &tf1, const Shape2 &s2, const Transform3< S > &tf2, S *distance=nullptr, Vector3< S > *p1=nullptr, Vector3< S > *p2=nullptr) const
distance computation between two shapes
Definition: gjk_solver_indep-inl.h:627
Center at zero point ellipsoid.
Definition: ellipsoid.h:48
S gjk_tolerance
the threshold used in GJK to stop iteration
Definition: gjk_solver_indep.h:162
GJKSolver_indep()
default setting for GJK algorithm
Definition: gjk_solver_indep-inl.h:920
const ShapeBase< S > * shapes[2]
points to two shapes
Definition: minkowski_diff.h:61
Definition: gjk_solver_indep-inl.h:738
Vector3< S > support(const Vector3< S > &d) const
support function for the pair of shapes
Definition: minkowski_diff-inl.h:231
bool enable_cached_guess
Whether smart guess can be provided.
Definition: gjk_solver_indep.h:168
Vector3< S > getGuessFromSimplex() const
get the guess from current simplex
Definition: gjk-inl.h:75
Transform3< S > toshape0
transform from shape1 to shape0
Definition: minkowski_diff.h:67
Center at zero point capsule.
Definition: capsule.h:48
Definition: gjk_solver_indep-inl.h:574
Center at zero point, axis aligned box.
Definition: box.h:48
Definition: gjk_solver_indep-inl.h:106
unsigned int epa_max_iterations
maximum number of iterations used for EPA iterations
Definition: gjk_solver_indep.h:156
Matrix3< S > toshape1
rotation from shape0 to shape1
Definition: minkowski_diff.h:64
unsigned int epa_max_face_num
maximum number of simplex face used in EPA algorithm
Definition: gjk_solver_indep.h:150
Infinite plane.
Definition: plane.h:48
Center at zero cylinder.
Definition: cylinder.h:48
Status evaluate(const MinkowskiDiff< S > &shape_, const Vector3< S > &guess)
GJK algorithm, given the initial value guess.
Definition: gjk-inl.h:82
Center at zero cone.
Definition: cone.h:48
unsigned int epa_max_vertex_num
maximum number of simplex vertex used in EPA algorithm
Definition: gjk_solver_indep.h:153
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.
Definition: kIOS-inl.h:266
Simplex * getSimplex() const
get the underlying simplex using in GJK, can be used for cache in next iteration
Definition: gjk-inl.h:302
collision and distance solver based on GJK algorithm implemented in fcl (rewritten the code from the ...
Definition: gjk_solver_indep.h:53
class for GJK algorithm
Definition: gjk.h:52
Center at zero point sphere.
Definition: sphere.h:48
S epa_tolerance
the threshold used in EPA to stop iteration
Definition: gjk_solver_indep.h:159
FCL_DEPRECATED bool shapeIntersect(const Shape1 &s1, const Transform3< S > &tf1, const Shape2 &s2, const Transform3< S > &tf2, Vector3< S > *contact_points, S *penetration_depth, Vector3< S > *normal) const
intersection checking between two shapes
Definition: gjk_solver_indep-inl.h:334
bool shapeTriangleIntersect(const Shape &s, const Transform3< S > &tf, const Vector3< S > &P1, const Vector3< S > &P2, const Vector3< S > &P3, Vector3< S > *contact_points=nullptr, S *penetration_depth=nullptr, Vector3< S > *normal=nullptr) const
intersection checking between one shape and a triangle
Definition: gjk_solver_indep-inl.h:393