38 #ifndef FCL_NARROWPHASE_DETAIL_PLANE_INL_H
39 #define FCL_NARROWPHASE_DETAIL_PLANE_INL_H
53 std::vector<ContactPoint<double>>* contacts);
59 std::vector<ContactPoint<double>>* contacts);
65 std::vector<ContactPoint<double>>* contacts);
76 std::vector<ContactPoint<double>>* contacts);
87 std::vector<ContactPoint<double>>* contacts);
93 std::vector<ContactPoint<double>>* contacts);
99 Vector3<double>* contact_points,
double* penetration_depth, Vector3<double>* normal);
104 const Vector3<double>& P1,
const Vector3<double>& P2,
const Vector3<double>& P3,
const Transform3<double>& tf2,
105 Vector3<double>* contact_points,
double* penetration_depth, Vector3<double>* normal);
111 std::vector<ContactPoint<double>>* contacts);
114 template <
typename S>
121 template <
typename S>
130 const S depth = - std::abs(signed_dist) + s1.
radius;
136 const Vector3<S> normal = (signed_dist > 0) ? (-new_s2.
n).eval() : new_s2.
n;
138 const S penetration_depth = depth;
140 contacts->emplace_back(normal,
point, penetration_depth);
152 template <
typename S>
164 const Vector3<S> normal2(std::pow(new_s2.
n[0], 2), std::pow(new_s2.
n[1], 2), std::pow(new_s2.
n[2], 2));
166 const S center_to_contact_plane = std::sqrt(normal2.dot(radii2));
168 const S signed_dist = -new_s2.
d;
171 const S depth = center_to_contact_plane - std::abs(signed_dist);
178 const Vector3<S> normal = (signed_dist > 0) ? (tf1.linear() * -new_s2.
n).eval() : (tf1.linear() * new_s2.
n).eval();
179 const Vector3<S> support_vector = (1.0/center_to_contact_plane) *
Vector3<S>(radii2[0]*new_s2.
n[0], radii2[1]*new_s2.
n[1], radii2[2]*new_s2.
n[2]);
180 const Vector3<S> point_in_plane_coords = support_vector * (depth / new_s2.
n.dot(support_vector) - 1.0);
181 const Vector3<S> point = (signed_dist > 0) ? tf1 * point_in_plane_coords : tf1 * -point_in_plane_coords;
182 const S penetration_depth = depth;
184 contacts->emplace_back(normal,
point, penetration_depth);
196 template <
typename S>
211 S depth = 0.5 * (B[0] + B[1] + B[2]) - std::abs(signed_dist);
212 if(depth < 0)
return false;
224 int sign = (signed_dist > 0) ? 1 : -1;
226 if(std::abs(Q[0] - 1) < planeIntersectTolerance<S>() || std::abs(Q[0] + 1) < planeIntersectTolerance<S>())
228 int sign2 = (A[0] > 0) ? -1 : 1;
230 p += axis[0] * (0.5 * s1.
side[0] * sign2);
232 else if(std::abs(Q[1] - 1) < planeIntersectTolerance<S>() || std::abs(Q[1] + 1) < planeIntersectTolerance<S>())
234 int sign2 = (A[1] > 0) ? -1 : 1;
236 p += axis[1] * (0.5 * s1.
side[1] * sign2);
238 else if(std::abs(Q[2] - 1) < planeIntersectTolerance<S>() || std::abs(Q[2] + 1) < planeIntersectTolerance<S>())
240 int sign2 = (A[2] > 0) ? -1 : 1;
242 p += axis[2] * (0.5 * s1.
side[2] * sign2);
246 for(std::size_t i = 0; i < 3; ++i)
248 int sign2 = (A[i] > 0) ? -1 : 1;
250 p += axis[i] * (0.5 * s1.
side[i] * sign2);
257 const Vector3<S> normal = (signed_dist > 0) ? (-new_s2.
n).eval() : new_s2.
n;
259 const S penetration_depth = depth;
261 contacts->emplace_back(normal,
point, penetration_depth);
268 template <
typename S>
289 return (std::abs(d1) <= s1.
radius) || (std::abs(d2) <= s1.
radius);
293 template <
typename S>
318 S abs_d1 = std::abs(d1);
319 S abs_d2 = std::abs(d2);
325 if(d1 * d2 < -planeIntersectTolerance<S>())
331 const Vector3<S> normal = (d1 < 0) ? (-new_s2.
n).eval() : new_s2.
n;
332 const Vector3<S> point = p1 * (abs_d2 / (abs_d1 + abs_d2)) + p2 * (abs_d1 / (abs_d1 + abs_d2));
333 const S penetration_depth = abs_d1 + s1.
radius;
335 contacts->emplace_back(normal,
point, penetration_depth);
342 const Vector3<S> normal = (d2 < 0) ? (-new_s2.
n).eval() : new_s2.
n;
343 const Vector3<S> point = p1 * (abs_d2 / (abs_d1 + abs_d2)) + p2 * (abs_d1 / (abs_d1 + abs_d2));
344 const S penetration_depth = abs_d2 + s1.
radius;
346 contacts->emplace_back(normal,
point, penetration_depth);
360 const Vector3<S> normal = (d1 < 0) ? new_s2.
n : (-new_s2.
n).eval();
367 point = (c1 + c2) * 0.5;
369 else if(abs_d1 <= s1.
radius)
376 assert(abs_d2 <= s1.
radius);
382 contacts->emplace_back(normal,
point, penetration_depth);
391 template <
typename S>
402 S term = std::abs(Q[2]) * s1.
lz + s1.
radius * std::sqrt(Q[0] * Q[0] + Q[1] * Q[1]);
404 S depth = term - dist;
413 template <
typename S>
430 S cosa = dir_z.dot(new_s2.
n);
432 if(std::abs(cosa) < planeIntersectTolerance<S>())
435 S depth = s1.
radius - std::abs(d);
436 if(depth < 0)
return false;
441 const Vector3<S> normal = (d < 0) ? new_s2.
n : (-new_s2.
n).eval();
443 const S penetration_depth = depth;
445 contacts->emplace_back(normal,
point, penetration_depth);
453 if(std::abs(cosa + 1) < planeIntersectTolerance<S>() || std::abs(cosa - 1) < planeIntersectTolerance<S>())
482 S abs_d1 = std::abs(d1);
483 S abs_d2 = std::abs(d2);
489 const Vector3<S> normal = (d2 < 0) ? (-new_s2.
n).eval() : new_s2.
n;
491 const S penetration_depth = abs_d2;
493 contacts->emplace_back(normal,
point, penetration_depth);
500 const Vector3<S> normal = (d1 < 0) ? (-new_s2.
n).eval() : new_s2.
n;
502 const S penetration_depth = abs_d1;
504 contacts->emplace_back(normal,
point, penetration_depth);
518 template <
typename S>
529 S cosa = dir_z.dot(new_s2.
n);
531 if(std::abs(cosa) < planeIntersectTolerance<S>())
534 S depth = s1.
radius - std::abs(d);
535 if(depth < 0)
return false;
540 const Vector3<S> normal = (d < 0) ? new_s2.
n : (-new_s2.
n).eval();
542 const S penetration_depth = depth;
544 contacts->emplace_back(normal,
point, penetration_depth);
553 if(std::abs(cosa + 1) < planeIntersectTolerance<S>() || std::abs(cosa - 1) < planeIntersectTolerance<S>())
563 c[0] = T + dir_z * (0.5 * s1.
lz);
564 c[1] = T - dir_z * (0.5 * s1.
lz) + C;
565 c[2] = T - dir_z * (0.5 * s1.
lz) - C;
572 if((d[0] >= 0 && d[1] >= 0 && d[2] >= 0) || (d[0] <= 0 && d[1] <= 0 && d[2] <= 0))
577 for(std::size_t i = 0; i < 3; ++i)
578 positive[i] = (d[i] >= 0);
581 S d_positive = 0, d_negative = 0;
582 for(std::size_t i = 0; i < 3; ++i)
587 if(d_positive <= d[i]) d_positive = d[i];
591 if(d_negative <= -d[i]) d_negative = -d[i];
597 const Vector3<S> normal = (d_positive > d_negative) ? (-new_s2.
n).eval() : new_s2.
n;
598 const S penetration_depth =
std::min(d_positive, d_negative);
609 for(std::size_t i = 0, j = 0; i < 3; ++i)
611 if(positive[i]) { p[j] = c[i]; p_d[j] = d[i]; j++; }
612 else { q = c[i]; q_d = d[i]; }
615 const Vector3<S> t1 = (-p[0] * q_d + q * p_d[0]) / (-q_d + p_d[0]);
616 const Vector3<S> t2 = (-p[1] * q_d + q * p_d[1]) / (-q_d + p_d[1]);
617 point = (t1 + t2) * 0.5;
621 for(std::size_t i = 0, j = 0; i < 3; ++i)
623 if(!positive[i]) { p[j] = c[i]; p_d[j] = d[i]; j++; }
624 else { q = c[i]; q_d = d[i]; }
627 const Vector3<S> t1 = (p[0] * q_d - q * p_d[0]) / (q_d - p_d[0]);
628 const Vector3<S> t2 = (p[1] * q_d - q * p_d[1]) / (q_d - p_d[1]);
629 point = (t1 + t2) * 0.5;
632 contacts->emplace_back(normal,
point, penetration_depth);
641 template <
typename S>
657 if(d < d_min) { d_min = d; v_min = p; }
658 if(d > d_max) { d_max = d; v_max = p; }
661 if(d_min * d_max > 0)
return false;
664 if(d_min + d_max > 0)
666 if(penetration_depth) *penetration_depth = -d_min;
667 if(normal) *normal = -new_s2.
n;
668 if(contact_points) *contact_points = v_min - new_s2.
n * d_min;
672 if(penetration_depth) *penetration_depth = d_max;
673 if(normal) *normal = new_s2.
n;
674 if(contact_points) *contact_points = v_max - new_s2.
n * d_max;
681 template <
typename S>
698 if((d[0] >= 0 && d[1] >= 0 && d[2] >= 0) || (d[0] <= 0 && d[1] <= 0 && d[2] <= 0))
703 for(std::size_t i = 0; i < 3; ++i)
704 positive[i] = (d[i] > 0);
707 S d_positive = 0, d_negative = 0;
708 for(std::size_t i = 0; i < 3; ++i)
713 if(d_positive <= d[i]) d_positive = d[i];
717 if(d_negative <= -d[i]) d_negative = -d[i];
721 if(penetration_depth) *penetration_depth =
std::min(d_positive, d_negative);
722 if(normal) *normal = (d_positive > d_negative) ? new_s1.
n : (-new_s1.
n).eval();
733 for(std::size_t i = 0, j = 0; i < 3; ++i)
735 if(positive[i]) { p[j] = c[i]; p_d[j] = d[i]; j++; }
736 else { q = c[i]; q_d = d[i]; }
739 Vector3<S> t1 = (-p[0] * q_d + q * p_d[0]) / (-q_d + p_d[0]);
740 Vector3<S> t2 = (-p[1] * q_d + q * p_d[1]) / (-q_d + p_d[1]);
741 *contact_points = (t1 + t2) * 0.5;
745 for(std::size_t i = 0, j = 0; i < 3; ++i)
747 if(!positive[i]) { p[j] = c[i]; p_d[j] = d[i]; j++; }
748 else { q = c[i]; q_d = d[i]; }
751 Vector3<S> t1 = (p[0] * q_d - q * p_d[0]) / (q_d - p_d[0]);
752 Vector3<S> t2 = (p[1] * q_d - q * p_d[1]) / (q_d - p_d[1]);
753 *contact_points = (t1 + t2) * 0.5;
761 template <
typename S>
769 S a = (new_s1.
n).dot(new_s2.
n);
770 if(a == 1 && new_s1.
d != new_s2.
d)
772 if(a == -1 && new_s1.
d != -new_s2.
d)