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;
84 lineSegmentPointClosestToPoint(s_c, pos1, pos2, segment_point);
85 normal = segment_point - s_c;
86 Scalar norm(normal.norm());
89 Scalar dist = norm - r1 - r2;
91 static const Scalar eps(std::numeric_limits<Scalar>::epsilon());
97 p1 = s_c + normal * r1;
98 p2 = segment_point - normal * r2;
109 static const Scalar eps(sqrt(std::numeric_limits<Scalar>::epsilon()));
122 assert((B - A - (s2.
halfLength * 2) * u).norm() < eps);
150 normal = (1 / dSp2) * Sp2;
151 p1 = S + r1 * normal;
153 assert(fabs(dist) - (p1 - p2).norm() < eps);
156 normal = p2 - .5 * (A + B);
157 assert(u.dot(normal) >= 0);
160 p1 = S + r1 * normal;
166 dist = dPS - r1 - r2;
183 normal = (1 / dSp2) * Sp2;
184 p1 = S + r1 * normal;
186 assert(fabs(dist) - (p1 - p2).norm() < eps);
189 normal = p2 - .5 * (A + B);
191 p1 = S + r1 * normal;
200 if (ssr1 > 0 || ssr2 > 0) {
203 dist -= (ssr1 + ssr2);
221 Vec3s c1c2 = center2 - center1;
222 Scalar cdist = c1c2.norm();
224 if (cdist > Eigen::NumTraits<Scalar>::epsilon()) unit = c1c2 / cdist;
225 Scalar dist = cdist - r1 - r2;
227 p1.noalias() = center1 + r1 * unit;
228 p2.noalias() = center2 - r2 * unit;
235 Vec3s diff = p - from;
240 Scalar dotVV = v.squaredNorm();
251 nearest.noalias() = from + v * t;
252 return diff.squaredNorm();
258 Vec3s edge1(p2 - p1);
259 Vec3s edge2(p3 - p2);
260 Vec3s edge3(p1 - p3);
262 Vec3s p1_to_p(p - p1);
263 Vec3s p2_to_p(p - p2);
264 Vec3s p3_to_p(p - p3);
266 Vec3s edge1_normal(edge1.cross(normal));
267 Vec3s edge2_normal(edge2.cross(normal));
268 Vec3s edge3_normal(edge3.cross(normal));
271 r1 = edge1_normal.dot(p1_to_p);
272 r2 = edge2_normal.dot(p2_to_p);
273 r3 = edge3_normal.dot(p3_to_p);
274 if ((r1 > 0 && r2 > 0 && r3 > 0) || (r1 <= 0 && r2 <= 0 && r3 <= 0)) {
292 Vec3s tri_normal = (P2 - P1).cross(P3 - P1);
293 tri_normal.normalize();
303 Vec3s p1_to_center = center - P1;
304 Scalar distance_from_plane = p1_to_center.dot(tri_normal);
306 Vec3s::Constant(std::numeric_limits<Scalar>::quiet_NaN()));
307 Scalar min_distance_sqr, distance_sqr;
309 if (distance_from_plane < 0) {
310 distance_from_plane *= -1;
315 closest_point = center - tri_normal * distance_from_plane;
316 min_distance_sqr = distance_from_plane * distance_from_plane;
319 Vec3s nearest_on_edge;
323 if (distance_sqr < min_distance_sqr) {
324 min_distance_sqr = distance_sqr;
325 closest_point = nearest_on_edge;
328 if (distance_sqr < min_distance_sqr) {
329 min_distance_sqr = distance_sqr;
330 closest_point = nearest_on_edge;
334 normal = (closest_point - center).normalized();
361 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_2, hint);
365 p1.noalias() = p2 - dist * new_h.
n;
366 normal.noalias() = new_h.
n;
368 const Scalar dummy_precision =
369 std::sqrt(Eigen::NumTraits<Scalar>::dummy_precision());
371 assert(new_h.
distance(p1) <= dummy_precision);
396 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_h1, hint);
401 getSupport<details::SupportOptions::WithSweptSphere>(&s, -n_h2, hint);
404 Scalar dist1 = new_h[0].signedDistance(p2h1);
405 Scalar dist2 = new_h[1].signedDistance(p2h2);
407 const Scalar dummy_precision =
408 std::sqrt(Eigen::NumTraits<Scalar>::dummy_precision());
412 if (dist1 >= dist2) {
415 p1.noalias() = p2 - dist * new_h[0].n;
416 normal.noalias() = new_h[0].n;
417 assert(new_h[0].
distance(p1) <= dummy_precision);
421 p1.noalias() = p2 - dist * new_h[1].n;
422 normal.noalias() = new_h[1].n;
423 assert(new_h[1].
distance(p1) <= dummy_precision);
442 bool outside =
false;
443 const Vec3s os_in_b_frame(Rb.transpose() * (os - ob));
445 Scalar min_d = (std::numeric_limits<Scalar>::max)();
446 for (
int i = 0; i < 3; ++i) {
448 if (os_in_b_frame(i) < -b.
halfSide(i)) {
449 pb.noalias() -= b.
halfSide(i) * Rb.col(i);
451 }
else if (os_in_b_frame(i) > b.
halfSide(i)) {
452 pb.noalias() += b.
halfSide(i) * Rb.col(i);
455 pb.noalias() += os_in_b_frame(i) * Rb.col(i);
457 (facedist = b.
halfSide(i) - std::fabs(os_in_b_frame(i))) < min_d) {
464 Scalar pdist = normal.norm();
470 if (os_in_b_frame(axis) >= 0) {
471 normal = Rb.col(axis);
473 normal = -Rb.col(axis);
477 ps = os - s.
radius * normal;
478 if (!outside || dist <= 0) {
480 pb = ps - dist * normal;
486 if (ssrb > 0 || ssrs > 0) {
489 dist -= (ssrb + ssrs);
516 Vec3s dir = (new_s1.
n).cross(new_s2.
n);
517 Scalar dir_sq_norm = dir.squaredNorm();
519 if (dir_sq_norm < std::numeric_limits<Scalar>::epsilon())
521 if (new_s1.
n.dot(new_s2.
n) > 0) {
524 distance = -(std::numeric_limits<Scalar>::max)();
525 if (new_s1.
d <= new_s2.
d) {
528 p2 = new_s2.
n * new_s2.
d;
530 Eigen::NumTraits<Scalar>::dummy_precision());
533 p1 << new_s1.
n * new_s1.
d;
536 Eigen::NumTraits<Scalar>::dummy_precision());
541 p1 = new_s1.
n * new_s1.
d;
542 p2 = new_s2.
n * new_s2.
d;
548 distance = -(std::numeric_limits<Scalar>::max)();
554 ((new_s2.
n * new_s1.
d - new_s1.
n * new_s2.
d).cross(dir)) / dir_sq_norm;
562 if (ssr1 > 0 || ssr2 > 0) {
591 Vec3s dir = (new_s1.
n).cross(new_s2.
n);
592 Scalar dir_sq_norm = dir.squaredNorm();
594 if (dir_sq_norm < std::numeric_limits<Scalar>::epsilon())
597 distance = new_s1.
n.dot(new_s2.
n) > 0 ? (new_s2.
d - new_s1.
d)
598 : -(new_s1.
d + new_s2.
d);
599 p1 = new_s1.
n * new_s1.
d;
600 p2 = new_s2.
n * new_s2.
d;
601 assert(new_s1.
distance(p1) <= Eigen::NumTraits<Scalar>::dummy_precision());
602 assert(new_s2.
distance(p2) <= Eigen::NumTraits<Scalar>::dummy_precision());
607 distance = -(std::numeric_limits<Scalar>::max)();
613 ((new_s2.
n * new_s1.
d - new_s1.
n * new_s2.
d).cross(dir)) / dir_sq_norm;
621 if (ssr1 > 0 || ssr2 > 0) {
649 Vec3s dir = (new_s1.
n).cross(new_s2.
n);
650 Scalar dir_sq_norm = dir.squaredNorm();
652 if (dir_sq_norm < std::numeric_limits<Scalar>::epsilon())
654 p1 = new_s1.
n * new_s1.
d;
655 p2 = new_s2.
n * new_s2.
d;
656 assert(new_s1.
distance(p1) <= Eigen::NumTraits<Scalar>::dummy_precision());
657 assert(new_s2.
distance(p2) <= Eigen::NumTraits<Scalar>::dummy_precision());
660 if (
distance > Eigen::NumTraits<Scalar>::dummy_precision()) {
661 normal = (p2 - p1).normalized();
669 distance = -(std::numeric_limits<Scalar>::max)();
675 ((new_s2.
n * new_s1.
d - new_s1.
n * new_s2.
d).cross(dir)) / dir_sq_norm;
683 if (ssr1 > 0 || ssr2 > 0) {
697 Vec3s u((P2 - P1).cross(P3 - P1));
698 normal = u.normalized();
699 Scalar depth1((P1 - Q1).dot(normal));
700 Scalar depth2((P1 - Q2).dot(normal));
701 Scalar depth3((P1 - Q3).dot(normal));
702 return std::max(depth1, std::max(depth2, depth3));
Center at zero point, axis aligned box.
Definition: geometric_shapes.h:164
Capsule It is where is the distance between the point x and the capsule segment AB,...
Definition: geometric_shapes.h:381
Cylinder along Z axis. The cylinder is defined at its centroid.
Definition: geometric_shapes.h:556
Half Space: this is equivalent to the Plane in ODE. A Half space has a priviledged direction: the dir...
Definition: geometric_shapes.h:886
Infinite plane. A plane can be viewed as two half spaces; it has no priviledged direction....
Definition: geometric_shapes.h:977
Base class for all basic geometric shapes.
Definition: geometric_shapes.h:58
Center at zero point sphere.
Definition: geometric_shapes.h:238
Triangle stores the points instead of only indices of points.
Definition: geometric_shapes.h:108
#define COAL_UNUSED_VARIABLE(var)
Definition: fwd.hh:56
Scalar 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.
Scalar halfLength
Half Length along z axis.
Definition: geometric_shapes.h:400
Scalar distance(const Vec3s &p) const
Definition: geometric_shapes.h:1016
Vec3s n
Plane normal.
Definition: geometric_shapes.h:950
Scalar radius
Radius of the cylinder.
Definition: geometric_shapes.h:577
Scalar d
Plane offset.
Definition: geometric_shapes.h:953
Vec3s n
Plane normal.
Definition: geometric_shapes.h:1027
Scalar distance(const Vec3s &p) const
Definition: geometric_shapes.h:918
Vec3s halfSide
box side half-length
Definition: geometric_shapes.h:187
Vec3s a
Definition: geometric_shapes.h:147
Scalar signedDistance(const Vec3s &p) const
Definition: geometric_shapes.h:914
Vec3s b
Definition: geometric_shapes.h:147
Scalar radius
Radius of the sphere.
Definition: geometric_shapes.h:248
Scalar halfLength
Half Length along z axis.
Definition: geometric_shapes.h:583
Scalar 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:147
Scalar radius
Radius of capsule.
Definition: geometric_shapes.h:394
Scalar d
Plane offset.
Definition: geometric_shapes.h:1030
Scalar segmentSqrDistance(const Vec3s &from, const Vec3s &to, const Vec3s &p, Vec3s &nearest)
the minimum distance from a point to a line
Definition: details.h:233
Scalar 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:642
Scalar 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:583
Scalar 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:507
Scalar planeDistance(const Plane &plane, const Transform3s &tf1, const ShapeBase &s, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:379
Scalar halfspaceDistance(const Halfspace &h, const Transform3s &tf1, const ShapeBase &s, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:345
Scalar sphereCylinderDistance(const Sphere &s1, const Transform3s &tf1, const Cylinder &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:106
Scalar sphereCapsuleDistance(const Sphere &s1, const Transform3s &tf1, const Capsule &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:75
Scalar sphereSphereDistance(const Sphere &s1, const Transform3s &tf1, const Sphere &s2, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:213
Scalar 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:693
Scalar sphereTriangleDistance(const Sphere &s, const Transform3s &tf1, const TriangleP &tri, const Transform3s &tf2, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: details.h:284
Scalar boxSphereDistance(const Box &b, const Transform3s &tfb, const Sphere &s, const Transform3s &tfs, Vec3s &pb, Vec3s &ps, Vec3s &normal)
Definition: details.h:433
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:256
Main namespace.
Definition: broadphase_bruteforce.h:44
std::array< Halfspace, 2 > transformToHalfspaces(const Plane &a, const Transform3s &tf)
Halfspace transform(const Halfspace &a, const Transform3s &tf)
Eigen::Matrix< Scalar, 3, 1 > Vec3s
Definition: data_types.h:70
double Scalar
Definition: data_types.h:68
Eigen::Matrix< Scalar, 3, 3 > Matrix3s
Definition: data_types.h:74