39 #ifndef COAL_SRC_NARROWPHASE_DETAILS_H
40 #define COAL_SRC_NARROWPHASE_DETAILS_H
62 }
else if (
c2 <= c1) {
87 normal = segment_point - s_c;
99 p1 = s_c + normal * r1;
100 p2 = segment_point - normal *
r2;
154 normal = (1 / dSp2) * Sp2;
155 p1 = S + r1 * normal;
157 assert(fabs(dist) - (
p1 - p2).norm() <
eps);
160 normal = p2 - .5 * (
A +
B);
161 assert(u.dot(normal) >= 0);
164 p1 = S + r1 * normal;
170 dist = dPS - r1 -
r2;
187 normal = (1 / dSp2) * Sp2;
188 p1 = S + r1 * normal;
190 assert(fabs(dist) - (
p1 - p2).norm() <
eps);
193 normal = p2 - .5 * (
A +
B);
195 p1 = S + r1 * normal;
204 if (ssr1 > 0 || ssr2 > 0) {
207 dist -= (ssr1 + ssr2);
225 Vec3s c1c2 = center2 - center1;
231 p1.noalias() = center1 + r1 * unit;
232 p2.noalias() = center2 -
r2 * unit;
239 Vec3s diff = p - from;
255 nearest.noalias() = from +
v *
t;
256 return diff.squaredNorm();
263 Vec3s edge2(p3 - p2);
267 Vec3s p2_to_p(p - p2);
268 Vec3s p3_to_p(p - p3);
270 Vec3s edge1_normal(edge1.cross(normal));
271 Vec3s edge2_normal(edge2.cross(normal));
272 Vec3s edge3_normal(edge3.cross(normal));
275 r1 = edge1_normal.dot(p1_to_p);
276 r2 = edge2_normal.dot(p2_to_p);
277 r3 = edge3_normal.dot(p3_to_p);
278 if ((r1 > 0 &&
r2 > 0 && r3 > 0) || (r1 <= 0 &&
r2 <= 0 && r3 <= 0)) {
298 tri_normal.normalize();
299 const Vec3s& center =
tf1.getTranslation();
308 Vec3s p1_to_center = center -
P1;
309 CoalScalar distance_from_plane = p1_to_center.dot(tri_normal);
311 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN()));
314 if (distance_from_plane < 0) {
315 distance_from_plane *= -1;
320 closest_point = center - tri_normal * distance_from_plane;
321 min_distance_sqr = distance_from_plane * distance_from_plane;
324 Vec3s nearest_on_edge;
328 if (distance_sqr < min_distance_sqr) {
329 min_distance_sqr = distance_sqr;
330 closest_point = nearest_on_edge;
333 if (distance_sqr < min_distance_sqr) {
334 min_distance_sqr = distance_sqr;
335 closest_point = nearest_on_edge;
339 normal = (closest_point - center).normalized();
361 Vec3s n_2(
tf2.getRotation().transpose() * new_h.
n);
366 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_2, hint);
367 p2 =
tf2.transform(p2);
370 p1.noalias() = p2 - dist * new_h.
n;
371 normal.noalias() = new_h.
n;
374 std::sqrt(Eigen::NumTraits<CoalScalar>::dummy_precision());
376 assert(new_h.
distance(
p1) <= dummy_precision);
395 Vec3s n_h1(
tf2.getRotation().transpose() * new_h[0].n);
396 Vec3s n_h2(
tf2.getRotation().transpose() * new_h[1].n);
401 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_h1, hint);
402 p2h1 =
tf2.transform(p2h1);
406 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_h2, hint);
407 p2h2 =
tf2.transform(p2h2);
409 CoalScalar dist1 = new_h[0].signedDistance(p2h1);
410 CoalScalar dist2 = new_h[1].signedDistance(p2h2);
413 std::sqrt(Eigen::NumTraits<CoalScalar>::dummy_precision());
417 if (dist1 >= dist2) {
420 p1.noalias() = p2 - dist * new_h[0].n;
421 normal.noalias() = new_h[0].n;
422 assert(new_h[0].
distance(
p1) <= dummy_precision);
426 p1.noalias() = p2 - dist * new_h[1].n;
427 normal.noalias() = new_h[1].n;
428 assert(new_h[1].
distance(
p1) <= dummy_precision);
447 bool outside =
false;
448 const Vec3s os_in_b_frame(Rb.transpose() * (os - ob));
450 CoalScalar min_d = (std::numeric_limits<CoalScalar>::max)();
451 for (
int i = 0; i < 3; ++i) {
453 if (os_in_b_frame(i) < -
b.halfSide(i)) {
454 pb.noalias() -=
b.halfSide(i) * Rb.col(i);
456 }
else if (os_in_b_frame(i) >
b.halfSide(i)) {
457 pb.noalias() +=
b.halfSide(i) * Rb.col(i);
460 pb.noalias() += os_in_b_frame(i) * Rb.col(i);
462 (facedist =
b.halfSide(i) - std::fabs(os_in_b_frame(i))) < min_d) {
475 if (os_in_b_frame(
axis) >= 0) {
476 normal = Rb.col(
axis);
478 normal = -Rb.col(
axis);
482 ps = os - s.
radius * normal;
483 if (!outside || dist <= 0) {
485 pb = ps - dist * normal;
491 if (ssrb > 0 || ssrs > 0) {
494 dist -= (ssrb + ssrs);
521 Vec3s dir = (new_s1.
n).cross(new_s2.
n);
526 if (new_s1.
n.dot(new_s2.
n) > 0) {
529 distance = -(std::numeric_limits<CoalScalar>::max)();
530 if (new_s1.
d <= new_s2.
d) {
533 p2 = new_s2.
n * new_s2.
d;
535 Eigen::NumTraits<CoalScalar>::dummy_precision());
538 p1 << new_s1.
n * new_s1.
d;
541 Eigen::NumTraits<CoalScalar>::dummy_precision());
546 p1 = new_s1.
n * new_s1.
d;
547 p2 = new_s2.
n * new_s2.
d;
553 distance = -(std::numeric_limits<CoalScalar>::max)();
559 ((new_s2.
n * new_s1.
d - new_s1.
n * new_s2.
d).cross(dir)) / dir_sq_norm;
567 if (ssr1 > 0 || ssr2 > 0) {
597 Vec3s dir = (new_s1.
n).cross(new_s2.
n);
603 distance = new_s1.
n.dot(new_s2.
n) > 0 ? (new_s2.
d - new_s1.
d)
604 : -(new_s1.
d + new_s2.
d);
605 p1 = new_s1.
n * new_s1.
d;
606 p2 = new_s2.
n * new_s2.
d;
608 Eigen::NumTraits<CoalScalar>::dummy_precision());
610 Eigen::NumTraits<CoalScalar>::dummy_precision());
615 distance = -(std::numeric_limits<CoalScalar>::max)();
621 ((new_s2.
n * new_s1.
d - new_s1.
n * new_s2.
d).cross(dir)) / dir_sq_norm;
629 if (ssr1 > 0 || ssr2 > 0) {
657 Vec3s dir = (new_s1.
n).cross(new_s2.
n);
662 p1 = new_s1.
n * new_s1.
d;
663 p2 = new_s2.
n * new_s2.
d;
665 Eigen::NumTraits<CoalScalar>::dummy_precision());
667 Eigen::NumTraits<CoalScalar>::dummy_precision());
670 if (
distance > Eigen::NumTraits<CoalScalar>::dummy_precision()) {
671 normal = (p2 -
p1).normalized();
679 distance = -(std::numeric_limits<CoalScalar>::max)();
685 ((new_s2.
n * new_s1.
d - new_s1.
n * new_s2.
d).cross(dir)) / dir_sq_norm;
693 if (ssr1 > 0 || ssr2 > 0) {
708 normal = u.normalized();
712 return std::max(depth1, std::max(depth2, depth3));
740 #endif // COAL_SRC_NARROWPHASE_DETAILS_H