coal 3.0.2
Coal, The Collision Detection Library. Previously known as HPP-FCL, fork of FCL -- The Flexible Collision Library
Loading...
Searching...
No Matches
shape_shape_func.h
Go to the documentation of this file.
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2014, CNRS-LAAS
5 * Copyright (c) 2024, INRIA
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 * * Neither the name of Willow Garage, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
37
38#ifndef COAL_INTERNAL_SHAPE_SHAPE_FUNC_H
39#define COAL_INTERNAL_SHAPE_SHAPE_FUNC_H
40
42
47
48namespace coal {
49
50template <typename ShapeType1, typename ShapeType2>
51struct ShapeShapeDistancer {
52 static CoalScalar run(const CollisionGeometry* o1, const Transform3s& tf1,
53 const CollisionGeometry* o2, const Transform3s& tf2,
54 const GJKSolver* nsolver,
55 const DistanceRequest& request,
56 DistanceResult& result) {
57 if (request.isSatisfied(result)) return result.min_distance;
58
59 // Witness points on shape1 and shape2, normal pointing from shape1 to
60 // shape2.
61 Vec3s p1, p2, normal;
62 const CoalScalar distance =
63 ShapeShapeDistancer<ShapeType1, ShapeType2>::run(
64 o1, tf1, o2, tf2, nsolver, request.enable_signed_distance, p1, p2,
65 normal);
66
67 result.update(distance, o1, o2, DistanceResult::NONE, DistanceResult::NONE,
68 p1, p2, normal);
69
70 return distance;
71 }
72
73 static CoalScalar run(const CollisionGeometry* o1, const Transform3s& tf1,
74 const CollisionGeometry* o2, const Transform3s& tf2,
75 const GJKSolver* nsolver,
76 const bool compute_signed_distance, Vec3s& p1,
77 Vec3s& p2, Vec3s& normal) {
78 const ShapeType1* obj1 = static_cast<const ShapeType1*>(o1);
79 const ShapeType2* obj2 = static_cast<const ShapeType2*>(o2);
80 return nsolver->shapeDistance(*obj1, tf1, *obj2, tf2,
81 compute_signed_distance, p1, p2, normal);
82 }
83};
84
92template <typename ShapeType1, typename ShapeType2>
93CoalScalar ShapeShapeDistance(const CollisionGeometry* o1,
94 const Transform3s& tf1,
95 const CollisionGeometry* o2,
96 const Transform3s& tf2, const GJKSolver* nsolver,
97 const DistanceRequest& request,
98 DistanceResult& result) {
99 return ShapeShapeDistancer<ShapeType1, ShapeType2>::run(
100 o1, tf1, o2, tf2, nsolver, request, result);
101}
102
103namespace internal {
114template <typename ShapeType1, typename ShapeType2>
115CoalScalar ShapeShapeDistance(const CollisionGeometry* o1,
116 const Transform3s& tf1,
117 const CollisionGeometry* o2,
118 const Transform3s& tf2, const GJKSolver* nsolver,
119 const bool compute_signed_distance, Vec3s& p1,
120 Vec3s& p2, Vec3s& normal) {
121 return ::coal::ShapeShapeDistancer<ShapeType1, ShapeType2>::run(
122 o1, tf1, o2, tf2, nsolver, compute_signed_distance, p1, p2, normal);
123}
124} // namespace internal
125
135template <typename ShapeType1, typename ShapeType2>
136struct ShapeShapeCollider {
137 static std::size_t run(const CollisionGeometry* o1, const Transform3s& tf1,
138 const CollisionGeometry* o2, const Transform3s& tf2,
139 const GJKSolver* nsolver,
140 const CollisionRequest& request,
141 CollisionResult& result) {
142 if (request.isSatisfied(result)) return result.numContacts();
143
144 const bool compute_penetration =
145 request.enable_contact || (request.security_margin < 0);
146 Vec3s p1, p2, normal;
147 CoalScalar distance = internal::ShapeShapeDistance<ShapeType1, ShapeType2>(
148 o1, tf1, o2, tf2, nsolver, compute_penetration, p1, p2, normal);
149
150 size_t num_contacts = 0;
151 const CoalScalar distToCollision = distance - request.security_margin;
152
153 internal::updateDistanceLowerBoundFromLeaf(request, result, distToCollision,
154 p1, p2, normal);
155 if (distToCollision <= request.collision_distance_threshold &&
156 result.numContacts() < request.num_max_contacts) {
157 if (result.numContacts() < request.num_max_contacts) {
158 Contact contact(o1, o2, Contact::NONE, Contact::NONE, p1, p2, normal,
159 distance);
160 result.addContact(contact);
161 }
162 num_contacts = result.numContacts();
163 }
164
165 return num_contacts;
166 }
167};
168
169template <typename ShapeType1, typename ShapeType2>
170std::size_t ShapeShapeCollide(const CollisionGeometry* o1,
171 const Transform3s& tf1,
172 const CollisionGeometry* o2,
173 const Transform3s& tf2, const GJKSolver* nsolver,
174 const CollisionRequest& request,
175 CollisionResult& result) {
176 return ShapeShapeCollider<ShapeType1, ShapeType2>::run(
177 o1, tf1, o2, tf2, nsolver, request, result);
178}
179
180// clang-format off
181// ==============================================================================================================
182// ==============================================================================================================
183// ==============================================================================================================
184// Shape distance algorithms based on:
185// - built-in function: 0
186// - GJK: 1
187//
188// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
189// | | box | sphere | capsule | cone | cylinder | plane | half-space | triangle | ellipsoid | convex |
190// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
191// | box | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
192// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
193// | sphere |/////| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
194// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
195// | capsule |/////|////////| 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
196// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
197// | cone |/////|////////|/////////| 1 | 1 | 0 | 0 | 1 | 1 | 1 |
198// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
199// | cylinder |/////|////////|/////////|//////| 1 | 0 | 0 | 1 | 1 | 1 |
200// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
201// | plane |/////|////////|/////////|//////|//////////| ? | ? | 0 | 0 | 0 |
202// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
203// | half-space |/////|////////|/////////|//////|//////////|///////| ? | 0 | 0 | 0 |
204// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
205// | triangle |/////|////////|/////////|//////|//////////|///////|////////////| 0 | 1 | 1 |
206// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
207// | ellipsoid |/////|////////|/////////|//////|//////////|///////|////////////|//////////| 1 | 1 |
208// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
209// | convex |/////|////////|/////////|//////|//////////|///////|////////////|//////////|///////////| 1 |
210// +------------+-----+--------+---------+------+----------+-------+------------+----------+-----------+--------+
211//
212// Number of pairs: 55
213// - Specialized: 26
214// - GJK: 29
215// clang-format on
216
217#define SHAPE_SHAPE_DISTANCE_SPECIALIZATION(T1, T2) \
218 template <> \
219 COAL_DLLAPI CoalScalar internal::ShapeShapeDistance<T1, T2>( \
220 const CollisionGeometry* o1, const Transform3s& tf1, \
221 const CollisionGeometry* o2, const Transform3s& tf2, \
222 const GJKSolver* nsolver, const bool compute_signed_distance, Vec3s& p1, \
223 Vec3s& p2, Vec3s& normal); \
224 template <> \
225 COAL_DLLAPI CoalScalar internal::ShapeShapeDistance<T2, T1>( \
226 const CollisionGeometry* o1, const Transform3s& tf1, \
227 const CollisionGeometry* o2, const Transform3s& tf2, \
228 const GJKSolver* nsolver, const bool compute_signed_distance, Vec3s& p1, \
229 Vec3s& p2, Vec3s& normal); \
230 template <> \
231 inline COAL_DLLAPI CoalScalar ShapeShapeDistance<T1, T2>( \
232 const CollisionGeometry* o1, const Transform3s& tf1, \
233 const CollisionGeometry* o2, const Transform3s& tf2, \
234 const GJKSolver* nsolver, const DistanceRequest& request, \
235 DistanceResult& result) { \
236 result.o1 = o1; \
237 result.o2 = o2; \
238 result.b1 = DistanceResult::NONE; \
239 result.b2 = DistanceResult::NONE; \
240 result.min_distance = internal::ShapeShapeDistance<T1, T2>( \
241 o1, tf1, o2, tf2, nsolver, request.enable_signed_distance, \
242 result.nearest_points[0], result.nearest_points[1], result.normal); \
243 return result.min_distance; \
244 } \
245 template <> \
246 inline COAL_DLLAPI CoalScalar ShapeShapeDistance<T2, T1>( \
247 const CollisionGeometry* o1, const Transform3s& tf1, \
248 const CollisionGeometry* o2, const Transform3s& tf2, \
249 const GJKSolver* nsolver, const DistanceRequest& request, \
250 DistanceResult& result) { \
251 result.o1 = o1; \
252 result.o2 = o2; \
253 result.b1 = DistanceResult::NONE; \
254 result.b2 = DistanceResult::NONE; \
255 result.min_distance = internal::ShapeShapeDistance<T2, T1>( \
256 o1, tf1, o2, tf2, nsolver, request.enable_signed_distance, \
257 result.nearest_points[0], result.nearest_points[1], result.normal); \
258 return result.min_distance; \
259 }
260
261#define SHAPE_SELF_DISTANCE_SPECIALIZATION(T) \
262 template <> \
263 COAL_DLLAPI CoalScalar internal::ShapeShapeDistance<T, T>( \
264 const CollisionGeometry* o1, const Transform3s& tf1, \
265 const CollisionGeometry* o2, const Transform3s& tf2, \
266 const GJKSolver* nsolver, const bool compute_signed_distance, Vec3s& p1, \
267 Vec3s& p2, Vec3s& normal); \
268 template <> \
269 inline COAL_DLLAPI CoalScalar ShapeShapeDistance<T, T>( \
270 const CollisionGeometry* o1, const Transform3s& tf1, \
271 const CollisionGeometry* o2, const Transform3s& tf2, \
272 const GJKSolver* nsolver, const DistanceRequest& request, \
273 DistanceResult& result) { \
274 result.o1 = o1; \
275 result.o2 = o2; \
276 result.b1 = DistanceResult::NONE; \
277 result.b2 = DistanceResult::NONE; \
278 result.min_distance = internal::ShapeShapeDistance<T, T>( \
279 o1, tf1, o2, tf2, nsolver, request.enable_signed_distance, \
280 result.nearest_points[0], result.nearest_points[1], result.normal); \
281 return result.min_distance; \
282 }
283
284SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Box, Halfspace)
285SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Box, Plane)
286SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Box, Sphere)
287SHAPE_SELF_DISTANCE_SPECIALIZATION(Capsule)
288SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Capsule, Halfspace)
289SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Capsule, Plane)
290SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Cone, Halfspace)
291SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Cone, Plane)
292SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Cylinder, Halfspace)
293SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Cylinder, Plane)
294SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Sphere, Halfspace)
295SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Sphere, Plane)
296SHAPE_SELF_DISTANCE_SPECIALIZATION(Sphere)
297SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Sphere, Cylinder)
298SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Sphere, Capsule)
299SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Ellipsoid, Halfspace)
300SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Ellipsoid, Plane)
301SHAPE_SHAPE_DISTANCE_SPECIALIZATION(ConvexBase, Halfspace)
302SHAPE_SHAPE_DISTANCE_SPECIALIZATION(ConvexBase, Plane)
303SHAPE_SHAPE_DISTANCE_SPECIALIZATION(TriangleP, Halfspace)
304SHAPE_SHAPE_DISTANCE_SPECIALIZATION(TriangleP, Plane)
305SHAPE_SELF_DISTANCE_SPECIALIZATION(TriangleP)
306SHAPE_SHAPE_DISTANCE_SPECIALIZATION(TriangleP, Sphere)
307SHAPE_SHAPE_DISTANCE_SPECIALIZATION(Plane, Halfspace)
308SHAPE_SELF_DISTANCE_SPECIALIZATION(Plane)
309SHAPE_SELF_DISTANCE_SPECIALIZATION(Halfspace)
310
311#undef SHAPE_SHAPE_DISTANCE_SPECIALIZATION
312#undef SHAPE_SELF_DISTANCE_SPECIALIZATION
313
314} // namespace coal
315
317
318#endif
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
The geometry for the object for collision or distance computation.
Definition collision_object.h:94
Cone The base of the cone is at and the top is at .
Definition geometric_shapes.h:467
Base for convex polytope.
Definition geometric_shapes.h:645
Cylinder along Z axis. The cylinder is defined at its centroid.
Definition geometric_shapes.h:560
Ellipsoid centered at point zero.
Definition geometric_shapes.h:305
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
Center at zero point sphere.
Definition geometric_shapes.h:240
Simple transform class used locally by InterpMotion.
Definition transform.h:55
Triangle stores the points instead of only indices of points.
Definition geometric_shapes.h:110
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.
Definition collision_data.h:1174
Main namespace.
Definition broadphase_bruteforce.h:44
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition data_types.h:77
double CoalScalar
Definition data_types.h:76
request to the collision algorithm
Definition collision_data.h:311
collision result
Definition collision_data.h:390
request to the distance computation
Definition collision_data.h:985
distance result
Definition collision_data.h:1051
collision and distance solver based on the GJK and EPA algorithms. Originally, GJK and EPA were imple...
Definition narrowphase.h:57