39 #ifndef COAL_SRC_NARROWPHASE_DETAILS_H
40 #define COAL_SRC_NARROWPHASE_DETAILS_H
51 static inline void lineSegmentPointClosestToPoint(
const Vec3s& p,
62 }
else if (c2 <= c1) {
66 Vec3s Pb = s1 + v * b;
86 lineSegmentPointClosestToPoint(s_c, pos1, pos2, segment_point);
87 normal = segment_point - s_c;
93 static const CoalScalar eps(std::numeric_limits<CoalScalar>::epsilon());
99 p1 = s_c + normal * r1;
100 p2 = segment_point - normal * r2;
113 static const CoalScalar eps(sqrt(std::numeric_limits<CoalScalar>::epsilon()));
126 assert((B - A - (s2.
halfLength * 2) * u).norm() < eps);
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;
228 if (cdist > Eigen::NumTraits<CoalScalar>::epsilon()) unit = c1c2 / cdist;
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();
262 Vec3s edge1(p2 - p1);
263 Vec3s edge2(p3 - p2);
264 Vec3s edge3(p1 - p3);
266 Vec3s p1_to_p(p - p1);
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)) {
297 Vec3s tri_normal = (P2 - P1).cross(P3 - P1);
298 tri_normal.normalize();
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();
366 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_2, hint);
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);
401 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_h1, hint);
406 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_h2, hint);
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);
524 if (dir_sq_norm < std::numeric_limits<CoalScalar>::epsilon())
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);
600 if (dir_sq_norm < std::numeric_limits<CoalScalar>::epsilon())
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);
660 if (dir_sq_norm < std::numeric_limits<CoalScalar>::epsilon())
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) {
707 Vec3s u((P2 - P1).cross(P3 - P1));
708 normal = u.normalized();
712 return std::max(depth1, std::max(depth2, depth3));
Center at zero point, axis aligned box.
Definition: geometric_shapes.h:166
Capsule It is where is the distance between the point x and the capsule segment AB,...
Definition: geometric_shapes.h:383
Cylinder along Z axis. The cylinder is defined at its centroid.
Definition: geometric_shapes.h:560
Half Space: this is equivalent to the Plane in ODE. A Half space has a priviledged direction: the dir...
Definition: geometric_shapes.h:892
Infinite plane. A plane can be viewed as two half spaces; it has no priviledged direction....
Definition: geometric_shapes.h:983
Base class for all basic geometric shapes.
Definition: geometric_shapes.h:58
Center at zero point sphere.
Definition: geometric_shapes.h:240
Triangle stores the points instead of only indices of points.
Definition: geometric_shapes.h:110
#define COAL_UNUSED_VARIABLE(var)
Definition: fwd.hh:56
CoalScalar distance(const Matrix3s &R0, const Vec3s &T0, const kIOS &b1, const kIOS &b2, Vec3s *P=NULL, Vec3s *Q=NULL)
Approximate distance between two kIOS bounding volumes.
Vec3s n
Plane normal.
Definition: geometric_shapes.h:956
CoalScalar radius
Radius of the sphere.
Definition: geometric_shapes.h:250
Vec3s n
Plane normal.
Definition: geometric_shapes.h:1034
CoalScalar distance(const Vec3s &p) const
Definition: geometric_shapes.h:924
CoalScalar halfLength
Half Length along z axis.
Definition: geometric_shapes.h:587
Vec3s halfSide
box side half-length
Definition: geometric_shapes.h:189
CoalScalar distance(const Vec3s &p) const
Definition: geometric_shapes.h:1023
Vec3s a
Definition: geometric_shapes.h:149
Vec3s b
Definition: geometric_shapes.h:149
CoalScalar getSweptSphereRadius() const
Get radius of sphere swept around the shape. This radius is always >= 0.
Definition: geometric_shapes.h:86
Vec3s c
Definition: geometric_shapes.h:149
CoalScalar signedDistance(const Vec3s &p) const
Definition: geometric_shapes.h:920
CoalScalar radius
Radius of capsule.
Definition: geometric_shapes.h:396
CoalScalar d
Plane offset.
Definition: geometric_shapes.h:1037
CoalScalar halfLength
Half Length along z axis.
Definition: geometric_shapes.h:402
CoalScalar radius
Radius of the cylinder.
Definition: geometric_shapes.h:581
CoalScalar d
Plane offset.
Definition: geometric_shapes.h:959
CoalScalar computePenetration(const Vec3s &P1, const Vec3s &P2, const Vec3s &P3, const Vec3s &Q1, const Vec3s &Q2, const Vec3s &Q3, Vec3s &normal)
See the prototype below.
Definition: details.h:703
CoalScalar sphereCapsuleDistance(const Sphere &s1, const Transform3s &tf1, const Capsule &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:75
CoalScalar halfspaceHalfspaceDistance(const Halfspace &s1, const Transform3s &tf1, const Halfspace &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
return distance between two halfspaces
Definition: details.h:512
CoalScalar segmentSqrDistance(const Vec3s &from, const Vec3s &to, const Vec3s &p, Vec3s &nearest)
the minimum distance from a point to a line
Definition: details.h:237
CoalScalar planePlaneDistance(const Plane &s1, const Transform3s &tf1, const Plane &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
return distance between two planes
Definition: details.h:650
CoalScalar boxSphereDistance(const Box &b, const Transform3s &tfb, const Sphere &s, const Transform3s &tfs, Vec3s &pb, Vec3s &ps, Vec3s &normal)
Definition: details.h:438
CoalScalar sphereTriangleDistance(const Sphere &s, const Transform3s &tf1, const TriangleP &tri, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:288
CoalScalar halfspacePlaneDistance(const Halfspace &s1, const Transform3s &tf1, const Plane &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
return distance between plane and halfspace.
Definition: details.h:588
CoalScalar sphereSphereDistance(const Sphere &s1, const Transform3s &tf1, const Sphere &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:217
CoalScalar planeDistance(const Plane &plane, const Transform3s &tf1, const ShapeBase &s, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:384
CoalScalar halfspaceDistance(const Halfspace &h, const Transform3s &tf1, const ShapeBase &s, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:350
CoalScalar sphereCylinderDistance(const Sphere &s1, const Transform3s &tf1, const Cylinder &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:108
bool projectInTriangle(const Vec3s &p1, const Vec3s &p2, const Vec3s &p3, const Vec3s &normal, const Vec3s &p)
Whether a point's projection is in a triangle.
Definition: details.h:260
Main namespace.
Definition: broadphase_bruteforce.h:44
Eigen::Matrix< CoalScalar, 3, 3 > Matrix3s
Definition: data_types.h:81
std::array< Halfspace, 2 > transformToHalfspaces(const Plane &a, const Transform3s &tf)
Halfspace transform(const Halfspace &a, const Transform3s &tf)
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: data_types.h:77
double CoalScalar
Definition: data_types.h:76