40 #ifndef COAL_NARROWPHASE_H 
   41 #define COAL_NARROWPHASE_H 
   59   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
 
   75   COAL_DEPRECATED_MESSAGE(Use gjk_initial_guess 
instead)
 
   76   bool enable_cached_guess;
 
   98   mutable details::EPA epa;
 
  101   size_t epa_max_iterations;
 
  107   mutable details::MinkowskiDiff minkowski_difference;
 
  128         enable_cached_guess(false),  
 
  129         cached_guess(
Vec3s(1, 0, 0)),
 
  131         distance_upper_bound((std::numeric_limits<
CoalScalar>::max)()),
 
  149       : 
gjk(request.gjk_max_iterations, request.gjk_tolerance),
 
  150         epa(0, request.epa_tolerance) {
 
  151     this->cached_guess = 
Vec3s(1, 0, 0);
 
  152     this->support_func_cached_guess = support_func_guess_t::Zero();
 
  167         this->enable_cached_guess) {
 
  174     this->distance_upper_bound = (std::numeric_limits<CoalScalar>::max)();
 
  177     this->gjk_convergence_criterion_type =
 
  187     this->epa.status = details::EPA::Status::DidNotRun;
 
  188     this->gjk.
status = details::GJK::Status::DidNotRun;
 
  201       : 
gjk(request.gjk_max_iterations, request.gjk_tolerance),
 
  202         epa(0, request.epa_tolerance) {
 
  203     this->cached_guess = 
Vec3s(1, 0, 0);
 
  204     this->support_func_cached_guess = support_func_guess_t::Zero();
 
  219         this->enable_cached_guess) {
 
  227     this->distance_upper_bound = (std::max)(
 
  231     this->gjk_convergence_criterion_type =
 
  241     this->gjk.
status = details::GJK::Status::DidNotRun;
 
  242     this->epa.status = details::EPA::Status::DidNotRun;
 
  251     return this->enable_cached_guess ==
 
  260            this->gjk_convergence_criterion_type ==
 
  273     return compute_penetration
 
  274                ? (std::max)(this->gjk_tolerance, this->epa_tolerance)
 
  275                : this->gjk_tolerance;
 
  307   template <
typename S1, 
typename S2>
 
  311                            Vec3s& normal)
 const {
 
  312     constexpr 
bool relative_transformation_already_computed = 
false;
 
  315                        normal, relative_transformation_already_computed);
 
  322   template <
typename S1>
 
  326                            Vec3s& normal)
 const {
 
  331     constexpr 
bool relative_transformation_already_computed = 
true;
 
  333     this->runGJKAndEPA(s1, 
tf1, tri, tf_1M2, compute_penetration, 
distance, 
p1,
 
  334                        p2, normal, relative_transformation_already_computed);
 
  339   template <
typename S2>
 
  343                            Vec3s& normal)
 const {
 
  345         s2, 
tf2, s1, 
tf1, compute_penetration, p2, 
p1, normal);
 
  353   template <
typename S1, 
typename S2>
 
  356                           const Vec3s& default_guess = 
Vec3s(1, 0, 0))
 const {
 
  359     support_hint = this->support_func_cached_guess;
 
  361     switch (gjk_initial_guess) {
 
  363         guess = default_guess;
 
  366         guess = this->cached_guess;
 
  369         if (s1.aabb_local.volume() < 0 || s2.aabb_local.volume() < 0) {
 
  371               "computeLocalAABB must have been called on the shapes before " 
  373               "GJKInitialGuess::BoundingVolumeGuess.",
 
  377             s1.aabb_local.center() -
 
  378             (this->minkowski_difference.oR1 * s2.aabb_local.center() +
 
  379              this->minkowski_difference.ot1);
 
  387     if (this->enable_cached_guess) {
 
  388       guess = this->cached_guess;
 
  420   template <
typename S1, 
typename S2,
 
  426       const bool relative_transformation_already_computed = 
false)
 const {
 
  428     if (relative_transformation_already_computed)
 
  429       this->minkowski_difference.set<_SupportOptions>(&s1, &s2);
 
  431       this->minkowski_difference.set<_SupportOptions>(&s1, &s2, 
tf1, 
tf2);
 
  432     this->gjk.
reset(this->gjk_max_iterations, this->gjk_tolerance);
 
  437     this->epa.status = details::EPA::Status::DidNotRun;
 
  442     getGJKInitialGuess(*(this->minkowski_difference.shapes[0]),
 
  443                        *(this->minkowski_difference.shapes[1]), guess,
 
  446     this->gjk.
evaluate(this->minkowski_difference, guess, support_hint);
 
  448     switch (this->gjk.
status) {
 
  450         COAL_ASSERT(
false, 
"GJK did not run. It should have!",
 
  452         this->cached_guess = 
Vec3s(1, 0, 0);
 
  453         this->support_func_cached_guess.setZero();
 
  454         distance = -(std::numeric_limits<CoalScalar>::max)();
 
  456             Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
 
  462         GJKExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  469         GJKEarlyStopExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2,
 
  472                                     this->m_dummy_precision,
 
  473                     "The distance should be bigger than GJK's " 
  474                     "`distance_upper_bound`.",
 
  482         GJKExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  485                     "The distance found by GJK should coincide with the " 
  486                     "distance between the closest points.",
 
  493         GJKExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  495             distance <= this->
gjk.getTolerance() + this->m_dummy_precision,
 
  496             "The distance found by GJK should be negative or at " 
  497             "least below GJK's tolerance.",
 
  501         if (!compute_penetration) {
 
  503           GJKCollisionExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2,
 
  514           this->epa.reset(this->epa_max_iterations, this->epa_tolerance);
 
  518           this->epa.evaluate(this->gjk, -guess);
 
  520           switch (epa.status) {
 
  534               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  538               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  542               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  547                   -epa.depth <= epa.getTolerance() + this->m_dummy_precision,
 
  548                   "EPA's penetration distance should be negative (or " 
  549                   "at least below EPA's tolerance).",
 
  551               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  555                   "EPA warning: created a polytope with a degenerated face.");
 
  556               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  560                   "EPA warning: EPA got called onto non-convex shapes.");
 
  561               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  565               EPAExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2, normal);
 
  568               COAL_ASSERT(
false, 
"EPA did not run. It should have!",
 
  571               EPAFailedExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2,
 
  577                   "EPA went into fallback mode. It should never do that.",
 
  580               EPAFailedExtractWitnessPointsAndNormal(
tf1, 
distance, 
p1, p2,
 
  592                                                  Vec3s& normal)
 const {
 
  595     this->cached_guess = this->gjk.
ray;
 
  596     this->support_func_cached_guess = this->gjk.
support_hint;
 
  600         Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
 
  620                     this->gjk.getTolerance() - this->m_dummy_precision,
 
  621                 "The norm of GJK's ray should be bigger than GJK's tolerance.",
 
  624     this->cached_guess = this->gjk.
ray;
 
  625     this->support_func_cached_guess = this->gjk.
support_hint;
 
  630     gjk.getWitnessPointsAndNormal(this->minkowski_difference, 
p1, p2, normal);
 
  632     normal = 
tf1.getRotation() * normal;
 
  634     p2.noalias() = p + 0.5 * 
distance * normal;
 
  640                                                  Vec3s& normal)
 const {
 
  643                     this->gjk.getTolerance() + this->m_dummy_precision,
 
  644                 "The distance should be lower than GJK's tolerance.",
 
  650     this->support_func_cached_guess = this->gjk.
support_hint;
 
  654         Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
 
  662     this->cached_guess = -(this->epa.depth * this->epa.normal);
 
  663     this->support_func_cached_guess = this->epa.support_hint;
 
  664     distance = (std::min)(0., -this->epa.depth);
 
  665     this->epa.getWitnessPointsAndNormal(this->minkowski_difference, 
p1, p2,
 
  707     normal = 
tf1.getRotation() * normal;
 
  709     p2.noalias() = p + 0.5 * 
distance * normal;
 
  715     this->cached_guess = 
Vec3s(1, 0, 0);
 
  716     this->support_func_cached_guess.setZero();
 
  719     distance = -(std::numeric_limits<CoalScalar>::max)();
 
  721         Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());