support_functions.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2015, Open Source Robotics Foundation
6  * Copyright (c) 2021-2024, INRIA
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Open Source Robotics Foundation nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
40 
41 #include <algorithm>
42 
43 namespace coal {
44 namespace details {
45 
46 // ============================================================================
47 #define CALL_GET_SHAPE_SUPPORT(ShapeType) \
48  getShapeSupport<_SupportOptions>(static_cast<const ShapeType*>(shape), dir, \
49  support, hint, support_data)
50 template <int _SupportOptions>
51 Vec3s getSupport(const ShapeBase* shape, const Vec3s& dir, int& hint) {
52  Vec3s support;
53  ShapeSupportData support_data;
54  switch (shape->getNodeType()) {
55  case GEOM_TRIANGLE:
57  break;
58  case GEOM_BOX:
60  break;
61  case GEOM_SPHERE:
63  break;
64  case GEOM_ELLIPSOID:
66  break;
67  case GEOM_CAPSULE:
69  break;
70  case GEOM_CONE:
72  break;
73  case GEOM_CYLINDER:
75  break;
76  case GEOM_CONVEX:
78  break;
79  case GEOM_PLANE:
80  case GEOM_HALFSPACE:
81  default:
82  support.setZero();
83  ; // nothing
84  }
85 
86  return support;
87 }
88 #undef CALL_GET_SHAPE_SUPPORT
89 
90 // Explicit instantiation
91 // clang-format off
92 template COAL_DLLAPI Vec3s getSupport<SupportOptions::NoSweptSphere>(const ShapeBase*, const Vec3s&, int&);
93 
94 template COAL_DLLAPI Vec3s getSupport<SupportOptions::WithSweptSphere>(const ShapeBase*, const Vec3s&, int&);
95 // clang-format on
96 
97 // ============================================================================
98 #define getShapeSupportTplInstantiation(ShapeType) \
99  template COAL_DLLAPI void getShapeSupport<SupportOptions::NoSweptSphere>( \
100  const ShapeType* shape_, const Vec3s& dir, Vec3s& support, int& hint, \
101  ShapeSupportData& support_data); \
102  \
103  template COAL_DLLAPI void getShapeSupport<SupportOptions::WithSweptSphere>( \
104  const ShapeType* shape_, const Vec3s& dir, Vec3s& support, int& hint, \
105  ShapeSupportData& support_data);
106 
107 // ============================================================================
108 template <int _SupportOptions>
109 void getShapeSupport(const TriangleP* triangle, const Vec3s& dir,
110  Vec3s& support, int& /*unused*/,
111  ShapeSupportData& /*unused*/) {
112  CoalScalar dota = dir.dot(triangle->a);
113  CoalScalar dotb = dir.dot(triangle->b);
114  CoalScalar dotc = dir.dot(triangle->c);
115  if (dota > dotb) {
116  if (dotc > dota) {
117  support = triangle->c;
118  } else {
119  support = triangle->a;
120  }
121  } else {
122  if (dotc > dotb) {
123  support = triangle->c;
124  } else {
125  support = triangle->b;
126  }
127  }
128 
129  if (_SupportOptions == SupportOptions::WithSweptSphere) {
130  support += triangle->getSweptSphereRadius() * dir.normalized();
131  }
132 }
134 
135 // ============================================================================
136 template <int _SupportOptions>
137 inline void getShapeSupport(const Box* box, const Vec3s& dir, Vec3s& support,
138  int& /*unused*/, ShapeSupportData& /*unused*/) {
139  // The inflate value is simply to make the specialized functions with box
140  // have a preferred side for edge cases.
141  static const CoalScalar inflate = (dir.array() == 0).any() ? 1 + 1e-10 : 1.;
142  static const CoalScalar dummy_precision =
143  Eigen::NumTraits<CoalScalar>::dummy_precision();
144  Vec3s support1 = (dir.array() > dummy_precision).select(box->halfSide, 0);
145  Vec3s support2 =
146  (dir.array() < -dummy_precision).select(-inflate * box->halfSide, 0);
147  support.noalias() = support1 + support2;
148 
149  if (_SupportOptions == SupportOptions::WithSweptSphere) {
150  support += box->getSweptSphereRadius() * dir.normalized();
151  }
152 }
154 
155 // ============================================================================
156 template <int _SupportOptions>
157 inline void getShapeSupport(const Sphere* sphere, const Vec3s& dir,
158  Vec3s& support, int& /*unused*/,
159  ShapeSupportData& /*unused*/) {
160  if (_SupportOptions == SupportOptions::WithSweptSphere) {
161  support.noalias() =
162  (sphere->radius + sphere->getSweptSphereRadius()) * dir.normalized();
163  } else {
164  support.setZero();
165  }
166 
169 }
171 
172 // ============================================================================
173 template <int _SupportOptions>
174 inline void getShapeSupport(const Ellipsoid* ellipsoid, const Vec3s& dir,
175  Vec3s& support, int& /*unused*/,
176  ShapeSupportData& /*unused*/) {
177  CoalScalar a2 = ellipsoid->radii[0] * ellipsoid->radii[0];
178  CoalScalar b2 = ellipsoid->radii[1] * ellipsoid->radii[1];
179  CoalScalar c2 = ellipsoid->radii[2] * ellipsoid->radii[2];
180 
181  Vec3s v(a2 * dir[0], b2 * dir[1], c2 * dir[2]);
182 
183  CoalScalar d = std::sqrt(v.dot(dir));
184 
185  support = v / d;
186 
187  if (_SupportOptions == SupportOptions::WithSweptSphere) {
188  support += ellipsoid->getSweptSphereRadius() * dir.normalized();
189  }
190 }
192 
193 // ============================================================================
194 template <int _SupportOptions>
195 inline void getShapeSupport(const Capsule* capsule, const Vec3s& dir,
196  Vec3s& support, int& /*unused*/,
197  ShapeSupportData& /*unused*/) {
198  static const CoalScalar dummy_precision =
199  Eigen::NumTraits<CoalScalar>::dummy_precision();
200  support.setZero();
201  if (dir[2] > dummy_precision) {
202  support[2] = capsule->halfLength;
203  } else if (dir[2] < -dummy_precision) {
204  support[2] = -capsule->halfLength;
205  }
206 
207  if (_SupportOptions == SupportOptions::WithSweptSphere) {
208  support +=
209  (capsule->radius + capsule->getSweptSphereRadius()) * dir.normalized();
210  }
211 }
213 
214 // ============================================================================
215 template <int _SupportOptions>
216 void getShapeSupport(const Cone* cone, const Vec3s& dir, Vec3s& support,
217  int& /*unused*/, ShapeSupportData& /*unused*/) {
218  static const CoalScalar dummy_precision =
219  Eigen::NumTraits<CoalScalar>::dummy_precision();
220 
221  // The cone radius is, for -h < z < h, (h - z) * r / (2*h)
222  // The inflate value is simply to make the specialized functions with cone
223  // have a preferred side for edge cases.
224  static const CoalScalar inflate = 1 + 1e-10;
225  CoalScalar h = cone->halfLength;
226  CoalScalar r = cone->radius;
227 
228  if (dir.head<2>().isZero(dummy_precision)) {
229  support.head<2>().setZero();
230  if (dir[2] > dummy_precision) {
231  support[2] = h;
232  } else {
233  support[2] = -inflate * h;
234  }
235  } else {
236  CoalScalar zdist = dir[0] * dir[0] + dir[1] * dir[1];
237  CoalScalar len = zdist + dir[2] * dir[2];
238  zdist = std::sqrt(zdist);
239 
240  if (dir[2] <= 0) {
241  CoalScalar rad = r / zdist;
242  support.head<2>() = rad * dir.head<2>();
243  support[2] = -h;
244  } else {
245  len = std::sqrt(len);
246  CoalScalar sin_a = r / std::sqrt(r * r + 4 * h * h);
247 
248  if (dir[2] > len * sin_a)
249  support << 0, 0, h;
250  else {
251  CoalScalar rad = r / zdist;
252  support.head<2>() = rad * dir.head<2>();
253  support[2] = -h;
254  }
255  }
256  }
257 
258  if (_SupportOptions == SupportOptions::WithSweptSphere) {
259  support += cone->getSweptSphereRadius() * dir.normalized();
260  }
261 }
263 
264 // ============================================================================
265 template <int _SupportOptions>
266 void getShapeSupport(const Cylinder* cylinder, const Vec3s& dir, Vec3s& support,
267  int& /*unused*/, ShapeSupportData& /*unused*/) {
268  static const CoalScalar dummy_precision =
269  Eigen::NumTraits<CoalScalar>::dummy_precision();
270 
271  // The inflate value is simply to make the specialized functions with cylinder
272  // have a preferred side for edge cases.
273  static const CoalScalar inflate = 1 + 1e-10;
274  CoalScalar half_h = cylinder->halfLength;
275  CoalScalar r = cylinder->radius;
276 
277  const bool dir_is_aligned_with_z = dir.head<2>().isZero(dummy_precision);
278  if (dir_is_aligned_with_z) half_h *= inflate;
279 
280  if (dir[2] > dummy_precision) {
281  support[2] = half_h;
282  } else if (dir[2] < -dummy_precision) {
283  support[2] = -half_h;
284  } else {
285  support[2] = 0;
286  r *= inflate;
287  }
288 
289  if (dir_is_aligned_with_z) {
290  support.head<2>().setZero();
291  } else {
292  support.head<2>() = dir.head<2>().normalized() * r;
293  }
294 
295  assert(fabs(support[0] * dir[1] - support[1] * dir[0]) <
297 
298  if (_SupportOptions == SupportOptions::WithSweptSphere) {
299  support += cylinder->getSweptSphereRadius() * dir.normalized();
300  }
301 }
303 
304 // ============================================================================
305 template <int _SupportOptions>
306 void getShapeSupportLog(const ConvexBase* convex, const Vec3s& dir,
307  Vec3s& support, int& hint,
308  ShapeSupportData& support_data) {
309  assert(convex->neighbors != nullptr && "Convex has no neighbors.");
310 
311  // Use warm start if current support direction is distant from last support
312  // direction.
313  const double use_warm_start_threshold = 0.9;
314  Vec3s dir_normalized = dir.normalized();
315  if (!support_data.last_dir.isZero() &&
316  !convex->support_warm_starts.points.empty() &&
317  support_data.last_dir.dot(dir_normalized) < use_warm_start_threshold) {
318  // Change hint if last dir is too far from current dir.
319  CoalScalar maxdot = convex->support_warm_starts.points[0].dot(dir);
320  hint = convex->support_warm_starts.indices[0];
321  for (size_t i = 1; i < convex->support_warm_starts.points.size(); ++i) {
322  CoalScalar dot = convex->support_warm_starts.points[i].dot(dir);
323  if (dot > maxdot) {
324  maxdot = dot;
325  hint = convex->support_warm_starts.indices[i];
326  }
327  }
328  }
329  support_data.last_dir = dir_normalized;
330 
331  const std::vector<Vec3s>& pts = *(convex->points);
332  const std::vector<ConvexBase::Neighbors>& nn = *(convex->neighbors);
333 
334  if (hint < 0 || hint >= (int)convex->num_points) {
335  hint = 0;
336  }
337  CoalScalar maxdot = pts[static_cast<size_t>(hint)].dot(dir);
338  std::vector<int8_t>& visited = support_data.visited;
339  if (support_data.visited.size() == convex->num_points) {
340  std::fill(visited.begin(), visited.end(), false);
341  } else {
342  // std::vector::assign not only assigns the values of the vector but also
343  // resizes the vector. So if `visited` has not been set up yet, this makes
344  // sure the size convex's points and visited are identical.
345  support_data.visited.assign(convex->num_points, false);
346  }
347  visited[static_cast<std::size_t>(hint)] = true;
348  // When the first face is orthogonal to dir, all the dot products will be
349  // equal. Yet, the neighbors must be visited.
350  bool found = true;
351  bool loose_check = true;
352  while (found) {
353  const ConvexBase::Neighbors& n = nn[static_cast<size_t>(hint)];
354  found = false;
355  for (int in = 0; in < n.count(); ++in) {
356  const unsigned int ip = n[in];
357  if (visited[ip]) continue;
358  visited[ip] = true;
359  const CoalScalar dot = pts[ip].dot(dir);
360  bool better = false;
361  if (dot > maxdot) {
362  better = true;
363  loose_check = false;
364  } else if (loose_check && dot == maxdot)
365  better = true;
366  if (better) {
367  maxdot = dot;
368  hint = static_cast<int>(ip);
369  found = true;
370  }
371  }
372  }
373 
374  support = pts[static_cast<size_t>(hint)];
375 
376  if (_SupportOptions == SupportOptions::WithSweptSphere) {
377  support += convex->getSweptSphereRadius() * dir.normalized();
378  }
379 }
380 
381 // ============================================================================
382 template <int _SupportOptions>
383 void getShapeSupportLinear(const ConvexBase* convex, const Vec3s& dir,
384  Vec3s& support, int& hint,
385  ShapeSupportData& /*unused*/) {
386  const std::vector<Vec3s>& pts = *(convex->points);
387 
388  hint = 0;
389  CoalScalar maxdot = pts[0].dot(dir);
390  for (int i = 1; i < (int)convex->num_points; ++i) {
391  CoalScalar dot = pts[static_cast<size_t>(i)].dot(dir);
392  if (dot > maxdot) {
393  maxdot = dot;
394  hint = i;
395  }
396  }
397 
398  support = pts[static_cast<size_t>(hint)];
399 
400  if (_SupportOptions == SupportOptions::WithSweptSphere) {
401  support += convex->getSweptSphereRadius() * dir.normalized();
402  }
403 }
404 
405 // ============================================================================
406 template <int _SupportOptions>
407 void getShapeSupport(const ConvexBase* convex, const Vec3s& dir, Vec3s& support,
408  int& hint, ShapeSupportData& support_data) {
409  // TODO add benchmark to set a proper value for switching between linear and
410  // logarithmic.
412  convex->neighbors != nullptr) {
413  getShapeSupportLog<_SupportOptions>(convex, dir, support, hint,
414  support_data);
415  } else {
416  getShapeSupportLinear<_SupportOptions>(convex, dir, support, hint,
417  support_data);
418  }
419 }
421 
422 // ============================================================================
423 template <int _SupportOptions>
424 inline void getShapeSupport(const SmallConvex* convex, const Vec3s& dir,
425  Vec3s& support, int& hint,
426  ShapeSupportData& support_data) {
427  getShapeSupportLinear<_SupportOptions>(
428  reinterpret_cast<const ConvexBase*>(convex), dir, support, hint,
429  support_data);
430 }
432 
433 // ============================================================================
434 template <int _SupportOptions>
435 inline void getShapeSupport(const LargeConvex* convex, const Vec3s& dir,
436  Vec3s& support, int& hint,
437  ShapeSupportData& support_data) {
438  getShapeSupportLog<_SupportOptions>(
439  reinterpret_cast<const ConvexBase*>(convex), dir, support, hint,
440  support_data);
441 }
443 
444 // ============================================================================
445 #define CALL_GET_SHAPE_SUPPORT_SET(ShapeType) \
446  getShapeSupportSet<_SupportOptions>(static_cast<const ShapeType*>(shape), \
447  support_set, hint, support_data, \
448  max_num_supports, tol)
449 template <int _SupportOptions>
450 void getSupportSet(const ShapeBase* shape, SupportSet& support_set, int& hint,
451  size_t max_num_supports, CoalScalar tol) {
452  ShapeSupportData support_data;
453  switch (shape->getNodeType()) {
454  case GEOM_TRIANGLE:
456  break;
457  case GEOM_BOX:
459  break;
460  case GEOM_SPHERE:
462  break;
463  case GEOM_ELLIPSOID:
465  break;
466  case GEOM_CAPSULE:
468  break;
469  case GEOM_CONE:
471  break;
472  case GEOM_CYLINDER:
474  break;
475  case GEOM_CONVEX:
477  break;
478  case GEOM_PLANE:
479  case GEOM_HALFSPACE:
480  default:; // nothing
481  }
482 }
483 #undef CALL_GET_SHAPE_SUPPORT
484 
485 // Explicit instantiation
486 // clang-format off
487 template COAL_DLLAPI void getSupportSet<SupportOptions::NoSweptSphere>(const ShapeBase*, SupportSet&, int&, size_t, CoalScalar);
488 
489 template COAL_DLLAPI void getSupportSet<SupportOptions::WithSweptSphere>(const ShapeBase*, SupportSet&, int&, size_t, CoalScalar);
490 // clang-format on
491 
492 // ============================================================================
493 #define getShapeSupportSetTplInstantiation(ShapeType) \
494  template COAL_DLLAPI void getShapeSupportSet<SupportOptions::NoSweptSphere>( \
495  const ShapeType* shape_, SupportSet& support_set, int& hint, \
496  ShapeSupportData& data, size_t num_sampled_supports, CoalScalar tol); \
497  \
498  template COAL_DLLAPI void \
499  getShapeSupportSet<SupportOptions::WithSweptSphere>( \
500  const ShapeType* shape_, SupportSet& support_set, int& hint, \
501  ShapeSupportData& data, size_t num_sampled_supports, CoalScalar tol);
502 
503 // ============================================================================
504 template <int _SupportOptions>
505 void getShapeSupportSet(const TriangleP* triangle, SupportSet& support_set,
506  int& hint /*unused*/,
507  ShapeSupportData& support_data /*unused*/,
508  size_t /*unused*/, CoalScalar tol) {
509  assert(tol > 0);
510  support_set.clear();
511 
512  Vec3s support;
513  const Vec3s& support_dir = support_set.getNormal();
514  // We simply want to compute the support value, no need to take the
515  // swept-sphere radius into account.
516  getShapeSupport<SupportOptions::NoSweptSphere>(triangle, support_dir, support,
517  hint, support_data);
518  const CoalScalar support_value = support.dot(support_dir);
519 
520  if (support_value - support_dir.dot(triangle->a) < tol) {
521  // Note: at the moment, it's useless to take into account the
522  // swept-sphere radius, but in the future we might want to store the
523  // offsets to the plane in `SupportSet`.
524  if (_SupportOptions == SupportOptions::WithSweptSphere) {
525  support_set.addPoint(triangle->a +
526  triangle->getSweptSphereRadius() * support_dir);
527  } else {
528  support_set.addPoint(triangle->a);
529  }
530  }
531  if (support_value - support_dir.dot(triangle->b) < tol) {
532  if (_SupportOptions == SupportOptions::WithSweptSphere) {
533  support_set.addPoint(triangle->b +
534  triangle->getSweptSphereRadius() * support_dir);
535  } else {
536  support_set.addPoint(triangle->b);
537  }
538  }
539  if (support_value - support_dir.dot(triangle->c) < tol) {
540  if (_SupportOptions == SupportOptions::WithSweptSphere) {
541  support_set.addPoint(triangle->c +
542  triangle->getSweptSphereRadius() * support_dir);
543  } else {
544  support_set.addPoint(triangle->c);
545  }
546  }
547 }
549 
550 // ============================================================================
551 template <int _SupportOptions>
552 void getShapeSupportSet(const Box* box, SupportSet& support_set,
553  int& hint /*unused*/, ShapeSupportData& support_data,
554  size_t /*unused*/, CoalScalar tol) {
555  assert(tol > 0);
556  Vec3s support;
557  const Vec3s& support_dir = support_set.getNormal();
558  getShapeSupport<SupportOptions::NoSweptSphere>(box, support_dir, support,
559  hint, support_data);
560  const CoalScalar support_value = support.dot(support_dir);
561 
562  const CoalScalar x = box->halfSide[0];
563  const CoalScalar y = box->halfSide[1];
564  const CoalScalar z = box->halfSide[2];
565  const std::array<Vec3s, 8> corners = {
566  Vec3s(x, y, z), Vec3s(-x, y, z), Vec3s(-x, -y, z), Vec3s(x, -y, z),
567  Vec3s(x, y, -z), Vec3s(-x, y, -z), Vec3s(-x, -y, -z), Vec3s(x, -y, -z),
568  };
569 
570  SupportSet::Polygon& polygon = support_data.polygon;
571  polygon.clear();
572  const Transform3s& tf = support_set.tf;
573  for (const Vec3s& corner : corners) {
574  const CoalScalar val = corner.dot(support_dir);
575  if (support_value - val < tol) {
576  if (_SupportOptions == SupportOptions::WithSweptSphere) {
577  const Vec2s p =
578  tf.inverseTransform(corner +
579  box->getSweptSphereRadius() * support_dir)
580  .template head<2>();
581  polygon.emplace_back(p);
582  } else {
583  const Vec2s p = tf.inverseTransform(corner).template head<2>();
584  polygon.emplace_back(p);
585  }
586  }
587  }
588  computeSupportSetConvexHull(polygon, support_set.points());
589 }
591 
592 // ============================================================================
593 template <int _SupportOptions>
594 void getShapeSupportSet(const Sphere* sphere, SupportSet& support_set,
595  int& hint /*unused*/,
596  ShapeSupportData& support_data /*unused*/,
597  size_t /*unused*/, CoalScalar /*unused*/) {
598  support_set.points().clear();
599 
600  Vec3s support;
601  const Vec3s& support_dir = support_set.getNormal();
602  getShapeSupport<_SupportOptions>(sphere, support_dir, support, hint,
603  support_data);
604  support_set.addPoint(support);
605 }
607 
608 // ============================================================================
609 template <int _SupportOptions>
610 void getShapeSupportSet(const Ellipsoid* ellipsoid, SupportSet& support_set,
611  int& hint, ShapeSupportData& support_data /*unused*/,
612  size_t /*unused*/, CoalScalar /*unused*/) {
613  support_set.points().clear();
614 
615  Vec3s support;
616  const Vec3s& support_dir = support_set.getNormal();
617  getShapeSupport<_SupportOptions>(ellipsoid, support_dir, support, hint,
618  support_data);
619  support_set.addPoint(support);
620 }
622 
623 // ============================================================================
624 template <int _SupportOptions>
625 void getShapeSupportSet(const Capsule* capsule, SupportSet& support_set,
626  int& hint /*unused*/,
627  ShapeSupportData& support_data /*unused*/,
628  size_t /*unused*/, CoalScalar tol) {
629  // clang-format on
630  assert(tol > 0);
631  support_set.points().clear();
632 
633  Vec3s support;
634  const Vec3s& support_dir = support_set.getNormal();
635  getShapeSupport<SupportOptions::NoSweptSphere>(capsule, support_dir, support,
636  hint, support_data);
637  const CoalScalar support_value =
638  support_dir.dot(support + capsule->radius * support_dir);
639  // The support set of a capsule has either 2 points or 1 point.
640  // The two candidate points lie at the frontier between the cylinder and
641  // sphere parts of the capsule.
642  const CoalScalar h = capsule->halfLength;
643  const CoalScalar r = capsule->radius;
644  const Vec3s p1(r * support_dir[0], r * support_dir[1], h);
645  const Vec3s p2(r * support_dir[0], r * support_dir[1], -h);
646  if ((support_value - support_dir.dot(p1) <= tol) &&
647  (support_value - support_dir.dot(p2) <= tol)) {
648  if (_SupportOptions == SupportOptions::WithSweptSphere) {
649  const Vec3s ssr_vec = support_dir * capsule->getSweptSphereRadius();
650  support_set.addPoint(p1 + ssr_vec);
651  support_set.addPoint(p2 + ssr_vec);
652  } else {
653  support_set.addPoint(p1);
654  support_set.addPoint(p2);
655  }
656  } else {
657  if (_SupportOptions == SupportOptions::WithSweptSphere) {
658  const Vec3s ssr_vec = support_dir * capsule->getSweptSphereRadius();
659  support_set.addPoint(support + ssr_vec);
660  } else {
661  support_set.addPoint(support);
662  }
663  }
664 }
666 
667 // ============================================================================
668 template <int _SupportOptions>
669 void getShapeSupportSet(const Cone* cone, SupportSet& support_set,
670  int& hint /*unused*/,
671  ShapeSupportData& support_data /*unused*/,
672  size_t num_sampled_supports, CoalScalar tol) {
673  assert(tol > 0);
674  support_set.points().clear();
675 
676  Vec3s support;
677  const Vec3s& support_dir = support_set.getNormal();
678  getShapeSupport<SupportOptions::NoSweptSphere>(cone, support_dir, support,
679  hint, support_data);
680  const CoalScalar support_value = support.dot(support_dir);
681 
682  // If the support direction is perpendicular to the cone's basis, there is an
683  // infinite amount of support points; otherwise there are up to two support
684  // points (two if direction is perpendicular to the side of the cone and one
685  // otherwise).
686  //
687  // To check this condition, we look at two points on the cone's basis;
688  // these two points are symmetrical w.r.t the center of the circle. If
689  // both these points are tol away from the support plane, then all the
690  // points of the circle are tol away from the support plane.
691  const CoalScalar r = cone->radius;
692  const CoalScalar z = -cone->halfLength;
693  const Vec3s p1(r * support_dir[0], r * support_dir[1], z);
694  const Vec3s p2(-r * support_dir[0], -r * support_dir[1], z);
695 
696  if ((support_value - support_dir.dot(p1) <= tol) &&
697  (support_value - support_dir.dot(p2) <= tol)) {
698  // If this check passed, support direction is considered perpendicular to
699  // the basis of the cone. We sample `num_sampled_supports` points on the
700  // base of the cone. We are guaranteed that these points like at a distance
701  // tol of the support plane.
702  const CoalScalar angle_increment =
703  2.0 * (CoalScalar)(EIGEN_PI) / ((CoalScalar)(num_sampled_supports));
704  for (size_t i = 0; i < num_sampled_supports; ++i) {
705  const CoalScalar theta = (CoalScalar)(i)*angle_increment;
706  Vec3s point_on_cone_base(r * std::cos(theta), r * std::sin(theta), z);
707  assert(std::abs(support_dir.dot(support - point_on_cone_base)) <= tol);
708  if (_SupportOptions == SupportOptions::WithSweptSphere) {
709  point_on_cone_base += cone->getSweptSphereRadius() * support_dir;
710  }
711  support_set.addPoint(point_on_cone_base);
712  }
713  } else {
714  // There are two potential supports to add: the tip of the cone and a point
715  // on the basis of the cone. We compare each of these points to the support
716  // value.
717  Vec3s cone_tip(0, 0, cone->halfLength);
718  if (support_value - support_dir.dot(cone_tip) <= tol) {
719  if (_SupportOptions == SupportOptions::WithSweptSphere) {
720  cone_tip += cone->getSweptSphereRadius() * support_dir;
721  }
722  support_set.addPoint(cone_tip);
723  }
724 
725  Vec3s point_on_cone_base = Vec3s(cone->radius * support_dir[0], //
726  cone->radius * support_dir[1], //
727  z);
728  if (support_value - support_dir.dot(point_on_cone_base) <= tol) {
729  if (_SupportOptions == SupportOptions::WithSweptSphere) {
730  point_on_cone_base += cone->getSweptSphereRadius() * support_dir;
731  }
732  support_set.addPoint(point_on_cone_base);
733  }
734  }
735 }
737 
738 // ============================================================================
739 template <int _SupportOptions>
740 void getShapeSupportSet(const Cylinder* cylinder, SupportSet& support_set,
741  int& hint /*unused*/,
742  ShapeSupportData& support_data /*unused*/,
743  size_t num_sampled_supports, CoalScalar tol) {
744  assert(tol > 0);
745  support_set.points().clear();
746 
747  Vec3s support;
748  const Vec3s& support_dir = support_set.getNormal();
749  getShapeSupport<SupportOptions::NoSweptSphere>(cylinder, support_dir, support,
750  hint, support_data);
751  const CoalScalar support_value = support.dot(support_dir);
752 
753  // The following is very similar to what is done for Cone's support set
754  // computation.
755  const CoalScalar r = cylinder->radius;
756  const CoalScalar z =
757  support_dir[2] <= 0 ? -cylinder->halfLength : cylinder->halfLength;
758  const Vec3s p1(r * support_dir[0], r * support_dir[1], z);
759  const Vec3s p2(-r * support_dir[0], -r * support_dir[1], z);
760 
761  if ((support_value - support_dir.dot(p1) <= tol) &&
762  (support_value - support_dir.dot(p2) <= tol)) {
763  const CoalScalar angle_increment =
764  2.0 * (CoalScalar)(EIGEN_PI) / ((CoalScalar)(num_sampled_supports));
765  for (size_t i = 0; i < num_sampled_supports; ++i) {
766  const CoalScalar theta = (CoalScalar)(i)*angle_increment;
767  Vec3s point_on_cone_base(r * std::cos(theta), r * std::sin(theta), z);
768  assert(std::abs(support_dir.dot(support - point_on_cone_base)) <= tol);
769  if (_SupportOptions == SupportOptions::WithSweptSphere) {
770  point_on_cone_base += cylinder->getSweptSphereRadius() * support_dir;
771  }
772  support_set.addPoint(point_on_cone_base);
773  }
774  } else {
775  // There are two potential supports to add: one on each circle bases of the
776  // cylinder.
777  Vec3s point_on_lower_circle = Vec3s(cylinder->radius * support_dir[0], //
778  cylinder->radius * support_dir[1], //
779  -cylinder->halfLength);
780  if (support_value - support_dir.dot(point_on_lower_circle) <= tol) {
781  if (_SupportOptions == SupportOptions::WithSweptSphere) {
782  point_on_lower_circle += cylinder->getSweptSphereRadius() * support_dir;
783  }
784  support_set.addPoint(point_on_lower_circle);
785  }
786 
787  Vec3s point_on_upper_circle = Vec3s(cylinder->radius * support_dir[0], //
788  cylinder->radius * support_dir[1], //
789  cylinder->halfLength);
790  if (support_value - support_dir.dot(point_on_upper_circle) <= tol) {
791  if (_SupportOptions == SupportOptions::WithSweptSphere) {
792  point_on_upper_circle += cylinder->getSweptSphereRadius() * support_dir;
793  }
794  support_set.addPoint(point_on_upper_circle);
795  }
796  }
797 }
799 
800 // ============================================================================
801 template <int _SupportOptions>
802 void getShapeSupportSetLinear(const ConvexBase* convex, SupportSet& support_set,
803  int& hint /*unused*/,
804  ShapeSupportData& support_data, size_t /*unused*/,
805  CoalScalar tol) {
806  assert(tol > 0);
807  Vec3s support;
808  const Vec3s& support_dir = support_set.getNormal();
809  getShapeSupport<SupportOptions::NoSweptSphere>(convex, support_dir, support,
810  hint, support_data);
811  const CoalScalar support_value = support_dir.dot(support);
812 
813  const std::vector<Vec3s>& points = *(convex->points);
814  SupportSet::Polygon& polygon = support_data.polygon;
815  polygon.clear();
816  const Transform3s& tf = support_set.tf;
817  for (const Vec3s& point : points) {
818  const CoalScalar dot = support_dir.dot(point);
819  if (support_value - dot <= tol) {
820  if (_SupportOptions == SupportOptions::WithSweptSphere) {
821  const Vec2s p =
822  tf.inverseTransform(point +
823  convex->getSweptSphereRadius() * support_dir)
824  .template head<2>();
825  polygon.emplace_back(p);
826  } else {
827  const Vec2s p = tf.inverseTransform(point).template head<2>();
828  polygon.emplace_back(p);
829  }
830  }
831  }
832 
833  computeSupportSetConvexHull(polygon, support_set.points());
834 }
835 
836 // ============================================================================
837 template <int _SupportOptions>
839  const std::vector<Vec3s>& points,
840  const std::vector<ConvexBase::Neighbors>& neighbors,
841  const CoalScalar swept_sphere_radius, const size_t vertex_idx,
842  const Vec3s& support_dir, const CoalScalar support_value,
843  const Transform3s& tf, std::vector<int8_t>& visited,
844  SupportSet::Polygon& polygon, CoalScalar tol) {
845  COAL_UNUSED_VARIABLE(swept_sphere_radius);
846 
847  if (visited[vertex_idx]) {
848  return;
849  }
850 
851  visited[vertex_idx] = true;
852  const Vec3s& point = points[vertex_idx];
853  const CoalScalar val = point.dot(support_dir);
854  if (support_value - val <= tol) {
855  if (_SupportOptions == SupportOptions::WithSweptSphere) {
856  const Vec2s p =
857  tf.inverseTransform(point + swept_sphere_radius * support_dir)
858  .template head<2>();
859  polygon.emplace_back(p);
860 
861  } else {
862  const Vec2s p = tf.inverseTransform(point).template head<2>();
863  polygon.emplace_back(p);
864  }
865 
866  const ConvexBase::Neighbors& point_neighbors = neighbors[vertex_idx];
867  for (int i = 0; i < point_neighbors.count(); ++i) {
868  const size_t neighbor_index = (size_t)(point_neighbors[i]);
869  convexSupportSetRecurse<_SupportOptions>(
870  points, neighbors, swept_sphere_radius, neighbor_index, support_dir,
871  support_value, tf, visited, polygon, tol);
872  }
873  }
874 }
875 
876 // ============================================================================
877 template <int _SupportOptions>
878 void getShapeSupportSetLog(const ConvexBase* convex, SupportSet& support_set,
879  int& hint, ShapeSupportData& support_data,
880  size_t /*unused*/, CoalScalar tol) {
881  assert(tol > 0);
882  Vec3s support;
883  const Vec3s& support_dir = support_set.getNormal();
884  getShapeSupportLog<SupportOptions::NoSweptSphere>(
885  convex, support_dir, support, hint, support_data);
886  const CoalScalar support_value = support.dot(support_dir);
887 
888  const std::vector<Vec3s>& points = *(convex->points);
889  const std::vector<ConvexBase::Neighbors>& neighbors = *(convex->neighbors);
890  const CoalScalar swept_sphere_radius = convex->getSweptSphereRadius();
891  std::vector<int8_t>& visited = support_data.visited;
892  // `visited` is guaranteed to be of right size due to previous call to convex
893  // log support function.
894  std::fill(support_data.visited.begin(), support_data.visited.end(), false);
895 
896  SupportSet::Polygon& polygon = support_data.polygon;
897  polygon.clear();
898  const Transform3s& tf = support_set.tf;
899 
900  const size_t vertex_idx = (size_t)(hint);
901  convexSupportSetRecurse<_SupportOptions>(
902  points, neighbors, swept_sphere_radius, vertex_idx, support_dir,
903  support_value, tf, visited, polygon, tol);
904 
905  computeSupportSetConvexHull(polygon, support_set.points());
906 }
907 
908 // ============================================================================
909 template <int _SupportOptions>
910 void getShapeSupportSet(const ConvexBase* convex, SupportSet& support_set,
911  int& hint, ShapeSupportData& support_data,
912  size_t num_sampled_supports /*unused*/,
913  CoalScalar tol) {
915  convex->neighbors != nullptr) {
916  getShapeSupportSetLog<_SupportOptions>(
917  convex, support_set, hint, support_data, num_sampled_supports, tol);
918  } else {
919  getShapeSupportSetLinear<_SupportOptions>(
920  convex, support_set, hint, support_data, num_sampled_supports, tol);
921  }
922 }
924 
925 // ============================================================================
926 template <int _SupportOptions>
927 void getShapeSupportSet(const SmallConvex* convex, SupportSet& support_set,
928  int& hint /*unused*/,
929  ShapeSupportData& support_data /*unused*/,
930  size_t num_sampled_supports /*unused*/,
931  CoalScalar tol) {
932  getShapeSupportSetLinear<_SupportOptions>(
933  reinterpret_cast<const ConvexBase*>(convex), support_set, hint,
934  support_data, num_sampled_supports, tol);
935 }
937 
938 // ============================================================================
939 template <int _SupportOptions>
940 void getShapeSupportSet(const LargeConvex* convex, SupportSet& support_set,
941  int& hint, ShapeSupportData& support_data,
942  size_t num_sampled_supports /*unused*/,
943  CoalScalar tol) {
944  getShapeSupportSetLog<_SupportOptions>(
945  reinterpret_cast<const ConvexBase*>(convex), support_set, hint,
946  support_data, num_sampled_supports, tol);
947 }
949 
950 // ============================================================================
951 COAL_DLLAPI
953  SupportSet::Polygon& cvx_hull) {
954  cvx_hull.clear();
955 
956  if (cloud.size() <= 2) {
957  // Point or segment, nothing to do.
958  for (const Vec2s& point : cloud) {
959  cvx_hull.emplace_back(point);
960  }
961  return;
962  }
963 
964  if (cloud.size() == 3) {
965  // We have a triangle, we only need to arrange it in a counter clockwise
966  // fashion.
967  //
968  // Put the vector which has the lowest y coordinate first.
969  if (cloud[0](1) > cloud[1](1)) {
970  std::swap(cloud[0], cloud[1]);
971  }
972  if (cloud[0](1) > cloud[2](1)) {
973  std::swap(cloud[0], cloud[2]);
974  }
975  const Vec2s& a = cloud[0];
976  const Vec2s& b = cloud[1];
977  const Vec2s& c = cloud[2];
978  const CoalScalar det =
979  (b(0) - a(0)) * (c(1) - a(1)) - (b(1) - a(1)) * (c(0) - a(0));
980  if (det < 0) {
981  std::swap(cloud[1], cloud[2]);
982  }
983 
984  for (const Vec2s& point : cloud) {
985  cvx_hull.emplace_back(point);
986  }
987  return;
988  }
989 
990  // The following is an implementation of the O(nlog(n)) graham scan
991  // algorithm, used to compute convex-hulls in 2D.
992  // See https://en.wikipedia.org/wiki/Graham_scan
993  //
994  // Step 1 - Compute first element of the convex-hull by computing the support
995  // in the direction (0, -1) (take the element of the set which has the lowest
996  // y coordinate).
997  size_t support_idx = 0;
998  CoalScalar support_val = cloud[0](1);
999  for (size_t i = 1; i < cloud.size(); ++i) {
1000  const CoalScalar val = cloud[i](1);
1001  if (val < support_val) {
1002  support_val = val;
1003  support_idx = i;
1004  }
1005  }
1006  std::swap(cloud[0], cloud[support_idx]);
1007  cvx_hull.clear();
1008  cvx_hull.emplace_back(cloud[0]);
1009  const Vec2s& v = cvx_hull[0];
1010 
1011  // Step 2 - Sort the rest of the point cloud according to the angle made with
1012  // v. Note: we use stable_sort instead of sort because sort can fail if two
1013  // values are identical.
1014  std::stable_sort(
1015  cloud.begin() + 1, cloud.end(), [&v](const Vec2s& p1, const Vec2s& p2) {
1016  // p1 is "smaller" than p2 if det(p1 - v, p2 - v) >= 0
1017  const CoalScalar det =
1018  (p1(0) - v(0)) * (p2(1) - v(1)) - (p1(1) - v(1)) * (p2(0) - v(0));
1019  if (std::abs(det) <= Eigen::NumTraits<CoalScalar>::dummy_precision()) {
1020  // If two points are identical or (v, p1, p2) are colinear, p1 is
1021  // "smaller" if it is closer to v.
1022  return ((p1 - v).squaredNorm() <= (p2 - v).squaredNorm());
1023  }
1024  return det > 0;
1025  });
1026 
1027  // Step 3 - We iterate over the now ordered point of cloud and add the points
1028  // to the cvx-hull if they successively form "left turns" only. A left turn
1029  // is: considering the last three points of the cvx-hull, if they form a
1030  // right-hand basis (determinant > 0) then they make a left turn.
1031  auto isRightSided = [](const Vec2s& p1, const Vec2s& p2, const Vec2s& p3) {
1032  // Checks if (p2 - p1, p3 - p1) forms a right-sided base based on
1033  // det(p2 - p1, p3 - p1)
1034  const CoalScalar det =
1035  (p2(0) - p1(0)) * (p3(1) - p1(1)) - (p2(1) - p1(1)) * (p3(0) - p1(0));
1036  // Note: we set a dummy precision threshold so that identical points or
1037  // colinear pionts are not added to the cvx-hull.
1038  return det > Eigen::NumTraits<CoalScalar>::dummy_precision();
1039  };
1040 
1041  // We initialize the cvx-hull algo by adding the first three
1042  // (distinct) points of the set.
1043  // These three points are guaranteed, due to the previous sorting,
1044  // to form a right sided basis, hence to form a left turn.
1045  size_t cloud_beginning_idx = 1;
1046  while (cvx_hull.size() < 3) {
1047  const Vec2s& vec = cloud[cloud_beginning_idx];
1048  if ((cvx_hull.back() - vec).squaredNorm() >
1050  cvx_hull.emplace_back(vec);
1051  }
1052  ++cloud_beginning_idx;
1053  }
1054  // The convex-hull should wrap counter-clockwise, i.e. three successive
1055  // points should always form a right-sided basis. Every time we do a turn
1056  // in the wrong direction, we remove the last point of the convex-hull.
1057  // When we do a turn in the correct direction, we add a point to the
1058  // convex-hull.
1059  for (size_t i = cloud_beginning_idx; i < cloud.size(); ++i) {
1060  const Vec2s& vec = cloud[i];
1061  while (cvx_hull.size() > 1 &&
1062  !isRightSided(cvx_hull[cvx_hull.size() - 2],
1063  cvx_hull[cvx_hull.size() - 1], vec)) {
1064  cvx_hull.pop_back();
1065  }
1066  cvx_hull.emplace_back(vec);
1067  }
1068 }
1069 
1070 } // namespace details
1071 } // namespace coal
coal::ContactPatch::Polygon
std::vector< Vec2s > Polygon
Definition: coal/collision_data.h:514
coal::CollisionGeometry::getNodeType
virtual NODE_TYPE getNodeType() const
get the node type
Definition: coal/collision_object.h:130
coal::TriangleP::b
Vec3s b
Definition: coal/shape/geometric_shapes.h:149
coal::details::getShapeSupportSetLinear
void getShapeSupportSetLinear(const ConvexBase *convex, SupportSet &support_set, int &hint, ShapeSupportData &support_data, size_t, CoalScalar tol)
Definition: support_functions.cpp:802
coal::Cylinder::halfLength
CoalScalar halfLength
Half Length along z axis.
Definition: coal/shape/geometric_shapes.h:587
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
coal::details::getShapeSupport
void getShapeSupport(const TriangleP *triangle, const Vec3s &dir, Vec3s &support, int &, ShapeSupportData &)
Triangle support function.
Definition: support_functions.cpp:109
coal::ConvexBase::num_points
unsigned int num_points
Definition: coal/shape/geometric_shapes.h:720
collision_manager.box
box
Definition: collision_manager.py:11
coal::ConvexBase::neighbors
std::shared_ptr< std::vector< Neighbors > > neighbors
Neighbors of each vertex. It is an array of size num_points. For each vertex, it contains the number ...
Definition: coal/shape/geometric_shapes.h:732
coal::details::ShapeSupportData
Stores temporary data for the computation of support points.
Definition: coal/narrowphase/support_functions.h:80
support_functions.h
y
y
coal::ContactPatch::getNormal
Vec3s getNormal() const
Normal of the contact patch, expressed in the WORLD frame.
Definition: coal/collision_data.h:569
coal::Capsule::halfLength
CoalScalar halfLength
Half Length along z axis.
Definition: coal/shape/geometric_shapes.h:402
coal::GEOM_CONE
@ GEOM_CONE
Definition: coal/collision_object.h:77
collision_manager.sphere
sphere
Definition: collision_manager.py:4
val
val
coal::GEOM_CONVEX
@ GEOM_CONVEX
Definition: coal/collision_object.h:79
coal::Capsule
Capsule It is where is the distance between the point x and the capsule segment AB,...
Definition: coal/shape/geometric_shapes.h:383
coal::Cylinder::radius
CoalScalar radius
Radius of the cylinder.
Definition: coal/shape/geometric_shapes.h:581
coal::details::ShapeSupportData::visited
std::vector< int8_t > visited
Definition: coal/narrowphase/support_functions.h:82
coal::details::ShapeSupportData::last_dir
Vec3s last_dir
Definition: coal/narrowphase/support_functions.h:86
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
vec
vec
coal::GEOM_CAPSULE
@ GEOM_CAPSULE
Definition: coal/collision_object.h:76
octree.r
r
Definition: octree.py:9
coal::Ellipsoid
Ellipsoid centered at point zero.
Definition: coal/shape/geometric_shapes.h:305
coal::GEOM_SPHERE
@ GEOM_SPHERE
Definition: coal/collision_object.h:75
coal::details::WithSweptSphere
@ WithSweptSphere
Definition: coal/narrowphase/support_functions.h:60
coal::ContactPatch
This structure allows to encode contact patches. A contact patch is defined by a set of points belong...
Definition: coal/collision_data.h:512
coal::Ellipsoid::radii
Vec3s radii
Radii of the Ellipsoid (such that on boundary: x^2/rx^2 + y^2/ry^2.
Definition: coal/shape/geometric_shapes.h:318
coal::Transform3s::inverseTransform
Vec3s inverseTransform(const Eigen::MatrixBase< Derived > &v) const
transform a given vector by the inverse of the transform
Definition: coal/math/transform.h:158
a
list a
coal::Box
Center at zero point, axis aligned box.
Definition: coal/shape/geometric_shapes.h:166
coal::ConvexBase::Neighbors::count
unsigned char const & count() const
Definition: coal/shape/geometric_shapes.h:691
coal::Sphere
Center at zero point sphere.
Definition: coal/shape/geometric_shapes.h:240
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
coal::details::getSupport
Vec3s getSupport(const ShapeBase *shape, const Vec3s &dir, int &hint)
the support function for shape. The output support point is expressed in the local frame of the shape...
Definition: support_functions.cpp:51
coal::ConvexBase::Neighbors
Definition: coal/shape/geometric_shapes.h:687
COAL_UNUSED_VARIABLE
#define COAL_UNUSED_VARIABLE(var)
Definition: include/coal/fwd.hh:56
coal::GEOM_PLANE
@ GEOM_PLANE
Definition: coal/collision_object.h:80
coal::TriangleP::a
Vec3s a
Definition: coal/shape/geometric_shapes.h:149
coal::detail::select
size_t select(const NodeBase< BV > &query, const NodeBase< BV > &node1, const NodeBase< BV > &node2)
select from node1 and node2 which is close to a given query. 0 for node1 and 1 for node2
Definition: coal/broadphase/detail/hierarchy_tree-inl.h:952
coal::GEOM_ELLIPSOID
@ GEOM_ELLIPSOID
Definition: coal/collision_object.h:84
d
d
c
c
coal::GEOM_HALFSPACE
@ GEOM_HALFSPACE
Definition: coal/collision_object.h:81
coal::Cone::halfLength
CoalScalar halfLength
Half Length along z axis.
Definition: coal/shape/geometric_shapes.h:486
coal::ShapeBase
Base class for all basic geometric shapes.
Definition: coal/shape/geometric_shapes.h:58
coal::GEOM_TRIANGLE
@ GEOM_TRIANGLE
Definition: coal/collision_object.h:82
coal::details::getShapeSupportLinear
void getShapeSupportLinear(const ConvexBase *convex, const Vec3s &dir, Vec3s &support, int &hint, ShapeSupportData &)
Definition: support_functions.cpp:383
x
x
coal::details::ShapeSupportData::polygon
SupportSet::Polygon polygon
Definition: coal/narrowphase/support_functions.h:90
coal::details::computeSupportSetConvexHull
COAL_DLLAPI void computeSupportSetConvexHull(SupportSet::Polygon &cloud, SupportSet::Polygon &cvx_hull)
Computes the convex-hull of support_set. For now, this function is only needed for Box and ConvexBase...
Definition: support_functions.cpp:952
coal::Cylinder
Cylinder along Z axis. The cylinder is defined at its centroid.
Definition: coal/shape/geometric_shapes.h:560
coal::details::convexSupportSetRecurse
void convexSupportSetRecurse(const std::vector< Vec3s > &points, const std::vector< ConvexBase::Neighbors > &neighbors, const CoalScalar swept_sphere_radius, const size_t vertex_idx, const Vec3s &support_dir, const CoalScalar support_value, const Transform3s &tf, std::vector< int8_t > &visited, SupportSet::Polygon &polygon, CoalScalar tol)
Definition: support_functions.cpp:838
coal::details::details::inflate
void inflate(const MinkowskiDiff &shape, const Vec3s &normal, Vec3s &w0, Vec3s &w1)
Definition: src/narrowphase/gjk.cpp:158
setZero
void setZero(std::vector< MatType, Eigen::aligned_allocator< MatType > > &Ms)
coal::ContactPatch::tf
Transform3s tf
Frame of the set, expressed in the world coordinates. The z-axis of the frame's rotation is the conta...
Definition: coal/collision_data.h:518
coal::ContactPatch::clear
void clear()
Clear the set.
Definition: coal/collision_data.h:640
octree.p1
tuple p1
Definition: octree.py:54
coal::TriangleP
Triangle stores the points instead of only indices of points.
Definition: coal/shape/geometric_shapes.h:110
coal::GEOM_CYLINDER
@ GEOM_CYLINDER
Definition: coal/collision_object.h:78
coal::details::getShapeSupportTplInstantiation
getShapeSupportTplInstantiation(TriangleP)
coal::ShapeBase::getSweptSphereRadius
CoalScalar getSweptSphereRadius() const
Get radius of sphere swept around the shape. This radius is always >= 0.
Definition: coal/shape/geometric_shapes.h:86
generate_distance_plot.b
float b
Definition: generate_distance_plot.py:7
coal::details::getSupportSet
void getSupportSet(const ShapeBase *shape, SupportSet &support_set, int &hint, size_t num_sampled_supports=6, CoalScalar tol=1e-3)
Computes the support set for shape. This function assumes the frame of the support set has already be...
Definition: support_functions.cpp:450
epsilon
static CoalScalar epsilon
Definition: simple.cpp:12
coal::Cone
Cone The base of the cone is at and the top is at .
Definition: coal/shape/geometric_shapes.h:467
coal::details::LargeConvex
Cast a ConvexBase to a LargeConvex to use the log version of getShapeSupport. This is much faster tha...
Definition: coal/narrowphase/support_functions.h:142
coal::ConvexBase::SupportWarmStartPolytope::points
std::vector< Vec3s > points
Array of support points to warm start the support function computation.
Definition: coal/shape/geometric_shapes.h:745
coal::details::getShapeSupportSet
void getShapeSupportSet(const TriangleP *triangle, SupportSet &support_set, int &, ShapeSupportData &, size_t num_sampled_supports=6, CoalScalar tol=1e-3)
Triangle support set function. Assumes the support set frame has already been computed.
Definition: support_functions.cpp:505
coal::details::SmallConvex
See LargeConvex.
Definition: coal/narrowphase/support_functions.h:144
coal::details::getShapeSupportLog
void getShapeSupportLog(const ConvexBase *convex, const Vec3s &dir, Vec3s &support, int &hint, ShapeSupportData &support_data)
Definition: support_functions.cpp:306
obb.fill
fill
Definition: obb.py:104
coal::Cone::radius
CoalScalar radius
Radius of the cone.
Definition: coal/shape/geometric_shapes.h:480
coal::details::getShapeSupportSetTplInstantiation
getShapeSupportSetTplInstantiation(TriangleP)
coal::ContactPatch::points
Polygon & points()
Getter for the 2D points in the set.
Definition: coal/collision_data.h:616
CALL_GET_SHAPE_SUPPORT_SET
#define CALL_GET_SHAPE_SUPPORT_SET(ShapeType)
Definition: support_functions.cpp:445
coal::Capsule::radius
CoalScalar radius
Radius of capsule.
Definition: coal/shape/geometric_shapes.h:396
coal::ConvexBase::SupportWarmStartPolytope::indices
std::vector< int > indices
Indices of the support points warm starts. These are the indices of the real convex,...
Definition: coal/shape/geometric_shapes.h:750
coal::TriangleP::c
Vec3s c
Definition: coal/shape/geometric_shapes.h:149
c2
c2
coal::GEOM_BOX
@ GEOM_BOX
Definition: coal/collision_object.h:74
CALL_GET_SHAPE_SUPPORT
#define CALL_GET_SHAPE_SUPPORT(ShapeType)
Definition: support_functions.cpp:47
coal::ConvexBase::support_warm_starts
SupportWarmStartPolytope support_warm_starts
Support warm start polytopes.
Definition: coal/shape/geometric_shapes.h:757
coal::ConvexBase::points
std::shared_ptr< std::vector< Vec3s > > points
An array of the points of the polygon.
Definition: coal/shape/geometric_shapes.h:719
coal::details::getShapeSupportSetLog
void getShapeSupportSetLog(const ConvexBase *convex, SupportSet &support_set, int &hint, ShapeSupportData &support_data, size_t, CoalScalar tol)
Definition: support_functions.cpp:878
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
obb.v
list v
Definition: obb.py:48
coal::ContactPatch::addPoint
void addPoint(const Vec3s &point_3d)
Add a 3D point to the set, expressed in the world frame.
Definition: coal/collision_data.h:584
coal::Vec2s
Eigen::Matrix< CoalScalar, 2, 1 > Vec2s
Definition: coal/data_types.h:78
coal::ConvexBase::num_vertices_large_convex_threshold
static constexpr size_t num_vertices_large_convex_threshold
Above this threshold, the convex polytope is considered large. This influcences the way the support f...
Definition: coal/shape/geometric_shapes.h:716
coal::ConvexBase
Base for convex polytope.
Definition: coal/shape/geometric_shapes.h:645


hpp-fcl
Author(s):
autogenerated on Sat Nov 23 2024 03:44:59