bullet_utils.cpp
Go to the documentation of this file.
1 
46 
48 #include <LinearMath/btConvexHullComputer.h>
49 #include <BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h>
50 #include <BulletCollision/CollisionShapes/btShapeHull.h>
51 #include <BulletCollision/Gimpact/btTriangleShapeEx.h>
52 #include <boost/thread/mutex.hpp>
53 #include <memory>
54 #include <stdexcept>
55 #include <octomap/octomap.h>
57 
59 
61 {
62 btVector3 convertEigenToBt(const Eigen::Vector3d& v)
63 {
64  return btVector3{ static_cast<btScalar>(v[0]), static_cast<btScalar>(v[1]), static_cast<btScalar>(v[2]) };
65 }
66 
67 Eigen::Vector3d convertBtToEigen(const btVector3& v)
68 {
69  return Eigen::Vector3d{ static_cast<double>(v.x()), static_cast<double>(v.y()), static_cast<double>(v.z()) };
70 }
71 
72 btQuaternion convertEigenToBt(const Eigen::Quaterniond& q)
73 {
74  return btQuaternion{ static_cast<btScalar>(q.x()),
75  static_cast<btScalar>(q.y()),
76  static_cast<btScalar>(q.z()),
77  static_cast<btScalar>(q.w()) };
78 }
79 
80 btMatrix3x3 convertEigenToBt(const Eigen::Matrix3d& r)
81 {
82  return btMatrix3x3{ static_cast<btScalar>(r(0, 0)), static_cast<btScalar>(r(0, 1)), static_cast<btScalar>(r(0, 2)),
83  static_cast<btScalar>(r(1, 0)), static_cast<btScalar>(r(1, 1)), static_cast<btScalar>(r(1, 2)),
84  static_cast<btScalar>(r(2, 0)), static_cast<btScalar>(r(2, 1)), static_cast<btScalar>(r(2, 2)) };
85 }
86 
87 Eigen::Matrix3d convertBtToEigen(const btMatrix3x3& r)
88 {
89  Eigen::Matrix3d m;
90  m << static_cast<double>(r[0][0]), static_cast<double>(r[0][1]), static_cast<double>(r[0][2]),
91  static_cast<double>(r[1][0]), static_cast<double>(r[1][1]), static_cast<double>(r[1][2]),
92  static_cast<double>(r[2][0]), static_cast<double>(r[2][1]), static_cast<double>(r[2][2]);
93  return m;
94 }
95 
96 btTransform convertEigenToBt(const Eigen::Isometry3d& t)
97 {
98  const Eigen::Matrix3d& rot = t.matrix().block<3, 3>(0, 0);
99  const Eigen::Vector3d& tran = t.translation();
100 
101  return btTransform{ convertEigenToBt(rot), convertEigenToBt(tran) };
102 }
103 
104 Eigen::Isometry3d convertBtToEigen(const btTransform& t)
105 {
106  Eigen::Isometry3d i = Eigen::Isometry3d::Identity();
107  i.linear() = convertBtToEigen(t.getBasis());
108  i.translation() = convertBtToEigen(t.getOrigin());
109 
110  return i;
111 }
112 
113 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Box::ConstPtr& geom)
114 {
115  auto a = static_cast<btScalar>(geom->getX() / 2);
116  auto b = static_cast<btScalar>(geom->getY() / 2);
117  auto c = static_cast<btScalar>(geom->getZ() / 2);
118 
119  return std::make_shared<BulletCollisionShape>(std::make_shared<btBoxShape>(btVector3(a, b, c)));
120 }
121 
122 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Sphere::ConstPtr& geom)
123 {
124  return std::make_shared<BulletCollisionShape>(
125  std::make_shared<btSphereShape>(static_cast<btScalar>(geom->getRadius())));
126 }
127 
128 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Cylinder::ConstPtr& geom)
129 {
130  auto radius = static_cast<btScalar>(geom->getRadius());
131  auto length = static_cast<btScalar>(geom->getLength() / 2);
132  return std::make_shared<BulletCollisionShape>(std::make_shared<btCylinderShapeZ>(btVector3(radius, radius, length)));
133 }
134 
135 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Cone::ConstPtr& geom)
136 {
137  auto radius = static_cast<btScalar>(geom->getRadius());
138  auto length = static_cast<btScalar>(geom->getLength());
139  return std::make_shared<BulletCollisionShape>(std::make_shared<btConeShapeZ>(radius, length));
140 }
141 
142 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Capsule::ConstPtr& geom)
143 {
144  auto radius = static_cast<btScalar>(geom->getRadius());
145  auto length = static_cast<btScalar>(geom->getLength());
146  return std::make_shared<BulletCollisionShape>(std::make_shared<btCapsuleShapeZ>(radius, length));
147 }
148 
149 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Mesh::ConstPtr& geom)
150 {
151  int vertice_count = geom->getVertexCount();
152  int triangle_count = geom->getFaceCount();
153  const tesseract_common::VectorVector3d& vertices = *(geom->getVertices());
154  const Eigen::VectorXi& triangles = *(geom->getFaces());
155 
156  auto collision_shape = std::make_shared<BulletCollisionShape>();
157  if (vertice_count > 0 && triangle_count > 0)
158  {
159  auto compound = std::make_shared<btCompoundShape>(BULLET_COMPOUND_USE_DYNAMIC_AABB, triangle_count);
160  compound->setMargin(BULLET_MARGIN); // margin: compound. seems to have no
161  // effect when positive but has an
162  // effect when negative
163 
164  collision_shape->children.reserve(static_cast<std::size_t>(triangle_count));
165  for (int i = 0; i < triangle_count; ++i)
166  {
167  btVector3 v[3]; // NOLINT
168  assert(triangles[4L * i] == 3);
169  for (unsigned x = 0; x < 3; ++x)
170  {
171  // Note: triangles structure is number of vertices that represent the triangle followed by vertex indexes
172  const Eigen::Vector3d& vertice = vertices[static_cast<size_t>(triangles[(4 * i) + (static_cast<int>(x) + 1)])];
173  for (unsigned y = 0; y < 3; ++y)
174  v[x][y] = static_cast<btScalar>(vertice[y]);
175  }
176 
177  std::shared_ptr<btCollisionShape> subshape = std::make_shared<btTriangleShapeEx>(v[0], v[1], v[2]);
178  if (subshape != nullptr)
179  {
180  collision_shape->children.push_back(subshape);
181  subshape->setMargin(BULLET_MARGIN);
182  btTransform geomTrans;
183  geomTrans.setIdentity();
184  compound->addChildShape(geomTrans, subshape.get());
185  }
186  }
187  collision_shape->top_level = compound;
188  return collision_shape;
189  }
190  CONSOLE_BRIDGE_logError("The mesh is empty!");
191  return nullptr;
192 }
193 
194 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::ConvexMesh::ConstPtr& geom)
195 {
196  int vertice_count = geom->getVertexCount();
197  int triangle_count = geom->getFaceCount();
198  const tesseract_common::VectorVector3d& vertices = *(geom->getVertices());
199 
200  if (vertice_count > 0 && triangle_count > 0)
201  {
202  auto convex_hull_shape = std::make_shared<btConvexHullShape>();
203  for (const auto& v : vertices)
204  convex_hull_shape->addPoint(
205  btVector3(static_cast<btScalar>(v[0]), static_cast<btScalar>(v[1]), static_cast<btScalar>(v[2])));
206 
207  return std::make_shared<BulletCollisionShape>(convex_hull_shape);
208  }
209  CONSOLE_BRIDGE_logError("The mesh is empty!");
210  return nullptr;
211 }
212 
213 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::Octree::ConstPtr& geom)
214 {
215  const octomap::OcTree& octree = *(geom->getOctree());
216  double occupancy_threshold = octree.getOccupancyThres();
217  auto subshape = std::make_shared<btCompoundShape>(BULLET_COMPOUND_USE_DYNAMIC_AABB, static_cast<int>(octree.size()));
218 
219  std::vector<std::shared_ptr<btCollisionShape>> managed_shapes;
220  managed_shapes.resize(octree.getTreeDepth() + 1);
221  switch (geom->getSubType())
222  {
224  {
225  for (auto it = octree.begin(static_cast<unsigned char>(octree.getTreeDepth())), end = octree.end(); it != end;
226  ++it)
227  {
228  if (it->getOccupancy() >= occupancy_threshold)
229  {
230  double size = it.getSize();
231  btTransform geomTrans;
232  geomTrans.setIdentity();
233  geomTrans.setOrigin(btVector3(
234  static_cast<btScalar>(it.getX()), static_cast<btScalar>(it.getY()), static_cast<btScalar>(it.getZ())));
235  auto length = static_cast<btScalar>(size / 2.0);
236 
237  std::shared_ptr<btCollisionShape> childshape = managed_shapes.at(it.getDepth());
238  if (childshape == nullptr)
239  {
240  childshape = std::make_shared<btBoxShape>(btVector3(length, length, length));
241  childshape->setMargin(BULLET_MARGIN);
242  managed_shapes.at(it.getDepth()) = childshape;
243  }
244 
245  subshape->addChildShape(geomTrans, childshape.get());
246  }
247  }
248 
249  auto collision_shape = std::make_shared<BulletCollisionShape>();
250  collision_shape->top_level = subshape;
251  collision_shape->children.reserve(managed_shapes.size());
252  for (const auto& managed_shape : managed_shapes)
253  {
254  if (managed_shape != nullptr)
255  collision_shape->children.push_back(managed_shape);
256  }
257 
258  return collision_shape;
259  }
261  {
262  for (auto it = octree.begin(static_cast<unsigned char>(octree.getTreeDepth())), end = octree.end(); it != end;
263  ++it)
264  {
265  if (it->getOccupancy() >= occupancy_threshold)
266  {
267  double size = it.getSize();
268  btTransform geomTrans;
269  geomTrans.setIdentity();
270  geomTrans.setOrigin(btVector3(
271  static_cast<btScalar>(it.getX()), static_cast<btScalar>(it.getY()), static_cast<btScalar>(it.getZ())));
272 
273  std::shared_ptr<btCollisionShape> childshape = managed_shapes.at(it.getDepth());
274  if (childshape == nullptr)
275  {
276  childshape = std::make_shared<btSphereShape>(static_cast<btScalar>((size / 2)));
277  // Sphere is a special case where you do not modify the margin which is internally set to the radius
278  managed_shapes.at(it.getDepth()) = childshape;
279  }
280 
281  subshape->addChildShape(geomTrans, childshape.get());
282  }
283  }
284 
285  auto collision_shape = std::make_shared<BulletCollisionShape>();
286  collision_shape->top_level = subshape;
287  collision_shape->children.reserve(managed_shapes.size());
288  for (const auto& managed_shape : managed_shapes)
289  {
290  if (managed_shape != nullptr)
291  collision_shape->children.push_back(managed_shape);
292  }
293 
294  return collision_shape;
295  }
297  {
298  for (auto it = octree.begin(static_cast<unsigned char>(octree.getTreeDepth())), end = octree.end(); it != end;
299  ++it)
300  {
301  if (it->getOccupancy() >= occupancy_threshold)
302  {
303  double size = it.getSize();
304  btTransform geomTrans;
305  geomTrans.setIdentity();
306  geomTrans.setOrigin(btVector3(
307  static_cast<btScalar>(it.getX()), static_cast<btScalar>(it.getY()), static_cast<btScalar>(it.getZ())));
308 
309  std::shared_ptr<btCollisionShape> childshape = managed_shapes.at(it.getDepth());
310  if (childshape == nullptr)
311  {
312  childshape =
313  std::make_shared<btSphereShape>(static_cast<btScalar>(std::sqrt(2 * ((size / 2) * (size / 2)))));
314  // Sphere is a special case where you do not modify the margin which is internally set to the radius
315  managed_shapes.at(it.getDepth()) = childshape;
316  }
317 
318  subshape->addChildShape(geomTrans, childshape.get());
319  }
320  }
321 
322  auto collision_shape = std::make_shared<BulletCollisionShape>();
323  collision_shape->top_level = subshape;
324  collision_shape->children.reserve(managed_shapes.size());
325  for (const auto& managed_shape : managed_shapes)
326  {
327  if (managed_shape != nullptr)
328  collision_shape->children.push_back(managed_shape);
329  }
330 
331  return collision_shape;
332  }
333  }
334 
335  CONSOLE_BRIDGE_logError("This bullet shape type (%d) is not supported for geometry octree",
336  static_cast<int>(geom->getSubType()));
337  return nullptr;
338 }
339 
340 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const tesseract_geometry::CompoundMesh::ConstPtr& geom)
341 {
342  const auto& meshes = geom->getMeshes();
343  auto compound_mesh =
344  std::make_shared<btCompoundShape>(BULLET_COMPOUND_USE_DYNAMIC_AABB, static_cast<int>(meshes.size()));
345  compound_mesh->setMargin(BULLET_MARGIN); // margin: compound. seems to have no
346  // effect when positive but has an
347  // effect when negative
348 
349  auto shape = std::make_shared<BulletCollisionShape>(compound_mesh);
350  btTransform trans;
351  trans.setIdentity();
352  for (const auto& mesh : meshes)
353  {
354  std::shared_ptr<BulletCollisionShape> subshape = createShapePrimitive(mesh);
355  if (subshape != nullptr)
356  {
357  shape->children.push_back(subshape->top_level);
358  shape->children.insert(shape->children.end(), subshape->children.begin(), subshape->children.end());
359  compound_mesh->addChildShape(trans, subshape->top_level.get());
360  }
361  }
362 
363  return shape;
364 }
365 
366 std::shared_ptr<BulletCollisionShape> createShapePrimitive(const CollisionShapeConstPtr& geom)
367 {
368  std::shared_ptr<BulletCollisionShape> shape = BulletCollisionShapeCache::get(geom);
369  if (shape != nullptr)
370  return shape;
371 
372  switch (geom->getType())
373  {
375  {
376  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Box>(geom));
377  shape->top_level->setMargin(BULLET_MARGIN);
378  break;
379  }
381  {
382  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Sphere>(geom));
383  // Sphere is a special case where you do not modify the margin which is internally set to the radius
384  break;
385  }
387  {
388  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Cylinder>(geom));
389  shape->top_level->setMargin(BULLET_MARGIN);
390  break;
391  }
393  {
394  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Cone>(geom));
395  shape->top_level->setMargin(BULLET_MARGIN);
396  break;
397  }
399  {
400  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Capsule>(geom));
401  shape->top_level->setMargin(BULLET_MARGIN);
402  break;
403  }
405  {
406  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Mesh>(geom));
407  shape->top_level->setMargin(BULLET_MARGIN);
408  break;
409  }
411  {
412  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::ConvexMesh>(geom));
413  shape->top_level->setMargin(BULLET_MARGIN);
414  break;
415  }
417  {
418  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Octree>(geom));
419  shape->top_level->setMargin(BULLET_MARGIN);
420  break;
421  }
423  {
424  shape = createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::CompoundMesh>(geom));
425  shape->top_level->setMargin(BULLET_MARGIN);
426  break;
427  }
428  // LCOV_EXCL_START
429  default:
430  {
431  CONSOLE_BRIDGE_logError("This geometric shape type (%d) is not supported using BULLET yet",
432  static_cast<int>(geom->getType()));
433  break;
434  }
435  // LCOV_EXCL_STOP
436  }
437 
439  return shape;
440 }
441 
442 void updateCollisionObjectFilters(const std::vector<std::string>& active, const COW::Ptr& cow)
443 {
444  cow->m_collisionFilterGroup = btBroadphaseProxy::KinematicFilter;
445 
446  if (!isLinkActive(active, cow->getName()))
447  {
448  cow->m_collisionFilterGroup = btBroadphaseProxy::StaticFilter;
449  }
450 
451  if (cow->m_collisionFilterGroup == btBroadphaseProxy::StaticFilter)
452  {
453  cow->m_collisionFilterMask = btBroadphaseProxy::KinematicFilter;
454  }
455  else
456  {
458  }
459 }
460 
462  const int& type_id,
463  CollisionShapesConst shapes,
465  : m_name(std::move(name)), m_type_id(type_id), m_shapes(std::move(shapes)), m_shape_poses(std::move(shape_poses))
466 {
467  assert(!m_shapes.empty());
468  assert(!m_shape_poses.empty());
469  assert(!m_name.empty());
470  assert(m_shapes.size() == m_shape_poses.size());
471 
474 
475  if (m_shapes.size() == 1 && m_shape_poses[0].matrix().isIdentity())
476  {
477  std::shared_ptr<BulletCollisionShape> shape = createShapePrimitive(m_shapes[0]);
478  manage(shape);
479  setCollisionShape(shape->top_level.get());
480  }
481  else
482  {
483  auto compound =
484  std::make_shared<btCompoundShape>(BULLET_COMPOUND_USE_DYNAMIC_AABB, static_cast<int>(m_shapes.size()));
485  manage(std::make_shared<BulletCollisionShape>(compound));
486  compound->setMargin(BULLET_MARGIN); // margin: compound. seems to have no
487  // effect when positive but has an
488  // effect when negative
489  setCollisionShape(compound.get());
490 
491  for (std::size_t j = 0; j < m_shapes.size(); ++j)
492  {
493  std::shared_ptr<BulletCollisionShape> subshape = createShapePrimitive(m_shapes[j]);
494  if (subshape != nullptr)
495  {
496  manage(subshape);
497  btTransform geomTrans = convertEigenToBt(m_shape_poses[j]);
498  compound->addChildShape(geomTrans, subshape->top_level.get());
499  }
500  }
501  }
502 
503  btTransform trans;
504  trans.setIdentity();
505  setWorldTransform(trans);
506 }
507 
508 const std::string& CollisionObjectWrapper::getName() const { return m_name; }
509 
510 const int& CollisionObjectWrapper::getTypeID() const { return m_type_id; }
511 
513 {
514  return m_name == other.m_name && m_type_id == other.m_type_id && m_shapes.size() == other.m_shapes.size() &&
515  m_shape_poses.size() == other.m_shape_poses.size() &&
516  std::equal(m_shapes.begin(), m_shapes.end(), other.m_shapes.begin()) &&
517  std::equal(m_shape_poses.begin(),
518  m_shape_poses.end(),
519  other.m_shape_poses.begin(),
520  [](const Eigen::Isometry3d& t1, const Eigen::Isometry3d& t2) { return t1.isApprox(t2); });
521 }
522 
524 
526 {
527  return m_shape_poses;
528 }
529 
530 void CollisionObjectWrapper::getAABB(btVector3& aabb_min, btVector3& aabb_max) const
531 {
532  getCollisionShape()->getAabb(getWorldTransform(), aabb_min, aabb_max);
533  const btScalar& d = getContactProcessingThreshold();
534  btVector3 contactThreshold(d, d, d);
535  aabb_min -= contactThreshold;
536  aabb_max += contactThreshold;
537 }
538 
539 std::shared_ptr<CollisionObjectWrapper> CollisionObjectWrapper::clone()
540 {
541  auto clone_cow = std::make_shared<CollisionObjectWrapper>();
542  clone_cow->m_name = m_name;
543  clone_cow->m_type_id = m_type_id;
544  clone_cow->m_shapes = m_shapes;
545  clone_cow->m_shape_poses = m_shape_poses;
546  clone_cow->m_data = m_data;
547  clone_cow->setCollisionShape(getCollisionShape());
548  clone_cow->setWorldTransform(getWorldTransform());
549  clone_cow->m_collisionFilterGroup = m_collisionFilterGroup;
550  clone_cow->m_collisionFilterMask = m_collisionFilterMask;
551  clone_cow->m_enabled = m_enabled;
552  clone_cow->setBroadphaseHandle(nullptr);
553  return clone_cow;
554 }
555 
556 void CollisionObjectWrapper::manage(const std::shared_ptr<BulletCollisionShape>& t) { m_data.push_back(t); }
557 
558 void CollisionObjectWrapper::manageReserve(std::size_t s) { m_data.reserve(s); }
559 
560 CastHullShape::CastHullShape(btConvexShape* shape, const btTransform& t01) : m_shape(shape), m_t01(t01)
561 {
562  m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
563 }
564 
565 void CastHullShape::updateCastTransform(const btTransform& t01) { m_t01 = t01; }
566 btVector3 CastHullShape::localGetSupportingVertex(const btVector3& vec) const
567 {
568  btVector3 sv0 = m_shape->localGetSupportingVertex(vec);
569  btVector3 sv1 = m_t01 * m_shape->localGetSupportingVertex(vec * m_t01.getBasis());
570  return (vec.dot(sv0) > vec.dot(sv1)) ? sv0 : sv1;
571 }
572 
574 void CastHullShape::getAabb(const btTransform& t_w0, btVector3& aabbMin, btVector3& aabbMax) const
575 {
576  m_shape->getAabb(t_w0, aabbMin, aabbMax);
577  btVector3 min1, max1;
578  m_shape->getAabb(t_w0 * m_t01, min1, max1);
579  aabbMin.setMin(min1);
580  aabbMax.setMax(max1);
581 }
582 
583 const char* CastHullShape::getName() const { return "CastHull"; }
584 btVector3 CastHullShape::localGetSupportingVertexWithoutMargin(const btVector3& v) const
585 {
586  return localGetSupportingVertex(v);
587 }
588 
589 // LCOV_EXCL_START
590 // notice that the vectors should be unit length
592  btVector3* /*supportVerticesOut*/,
593  int /*numVectors*/) const
594 {
595  throw std::runtime_error("If you are seeing this error message then something in Bullet must have changed. Attach "
596  "a debugger and inspect the call stack to find the function in Bullet calling this "
597  "function, then review commit history to determine what change.");
598 }
599 
600 void CastHullShape::getAabbSlow(const btTransform& /*t*/, btVector3& /*aabbMin*/, btVector3& /*aabbMax*/) const
601 {
602  throw std::runtime_error("If you are seeing this error message then something in Bullet must have changed. Attach "
603  "a debugger and inspect the call stack to find the function in Bullet calling this "
604  "function, then review commit history to determine what change.");
605 }
606 
607 void CastHullShape::setLocalScaling(const btVector3& /*scaling*/)
608 {
609  throw std::runtime_error("If you are seeing this error message then something in Bullet must have changed. Attach "
610  "a debugger and inspect the call stack to find the function in Bullet calling this "
611  "function, then review commit history to determine what change.");
612 }
613 
614 const btVector3& CastHullShape::getLocalScaling() const
615 {
616  static btVector3 out(1, 1, 1);
617  return out;
618 }
619 
620 void CastHullShape::setMargin(btScalar /*margin*/) {}
621 
622 btScalar CastHullShape::getMargin() const { return 0; }
623 
625 
626 void CastHullShape::getPreferredPenetrationDirection(int /*index*/, btVector3& /*penetrationVector*/) const
627 {
628  throw std::runtime_error("If you are seeing this error message then something in Bullet must have changed. Attach "
629  "a debugger and inspect the call stack to find the function in Bullet calling this "
630  "function, then review commit history to determine what change.");
631 }
632 
633 void CastHullShape::calculateLocalInertia(btScalar, btVector3&) const
634 {
635  throw std::runtime_error("If you are seeing this error message then something in Bullet must have changed. Attach "
636  "a debugger and inspect the call stack to find the function in Bullet calling this "
637  "function, then review commit history to determine what change.");
638 }
639 
640 void GetAverageSupport(const btConvexShape* shape, const btVector3& localNormal, btScalar& outsupport, btVector3& outpt)
641 {
642  btVector3 ptSum(0, 0, 0);
643  btScalar ptCount = 0;
644  btScalar maxSupport = -1000;
645 
646  const auto* pshape = dynamic_cast<const btPolyhedralConvexShape*>(shape);
647  if (pshape != nullptr)
648  {
649  int nPts = pshape->getNumVertices();
650 
651  for (int i = 0; i < nPts; ++i)
652  {
653  btVector3 pt;
654  pshape->getVertex(i, pt);
655 
656  btScalar sup = pt.dot(localNormal);
657  if (sup > maxSupport + BULLET_EPSILON)
658  {
659  ptCount = 1;
660  ptSum = pt;
661  maxSupport = sup;
662  }
663  else if (sup < maxSupport - BULLET_EPSILON)
664  {
665  }
666  else
667  {
668  ptCount += 1;
669  ptSum += pt;
670  }
671  }
672  outsupport = maxSupport;
673  outpt = ptSum / ptCount;
674  }
675  else
676  {
677  // The margins are set to zero for most shapes, but for a sphere the margin is used so must use
678  // localGetSupportingVertex instead of localGetSupportingVertexWithoutMargin.
679  outpt = shape->localGetSupportingVertex(localNormal); // NOLINT
680  outsupport = localNormal.dot(outpt);
681  }
682 }
683 
684 btTransform getLinkTransformFromCOW(const btCollisionObjectWrapper* cow)
685 {
686  if (cow->m_parent != nullptr)
687  {
688  if (cow->m_parent->m_parent != nullptr)
689  {
690  assert(cow->m_parent->m_parent->m_parent == nullptr);
691  return cow->m_parent->m_parent->getWorldTransform();
692  }
693 
694  return cow->m_parent->getWorldTransform();
695  }
696 
697  return cow->getWorldTransform();
698 }
699 
700 bool needsCollisionCheck(const COW& cow1,
701  const COW& cow2,
702  const std::shared_ptr<const tesseract_common::ContactAllowedValidator>& validator,
703  bool verbose)
704 {
705  return cow1.m_enabled && cow2.m_enabled && (cow2.m_collisionFilterGroup & cow1.m_collisionFilterMask) && // NOLINT
706  (cow1.m_collisionFilterGroup & cow2.m_collisionFilterMask) && // NOLINT
707  !isContactAllowed(cow1.getName(), cow2.getName(), validator, verbose);
708 }
709 
710 btScalar addDiscreteSingleResult(btManifoldPoint& cp,
711  const btCollisionObjectWrapper* colObj0Wrap,
712  int index0,
713  const btCollisionObjectWrapper* colObj1Wrap,
714  int index1,
715  ContactTestData& collisions)
716 {
717  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject()) != nullptr); // NOLINT
718  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject()) != nullptr); // NOLINT
719  const auto* cd0 = static_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject()); // NOLINT
720  const auto* cd1 = static_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject()); // NOLINT
721 
722  ObjectPairKey pc = tesseract_common::makeOrderedLinkPair(cd0->getName(), cd1->getName());
723 
724  const auto it = collisions.res->find(pc);
725  bool found = (it != collisions.res->end() && !it->second.empty());
726 
727  // size_t l = 0;
728  // if (found)
729  // {
730  // l = it->second.size();
731  // if (m_collisions.req->type == DistanceRequestType::LIMITED && l >= m_collisions.req->max_contacts_per_body)
732  // return 0;
733 
734  // }
735 
736  btTransform tf0 = getLinkTransformFromCOW(colObj0Wrap);
737  btTransform tf1 = getLinkTransformFromCOW(colObj1Wrap);
738  btTransform tf0_inv = tf0.inverse();
739  btTransform tf1_inv = tf1.inverse();
740 
741  ContactResult contact;
742  contact.link_names[0] = cd0->getName();
743  contact.link_names[1] = cd1->getName();
744 
745  if (cd0->getCollisionGeometries().size() == 1)
746  contact.shape_id[0] = 0;
747  else
748  contact.shape_id[0] = (index0 < 0) ? 0 : index0;
749 
750  if (cd1->getCollisionGeometries().size() == 1)
751  contact.shape_id[1] = 0;
752  else
753  contact.shape_id[1] = (index1 < 0) ? 0 : index1;
754 
755  contact.subshape_id[0] = colObj0Wrap->m_index;
756  contact.subshape_id[1] = colObj1Wrap->m_index;
757  contact.nearest_points[0] = convertBtToEigen(cp.m_positionWorldOnA);
758  contact.nearest_points[1] = convertBtToEigen(cp.m_positionWorldOnB);
759  contact.nearest_points_local[0] = convertBtToEigen(tf0_inv * cp.m_positionWorldOnA);
760  contact.nearest_points_local[1] = convertBtToEigen(tf1_inv * cp.m_positionWorldOnB);
761  contact.transform[0] = convertBtToEigen(tf0);
762  contact.transform[1] = convertBtToEigen(tf1);
763  contact.type_id[0] = cd0->getTypeID();
764  contact.type_id[1] = cd1->getTypeID();
765  contact.distance = static_cast<double>(cp.m_distance1);
766  contact.normal = convertBtToEigen(-1 * cp.m_normalWorldOnB);
767 
768  if (processResult(collisions, contact, pc, found) == nullptr)
769  return 0;
770 
771  return 1;
772 }
773 
775  const btCollisionObjectWrapper* cow,
776  const btVector3& pt_world,
777  const btVector3& normal_world,
778  const btTransform& link_tf_inv,
779  size_t link_index)
780 {
781  assert(dynamic_cast<const CastHullShape*>(cow->getCollisionShape()) != nullptr);
782  const auto* shape = static_cast<const CastHullShape*>(cow->getCollisionShape());
783  assert(shape != nullptr);
784 
785  // Get the start and final location of the shape
786  const btTransform& shape_tfWorld0 = cow->getWorldTransform();
787  btTransform shape_tfWorld1 = cow->getWorldTransform() * shape->m_t01;
788 
789  // Given the shapes final location calculate the links transform at the final location
790  // NOLINTNEXTLINE
791  Eigen::Isometry3d s = col->transform[link_index].inverse() * convertBtToEigen(shape_tfWorld0);
792  col->cc_transform[link_index] = convertBtToEigen(shape_tfWorld1) * s.inverse();
793 
794  // Get the normal in the local shapes coordinate system at start and final location
795  btVector3 shape_normalLocal0 = normal_world * shape_tfWorld0.getBasis();
796  btVector3 shape_normalLocal1 = normal_world * shape_tfWorld1.getBasis();
797 
798  // Calculate the contact point at the start location using the casted normal vector in thapes local coordinate system
799  btVector3 shape_ptLocal0;
800  btScalar shape_localsup0{ std::numeric_limits<btScalar>::max() };
801  GetAverageSupport(shape->m_shape, shape_normalLocal0, shape_localsup0, shape_ptLocal0);
802  btVector3 shape_ptWorld0 = shape_tfWorld0 * shape_ptLocal0;
803 
804  // Calculate the contact point at the final location using the casted normal vector in thapes local coordinate system
805  btVector3 shape_ptLocal1;
806  btScalar shape_localsup1{ std::numeric_limits<btScalar>::max() };
807  GetAverageSupport(shape->m_shape, shape_normalLocal1, shape_localsup1, shape_ptLocal1);
808  btVector3 shape_ptWorld1 = shape_tfWorld1 * shape_ptLocal1;
809 
810  btScalar shape_sup0 = normal_world.dot(shape_ptWorld0);
811  btScalar shape_sup1 = normal_world.dot(shape_ptWorld1);
812 
813  // TODO: this section is potentially problematic. think hard about the math
814  if (shape_sup0 - shape_sup1 > BULLET_SUPPORT_FUNC_TOLERANCE)
815  {
816  // LCOV_EXCL_START
817  col->cc_time[link_index] = 0;
819  // LCOV_EXCL_STOP
820  }
821  else if (shape_sup1 - shape_sup0 > BULLET_SUPPORT_FUNC_TOLERANCE)
822  {
823  // LCOV_EXCL_START
824  col->cc_time[link_index] = 1;
826  // LCOV_EXCL_STOP
827  }
828  else
829  {
830  // Given the contact point at the start and final location along with the casted contact point
831  // the time between 0 and 1 can be calculated along the path between the start and final location contact occurs.
832  btScalar l0c = (pt_world - shape_ptWorld0).length();
833  btScalar l1c = (pt_world - shape_ptWorld1).length();
834 
835  col->nearest_points_local[link_index] =
836  convertBtToEigen(link_tf_inv * (shape_tfWorld0 * ((shape_ptLocal0 + shape_ptLocal1) / 2.0)));
838 
839  if (l0c + l1c < BULLET_LENGTH_TOLERANCE)
840  {
841  col->cc_time[link_index] = .5; // LCOV_EXCL_LINE
842  }
843  else
844  {
845  col->cc_time[link_index] = static_cast<double>(l0c / (l0c + l1c));
846  }
847  }
848 }
849 
850 btScalar addCastSingleResult(btManifoldPoint& cp,
851  const btCollisionObjectWrapper* colObj0Wrap,
852  int index0,
853  const btCollisionObjectWrapper* colObj1Wrap,
854  int index1,
855  ContactTestData& collisions)
856 {
857  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject()) != nullptr); // NOLINT
858  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject()) != nullptr); // NOLINT
859  const auto* cd0 = static_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject()); // NOLINT
860  const auto* cd1 = static_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject()); // NOLINT
861 
862  const std::pair<std::string, std::string>& pc = cd0->getName() < cd1->getName() ?
863  std::make_pair(cd0->getName(), cd1->getName()) :
864  std::make_pair(cd1->getName(), cd0->getName());
865 
866  const auto it = collisions.res->find(pc);
867  bool found = (it != collisions.res->end() && !it->second.empty());
868 
869  // size_t l = 0;
870  // if (found)
871  // {
872  // l = it->second.size();
873  // if (m_collisions.req->type == DistanceRequestType::LIMITED && l >= m_collisions.req->max_contacts_per_body)
874  // return 0;
875  // }
876 
877  btTransform tf0 = getLinkTransformFromCOW(colObj0Wrap);
878  btTransform tf1 = getLinkTransformFromCOW(colObj1Wrap);
879  btTransform tf0_inv = tf0.inverse();
880  btTransform tf1_inv = tf1.inverse();
881 
882  ContactResult contact;
883  contact.link_names[0] = cd0->getName();
884  contact.link_names[1] = cd1->getName();
885 
886  if (cd0->getCollisionGeometries().size() == 1)
887  contact.shape_id[0] = 0;
888  else
889  contact.shape_id[0] = (index0 < 0) ? 0 : index0;
890 
891  if (cd1->getCollisionGeometries().size() == 1)
892  contact.shape_id[1] = 0;
893  else
894  contact.shape_id[1] = (index1 < 0) ? 0 : index1;
895 
896  contact.subshape_id[0] = colObj0Wrap->m_index;
897  contact.subshape_id[1] = colObj1Wrap->m_index;
898  contact.nearest_points[0] = convertBtToEigen(cp.m_positionWorldOnA);
899  contact.nearest_points[1] = convertBtToEigen(cp.m_positionWorldOnB);
900  contact.nearest_points_local[0] = convertBtToEigen(tf0_inv * cp.m_positionWorldOnA);
901  contact.nearest_points_local[1] = convertBtToEigen(tf1_inv * cp.m_positionWorldOnB);
902  contact.transform[0] = convertBtToEigen(tf0);
903  contact.transform[1] = convertBtToEigen(tf1);
904  contact.type_id[0] = cd0->getTypeID();
905  contact.type_id[1] = cd1->getTypeID();
906  contact.distance = static_cast<double>(cp.m_distance1);
907  contact.normal = convertBtToEigen(-1 * cp.m_normalWorldOnB);
908 
909  ContactResult* col = processResult(collisions, contact, pc, found);
910  if (col == nullptr)
911  return 0;
912 
913  if (cd0->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter &&
914  cd1->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter)
915  {
916  calculateContinuousData(col, colObj0Wrap, cp.m_positionWorldOnA, -1 * cp.m_normalWorldOnB, tf0_inv, 0);
917  calculateContinuousData(col, colObj1Wrap, cp.m_positionWorldOnB, cp.m_normalWorldOnB, tf1_inv, 1);
918  }
919  else
920  {
921  bool castShapeIsFirst = (cd0->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter);
922  btVector3 normalWorldFromCast = -(castShapeIsFirst ? 1 : -1) * cp.m_normalWorldOnB;
923  const btCollisionObjectWrapper* firstColObjWrap = (castShapeIsFirst ? colObj0Wrap : colObj1Wrap);
924  const btTransform& first_tf_inv = (castShapeIsFirst ? tf0_inv : tf1_inv);
925  const btVector3& ptOnCast = castShapeIsFirst ? cp.m_positionWorldOnA : cp.m_positionWorldOnB;
926 
927  if (castShapeIsFirst)
928  {
929  std::swap(col->nearest_points[0], col->nearest_points[1]);
930  std::swap(col->nearest_points_local[0], col->nearest_points_local[1]);
931  std::swap(col->transform[0], col->transform[1]);
932  std::swap(col->link_names[0], col->link_names[1]);
933  std::swap(col->type_id[0], col->type_id[1]);
934  std::swap(col->shape_id[0], col->shape_id[1]);
935  std::swap(col->subshape_id[0], col->subshape_id[1]);
936  col->normal *= -1;
937  }
938 
939  calculateContinuousData(col, firstColObjWrap, ptOnCast, normalWorldFromCast, first_tf_inv, 1);
940  }
941 
942  return 1;
943 }
944 
945 TesseractBridgedManifoldResult::TesseractBridgedManifoldResult(const btCollisionObjectWrapper* obj0Wrap,
946  const btCollisionObjectWrapper* obj1Wrap,
947  btCollisionWorld::ContactResultCallback& resultCallback)
948  : btManifoldResult(obj0Wrap, obj1Wrap), m_resultCallback(resultCallback)
949 {
950 }
951 
952 void TesseractBridgedManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,
953  const btVector3& pointInWorld,
954  btScalar depth)
955 {
956  bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
957  btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
958  btVector3 localA;
959  btVector3 localB;
960  if (isSwapped)
961  {
962  localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
963  localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
964  }
965  else
966  {
967  localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
968  localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
969  }
970 
971  btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth);
972  newPt.m_positionWorldOnA = pointA;
973  newPt.m_positionWorldOnB = pointInWorld;
974 
975  // BP mod, store contact triangles.
976  if (isSwapped)
977  {
978  newPt.m_partId0 = m_partId1;
979  newPt.m_partId1 = m_partId0;
980  newPt.m_index0 = m_index1;
981  newPt.m_index1 = m_index0;
982  }
983  else
984  {
985  newPt.m_partId0 = m_partId0;
986  newPt.m_partId1 = m_partId1;
987  newPt.m_index0 = m_index0;
988  newPt.m_index1 = m_index1;
989  }
990 
991  // experimental feature info, for per-triangle material etc.
992  const btCollisionObjectWrapper* obj0Wrap = isSwapped ? m_body1Wrap : m_body0Wrap;
993  const btCollisionObjectWrapper* obj1Wrap = isSwapped ? m_body0Wrap : m_body1Wrap;
994  m_resultCallback.addSingleResult(
995  newPt, obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1);
996 }
997 
999  double contact_distance,
1000  bool verbose)
1001  : collisions_(collisions), contact_distance_(contact_distance), verbose_(verbose)
1002 {
1003 }
1004 
1006  const CollisionObjectWrapper* cow1) const
1007 {
1009 }
1010 
1012  double contact_distance,
1013  bool verbose)
1014  : BroadphaseContactResultCallback(collisions, contact_distance, verbose)
1015 {
1016 }
1017 
1019  const btCollisionObjectWrapper* colObj0Wrap,
1020  int /*partId0*/,
1021  int index0,
1022  const btCollisionObjectWrapper* colObj1Wrap,
1023  int /*partId1*/,
1024  int index1)
1025 {
1026  if (cp.m_distance1 > static_cast<btScalar>(contact_distance_))
1027  return 0;
1028 
1029  return addDiscreteSingleResult(cp, colObj0Wrap, index0, colObj1Wrap, index1, collisions_);
1030 }
1031 
1033  double contact_distance,
1034  bool verbose)
1035  : BroadphaseContactResultCallback(collisions, contact_distance, verbose)
1036 {
1037 }
1038 
1040  const btCollisionObjectWrapper* colObj0Wrap,
1041  int /*partId0*/,
1042  int index0,
1043  const btCollisionObjectWrapper* colObj1Wrap,
1044  int /*partId1*/,
1045  int index1)
1046 {
1047  // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
1048  if (cp.m_distance1 > static_cast<btScalar>(contact_distance_))
1049  return 0;
1050 
1051  return addCastSingleResult(cp, colObj0Wrap, index0, colObj1Wrap, index1, collisions_);
1052 }
1053 
1055  const btCollisionObjectWrapper* obj0Wrap,
1056  const btCollisionObjectWrapper* obj1Wrap,
1057  BroadphaseContactResultCallback& result_callback)
1058  : btManifoldResult(obj0Wrap, obj1Wrap), result_callback_(result_callback)
1059 {
1060 }
1061 
1062 void TesseractBroadphaseBridgedManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,
1063  const btVector3& pointInWorld,
1064  btScalar depth)
1065 {
1066  if (result_callback_.collisions_.done || depth > static_cast<btScalar>(result_callback_.contact_distance_))
1067  return;
1068 
1069  bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
1070  btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
1071  btVector3 localA;
1072  btVector3 localB;
1073  if (isSwapped)
1074  {
1075  localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
1076  localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1077  }
1078  else
1079  {
1080  localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
1081  localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1082  }
1083 
1084  btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth);
1085  newPt.m_positionWorldOnA = pointA;
1086  newPt.m_positionWorldOnB = pointInWorld;
1087 
1088  // BP mod, store contact triangles.
1089  if (isSwapped)
1090  {
1091  newPt.m_partId0 = m_partId1;
1092  newPt.m_partId1 = m_partId0;
1093  newPt.m_index0 = m_index1;
1094  newPt.m_index1 = m_index0;
1095  }
1096  else
1097  {
1098  newPt.m_partId0 = m_partId0;
1099  newPt.m_partId1 = m_partId1;
1100  newPt.m_index0 = m_index0;
1101  newPt.m_index1 = m_index1;
1102  }
1103 
1104  // experimental feature info, for per-triangle material etc.
1105  const btCollisionObjectWrapper* obj0Wrap = isSwapped ? m_body1Wrap : m_body0Wrap;
1106  const btCollisionObjectWrapper* obj1Wrap = isSwapped ? m_body0Wrap : m_body1Wrap;
1108  newPt, obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1);
1109 }
1110 
1112  btCollisionDispatcher* dispatcher,
1113  BroadphaseContactResultCallback& results_callback)
1114  : dispatch_info_(dispatchInfo), dispatcher_(dispatcher), results_callback_(results_callback)
1115 {
1116 }
1117 
1119 {
1121  return false;
1122 
1123  const auto* cow0 = static_cast<const CollisionObjectWrapper*>(pair.m_pProxy0->m_clientObject);
1124  const auto* cow1 = static_cast<const CollisionObjectWrapper*>(pair.m_pProxy1->m_clientObject);
1125 
1126  if (results_callback_.needsCollision(cow0, cow1))
1127  {
1128  btCollisionObjectWrapper obj0Wrap(nullptr, cow0->getCollisionShape(), cow0, cow0->getWorldTransform(), -1, -1);
1129  btCollisionObjectWrapper obj1Wrap(nullptr, cow1->getCollisionShape(), cow1, cow1->getWorldTransform(), -1, -1);
1130 
1131  // dispatcher will keep algorithms persistent in the collision pair
1132  if (pair.m_algorithm == nullptr)
1133  {
1134  pair.m_algorithm = dispatcher_->findAlgorithm(&obj0Wrap, &obj1Wrap, nullptr, BT_CLOSEST_POINT_ALGORITHMS);
1135  }
1136 
1137  if (pair.m_algorithm != nullptr)
1138  {
1139  TesseractBroadphaseBridgedManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap, results_callback_);
1140  contactPointResult.m_closestPointDistanceThreshold = static_cast<btScalar>(results_callback_.contact_distance_);
1141 
1142  // discrete collision detection query
1143  pair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatch_info_, &contactPointResult);
1144  }
1145  }
1146  return false;
1147 }
1148 
1150 
1151 bool TesseractOverlapFilterCallback::needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const
1152 {
1153  // Note: We do not pass the allowed collision matrix because if it changes we do not know and this function only
1154  // gets called under certain cases and it could cause overlapping pairs to not be processed.
1155  return needsCollisionCheck(*(static_cast<CollisionObjectWrapper*>(proxy0->m_clientObject)),
1156  *(static_cast<CollisionObjectWrapper*>(proxy1->m_clientObject)),
1157  nullptr,
1158  verbose_);
1159 }
1160 
1161 COW::Ptr createCollisionObject(const std::string& name,
1162  const int& type_id,
1163  const CollisionShapesConst& shapes,
1164  const tesseract_common::VectorIsometry3d& shape_poses,
1165  bool enabled)
1166 {
1167  // dont add object that does not have geometry
1168  if (shapes.empty() || shape_poses.empty() || (shapes.size() != shape_poses.size()))
1169  {
1170  CONSOLE_BRIDGE_logDebug("ignoring link %s", name.c_str());
1171  return nullptr;
1172  }
1173 
1174  auto new_cow = std::make_shared<COW>(name, type_id, shapes, shape_poses);
1175 
1176  new_cow->m_enabled = enabled;
1177  new_cow->setContactProcessingThreshold(BULLET_DEFAULT_CONTACT_DISTANCE);
1178 
1179  CONSOLE_BRIDGE_logDebug("Created collision object for link %s", new_cow->getName().c_str());
1180  return new_cow;
1181 }
1182 
1184  COW::Ptr cow,
1185  btScalar contact_distance,
1186  bool verbose)
1187  : collisions_(collisions), cow_(std::move(cow)), contact_distance_(contact_distance), verbose_(verbose)
1188 {
1189  m_closestDistanceThreshold = contact_distance;
1190  m_collisionFilterGroup = cow_->m_collisionFilterGroup;
1191  m_collisionFilterMask = cow_->m_collisionFilterMask;
1192 }
1193 
1194 btScalar DiscreteCollisionCollector::addSingleResult(btManifoldPoint& cp,
1195  const btCollisionObjectWrapper* colObj0Wrap,
1196  int /*partId0*/,
1197  int index0,
1198  const btCollisionObjectWrapper* colObj1Wrap,
1199  int /*partId1*/,
1200  int index1)
1201 {
1202  // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
1203  if (cp.m_distance1 > static_cast<btScalar>(contact_distance_))
1204  return 0;
1205 
1206  return addDiscreteSingleResult(cp, colObj0Wrap, index0, colObj1Wrap, index1, collisions_);
1207 }
1208 
1209 bool DiscreteCollisionCollector::needsCollision(btBroadphaseProxy* proxy0) const
1210 {
1211  return !collisions_.done &&
1213  *cow_, *(static_cast<CollisionObjectWrapper*>(proxy0->m_clientObject)), collisions_.validator, verbose_);
1214 }
1215 
1217  COW::Ptr cow,
1218  double contact_distance,
1219  bool verbose)
1220  : collisions_(collisions), cow_(std::move(cow)), contact_distance_(contact_distance), verbose_(verbose)
1221 {
1222  m_closestDistanceThreshold = static_cast<btScalar>(contact_distance);
1223  m_collisionFilterGroup = cow_->m_collisionFilterGroup;
1224  m_collisionFilterMask = cow_->m_collisionFilterMask;
1225 }
1226 
1227 btScalar CastCollisionCollector::addSingleResult(btManifoldPoint& cp,
1228  const btCollisionObjectWrapper* colObj0Wrap,
1229  int /*partId0*/,
1230  int index0,
1231  const btCollisionObjectWrapper* colObj1Wrap,
1232  int /*partId1*/,
1233  int index1)
1234 {
1235  // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
1236  if (cp.m_distance1 > static_cast<btScalar>(contact_distance_))
1237  return 0;
1238 
1239  return addCastSingleResult(cp, colObj0Wrap, index0, colObj1Wrap, index1, collisions_);
1240 }
1241 
1242 bool CastCollisionCollector::needsCollision(btBroadphaseProxy* proxy0) const
1243 {
1244  return !collisions_.done &&
1246  *cow_, *(static_cast<CollisionObjectWrapper*>(proxy0->m_clientObject)), collisions_.validator, verbose_);
1247 }
1248 
1250 {
1251  COW::Ptr new_cow = cow->clone();
1252 
1253  btTransform tf;
1254  tf.setIdentity();
1255 
1256  if (btBroadphaseProxy::isConvex(new_cow->getCollisionShape()->getShapeType()))
1257  {
1258  assert(dynamic_cast<btConvexShape*>(new_cow->getCollisionShape()) != nullptr);
1259  auto* convex = static_cast<btConvexShape*>(new_cow->getCollisionShape()); // NOLINT
1260  assert(convex->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE); // This checks if the collision object is already a
1261  // cast collision object
1262 
1263  auto shape = std::make_shared<CastHullShape>(convex, tf);
1264  assert(shape != nullptr);
1265 
1266  new_cow->manage(std::make_shared<BulletCollisionShape>(shape));
1267  new_cow->setCollisionShape(shape.get());
1268  }
1269  else if (btBroadphaseProxy::isCompound(new_cow->getCollisionShape()->getShapeType()))
1270  {
1271  assert(dynamic_cast<btCompoundShape*>(new_cow->getCollisionShape()) != nullptr);
1272  auto* compound = static_cast<btCompoundShape*>(new_cow->getCollisionShape()); // NOLINT
1273  auto new_compound =
1274  std::make_shared<btCompoundShape>(BULLET_COMPOUND_USE_DYNAMIC_AABB, compound->getNumChildShapes());
1275 
1276  auto collision_shape = std::make_shared<BulletCollisionShape>();
1277  collision_shape->top_level = new_compound;
1278  collision_shape->children.reserve(static_cast<std::size_t>(compound->getNumChildShapes()));
1279  for (int i = 0; i < compound->getNumChildShapes(); ++i)
1280  {
1281  if (btBroadphaseProxy::isConvex(compound->getChildShape(i)->getShapeType()))
1282  {
1283  auto* convex = static_cast<btConvexShape*>(compound->getChildShape(i)); // NOLINT
1284  assert(convex->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE); // This checks if already a cast collision object
1285 
1286  btTransform geomTrans = compound->getChildTransform(i);
1287 
1288  auto subshape = std::make_shared<CastHullShape>(convex, tf);
1289  assert(subshape != nullptr);
1290 
1291  collision_shape->children.push_back(subshape);
1292  subshape->setMargin(BULLET_MARGIN);
1293  new_compound->addChildShape(geomTrans, subshape.get());
1294  }
1295  else if (btBroadphaseProxy::isCompound(compound->getChildShape(i)->getShapeType()))
1296  {
1297  auto* second_compound = static_cast<btCompoundShape*>(compound->getChildShape(i)); // NOLINT
1298  auto new_second_compound =
1299  std::make_shared<btCompoundShape>(BULLET_COMPOUND_USE_DYNAMIC_AABB, second_compound->getNumChildShapes());
1300 
1301  for (int j = 0; j < second_compound->getNumChildShapes(); ++j)
1302  {
1303  assert(!btBroadphaseProxy::isCompound(second_compound->getChildShape(j)->getShapeType()));
1304  assert(dynamic_cast<btConvexShape*>(second_compound->getChildShape(j)) != nullptr);
1305 
1306  auto* convex = static_cast<btConvexShape*>(second_compound->getChildShape(j)); // NOLINT
1307  assert(convex->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE); // This checks if already a cast collision object
1308 
1309  btTransform geomTrans = second_compound->getChildTransform(j);
1310 
1311  auto subshape = std::make_shared<CastHullShape>(convex, tf);
1312  assert(subshape != nullptr);
1313 
1314  collision_shape->children.push_back(subshape);
1315  subshape->setMargin(BULLET_MARGIN);
1316  new_second_compound->addChildShape(geomTrans, subshape.get());
1317  }
1318 
1319  btTransform geomTrans = compound->getChildTransform(i);
1320 
1321  collision_shape->children.push_back(new_second_compound);
1322  new_second_compound->setMargin(BULLET_MARGIN); // margin: compound. seems to
1323  // have no effect when positive
1324  // but has an effect when
1325  // negative
1326 
1327  new_compound->addChildShape(geomTrans, new_second_compound.get());
1328  }
1329  else
1330  {
1331  // LCOV_EXCL_START
1332  throw std::runtime_error("I can only collision check convex shapes and compound shapes made of convex shapes");
1333  // LCOV_EXCL_STOP
1334  }
1335  }
1336 
1337  new_compound->setMargin(BULLET_MARGIN); // margin: compound. seems to
1338  // have no effect when positive
1339  // but has an effect when
1340  // negative
1341  new_cow->manage(collision_shape);
1342  new_cow->setCollisionShape(collision_shape->top_level.get());
1343  new_cow->setWorldTransform(cow->getWorldTransform());
1344  }
1345  else
1346  {
1347  // LCOV_EXCL_START
1348  throw std::runtime_error("I can only collision check convex shapes and compound shapes made of convex shapes");
1349  // LCOV_EXCL_STOP
1350  }
1351 
1352  return new_cow;
1353 }
1354 
1356  const std::unique_ptr<btBroadphaseInterface>& broadphase,
1357  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1358 {
1359  // Calculate the aabb
1360  btVector3 aabb_min, aabb_max;
1361  cow->getAABB(aabb_min, aabb_max);
1362 
1363  // Update the broadphase aabb
1364  assert(cow->getBroadphaseHandle() != nullptr);
1365  broadphase->setAabb(cow->getBroadphaseHandle(), aabb_min, aabb_max, dispatcher.get());
1366 }
1367 
1369  const std::unique_ptr<btBroadphaseInterface>& broadphase,
1370  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1371 {
1372  btBroadphaseProxy* bp = cow->getBroadphaseHandle();
1373  if (bp != nullptr)
1374  {
1375  // only clear the cached algorithms
1376  broadphase->getOverlappingPairCache()->cleanProxyFromPairs(bp, dispatcher.get());
1377  broadphase->destroyProxy(bp, dispatcher.get());
1378  cow->setBroadphaseHandle(nullptr);
1379  }
1380 }
1381 
1383  const std::unique_ptr<btBroadphaseInterface>& broadphase,
1384  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1385 {
1386  btVector3 aabb_min, aabb_max;
1387  cow->getAABB(aabb_min, aabb_max);
1388 
1389  // Add the active collision object to the broadphase
1390  int type{ cow->getCollisionShape()->getShapeType() };
1391  cow->setBroadphaseHandle(broadphase->createProxy(
1392  aabb_min, aabb_max, type, cow.get(), cow->m_collisionFilterGroup, cow->m_collisionFilterMask, dispatcher.get()));
1393 }
1394 
1395 void updateCollisionObjectFilters(const std::vector<std::string>& active,
1396  const COW::Ptr& cow,
1397  const std::unique_ptr<btBroadphaseInterface>& broadphase,
1398  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1399 {
1400  updateCollisionObjectFilters(active, cow);
1401 
1402  // Need to clean the proxy from broadphase cache so BroadPhaseFilter gets called again.
1403  // The BroadPhaseFilter only gets called once, so if you change when two objects can be in collision, like filters
1404  // this must be called or contacts between shapes will be missed.
1405  broadphase->getOverlappingPairCache()->cleanProxyFromPairs(cow->getBroadphaseHandle(), dispatcher.get());
1406 }
1407 
1409  const std::unique_ptr<btBroadphaseInterface>& broadphase,
1410  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1411 {
1412  if (cow->getBroadphaseHandle() != nullptr)
1413  {
1414  broadphase->destroyProxy(cow->getBroadphaseHandle(), dispatcher.get());
1415 
1416  btVector3 aabb_min, aabb_max;
1417  cow->getAABB(aabb_min, aabb_max);
1418 
1419  // Add the active collision object to the broadphase
1420  int type{ cow->getCollisionShape()->getShapeType() };
1421  cow->setBroadphaseHandle(broadphase->createProxy(aabb_min,
1422  aabb_max,
1423  type,
1424  cow.get(),
1425  cow->m_collisionFilterGroup,
1426  cow->m_collisionFilterMask,
1427  dispatcher.get()));
1428  }
1429 }
1430 } // namespace tesseract_collision::tesseract_collision_bullet
tesseract_common::VectorIsometry3d
AlignedVector< Eigen::Isometry3d > VectorIsometry3d
tesseract_collision::tesseract_collision_bullet::CastBroadphaseContactResultCallback::CastBroadphaseContactResultCallback
CastBroadphaseContactResultCallback(ContactTestData &collisions, double contact_distance, bool verbose=false)
Definition: bullet_utils.cpp:1032
tesseract_collision::tesseract_collision_bullet::CastHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin
void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const override
Definition: bullet_utils.cpp:591
tesseract_collision::tesseract_collision_bullet::TesseractBroadphaseBridgedManifoldResult::result_callback_
BroadphaseContactResultCallback & result_callback_
Definition: bullet_utils.h:317
tesseract_collision::tesseract_collision_bullet::TesseractBridgedManifoldResult::TesseractBridgedManifoldResult
TesseractBridgedManifoldResult(const btCollisionObjectWrapper *obj0Wrap, const btCollisionObjectWrapper *obj1Wrap, btCollisionWorld::ContactResultCallback &resultCallback)
Definition: bullet_utils.cpp:945
tesseract_collision::ContactResultMap::end
ConstIteratorType end() const
returns an iterator to the end
Definition: types.cpp:260
tesseract_geometry::Box::ConstPtr
std::shared_ptr< const Box > ConstPtr
tesseract_collision::tesseract_collision_bullet
Definition: bullet_cast_bvh_manager.h:48
tesseract_collision::tesseract_collision_bullet::CastHullShape::localGetSupportingVertexWithoutMargin
btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &v) const override
Definition: bullet_utils.cpp:584
tesseract_collision::ContactTestData
This data is intended only to be used internal to the collision checkers as a container and should no...
Definition: types.h:328
tesseract_collision::isContactAllowed
bool isContactAllowed(const std::string &name1, const std::string &name2, const std::shared_ptr< const tesseract_common::ContactAllowedValidator > &validator, bool verbose=false)
Determine if contact is allowed between two objects.
Definition: common.cpp:85
tesseract_geometry::GeometryType::COMPOUND_MESH
@ COMPOUND_MESH
tesseract_geometry::GeometryType::CONE
@ CONE
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::contact_distance_
double contact_distance_
Definition: bullet_utils.h:388
tesseract_collision::ContactResult::cc_time
std::array< double, 2 > cc_time
This is between 0 and 1 indicating the point of contact.
Definition: types.h:111
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::manageReserve
void manageReserve(std::size_t s)
Definition: bullet_utils.cpp:558
tesseract_collision::ContactTestData::done
bool done
Indicate if search is finished.
Definition: types.h:355
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback::BroadphaseContactResultCallback
BroadphaseContactResultCallback(ContactTestData &collisions, double contact_distance, bool verbose=false)
Definition: bullet_utils.cpp:998
OcTreeBaseImpl< OcTreeNode, AbstractOccupancyOcTree >::size
virtual size_t size() const
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::getCollisionGeometriesTransforms
const tesseract_common::VectorIsometry3d & getCollisionGeometriesTransforms() const
Definition: bullet_utils.cpp:525
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::getAABB
void getAABB(btVector3 &aabb_min, btVector3 &aabb_max) const
Get the collision objects axis aligned bounding box.
Definition: bullet_utils.cpp:530
tesseract_collision::ContactResult::shape_id
std::array< int, 2 > shape_id
The two shapes that are in contact. Each link can be made up of multiple shapes.
Definition: types.h:94
tesseract_collision::tesseract_collision_bullet::CastHullShape::setLocalScaling
void setLocalScaling(const btVector3 &scaling) override
Definition: bullet_utils.cpp:607
tesseract_collision::tesseract_collision_bullet::CastBroadphaseContactResultCallback::addSingleResult
btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) override
Definition: bullet_utils.cpp:1039
tesseract_collision::tesseract_collision_bullet::addCastSingleResult
btScalar addCastSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int index0, const btCollisionObjectWrapper *colObj1Wrap, int index1, ContactTestData &collisions)
Definition: bullet_utils.cpp:850
tesseract_collision::tesseract_collision_bullet::CastHullShape
This is a casted collision shape used for checking if an object is collision free between two transfo...
Definition: bullet_utils.h:155
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::needsCollision
bool needsCollision(btBroadphaseProxy *proxy0) const override
Definition: bullet_utils.cpp:1242
octomap::AbstractOccupancyOcTree::getOccupancyThres
double getOccupancyThres() const
tesseract_collision::isLinkActive
bool isLinkActive(const std::vector< std::string > &active, const std::string &name)
This will check if a link is active provided a list. If the list is empty the link is considered acti...
Definition: common.cpp:80
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_collisionFilterGroup
short int m_collisionFilterGroup
Definition: bullet_utils.h:105
tesseract_geometry::OctreeSubType::SPHERE_OUTSIDE
@ SPHERE_OUTSIDE
tesseract_collision::tesseract_collision_bullet::BULLET_EPSILON
const btScalar BULLET_EPSILON
Definition: bullet_utils.h:65
tesseract_collision::tesseract_collision_bullet::CastHullShape::calculateLocalInertia
void calculateLocalInertia(btScalar, btVector3 &) const override
Definition: bullet_utils.cpp:633
tesseract_collision::tesseract_collision_fcl::StaticFilter
@ StaticFilter
Definition: fcl_utils.h:68
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_shapes
CollisionShapesConst m_shapes
The shapes poses information.
Definition: bullet_utils.h:143
tesseract_collision::tesseract_collision_bullet::updateBroadphaseAABB
void updateBroadphaseAABB(const COW::Ptr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Update the Broadphase AABB for the input collision object.
Definition: bullet_utils.cpp:1355
tesseract_collision::ContactResult::normal
Eigen::Vector3d normal
The normal vector to move the two objects out of contact in world coordinates.
Definition: types.h:109
tesseract_collision::ContinuousCollisionType::CCType_Time1
@ CCType_Time1
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::cow_
const COW::Ptr cow_
Definition: bullet_utils.h:410
tesseract_collision::ContactTestData::validator
std::shared_ptr< const tesseract_common::ContactAllowedValidator > validator
The allowed collision function used to check if two links should be excluded from collision checking.
Definition: types.h:346
tesseract_collision::tesseract_collision_bullet::createCollisionObject
COW::Ptr createCollisionObject(const std::string &name, const int &type_id, const CollisionShapesConst &shapes, const tesseract_common::VectorIsometry3d &shape_poses, bool enabled=true)
Definition: bullet_utils.cpp:1161
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
tesseract_collision::tesseract_collision_bullet::BULLET_COMPOUND_USE_DYNAMIC_AABB
const bool BULLET_COMPOUND_USE_DYNAMIC_AABB
Definition: bullet_utils.h:67
tesseract_geometry::GeometryType::MESH
@ MESH
tesseract_collision::tesseract_collision_bullet::CastHullShape::getMargin
btScalar getMargin() const override
Definition: bullet_utils.cpp:622
tesseract_collision::tesseract_collision_bullet::TesseractBroadphaseBridgedManifoldResult
Definition: bullet_utils.h:315
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::collisions_
ContactTestData & collisions_
Definition: bullet_utils.h:386
tesseract_collision::tesseract_collision_bullet::createShapePrimitive
std::shared_ptr< BulletCollisionShape > createShapePrimitive(const CollisionShapeConstPtr &geom)
Create a bullet collision shape from tesseract collision shape.
Definition: bullet_utils.cpp:366
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback::collisions_
ContactTestData & collisions_
Definition: bullet_utils.h:266
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback::needsCollision
virtual bool needsCollision(const CollisionObjectWrapper *cow0, const CollisionObjectWrapper *cow1) const
Definition: bullet_utils.cpp:1005
tesseract_geometry::GeometryType::CYLINDER
@ CYLINDER
tesseract_geometry::CompoundMesh::ConstPtr
std::shared_ptr< const CompoundMesh > ConstPtr
tesseract_geometry::Sphere::ConstPtr
std::shared_ptr< const Sphere > ConstPtr
tesseract_collision::tesseract_collision_bullet::makeCastCollisionObject
COW::Ptr makeCastCollisionObject(const COW::Ptr &cow)
Definition: bullet_utils.cpp:1249
tesseract_geometry::Cone::ConstPtr
std::shared_ptr< const Cone > ConstPtr
geometries.h
tesseract_collision::tesseract_collision_bullet::addCollisionObjectToBroadphase
void addCollisionObjectToBroadphase(const COW::Ptr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Add the collision object to broadphase.
Definition: bullet_utils.cpp:1382
tesseract_collision::tesseract_collision_bullet::TesseractBridgedManifoldResult::m_resultCallback
btCollisionWorld::ContactResultCallback & m_resultCallback
Definition: bullet_utils.h:254
octomap::OcTree
tesseract_collision::tesseract_collision_bullet::CastHullShape::getAabbSlow
void getAabbSlow(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const override
Definition: bullet_utils.cpp:600
tesseract_collision::ContinuousCollisionType::CCType_Between
@ CCType_Between
tesseract_collision::tesseract_collision_bullet::CastHullShape::localGetSupportingVertex
btVector3 localGetSupportingVertex(const btVector3 &vec) const override
Definition: bullet_utils.cpp:566
tesseract_collision::tesseract_collision_bullet::TesseractCollisionPairCallback::dispatcher_
btCollisionDispatcher * dispatcher_
Definition: bullet_utils.h:335
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::collisions_
ContactTestData & collisions_
Definition: bullet_utils.h:409
tesseract_collision::tesseract_collision_bullet::needsCollisionCheck
bool needsCollisionCheck(const COW &cow1, const COW &cow2, const std::shared_ptr< const tesseract_common::ContactAllowedValidator > &validator, bool verbose=false)
This is used to check if a collision check is required between the provided two collision objects.
Definition: bullet_utils.cpp:700
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_name
std::string m_name
The name of the collision object.
Definition: bullet_utils.h:139
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::getTypeID
const int & getTypeID() const
Get a user defined type.
Definition: bullet_utils.cpp:510
tesseract_collision::tesseract_collision_bullet::addDiscreteSingleResult
btScalar addDiscreteSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, const btCollisionObjectWrapper *colObj1Wrap, ContactTestData &collisions)
tesseract_collision::tesseract_collision_bullet::calculateContinuousData
void calculateContinuousData(ContactResult *col, const btCollisionObjectWrapper *cow, const btVector3 &pt_world, const btVector3 &normal_world, const btTransform &link_tf_inv, size_t link_index)
Calculate the continuous contact data for casted collision shape.
Definition: bullet_utils.cpp:774
tesseract_collision::tesseract_collision_bullet::removeCollisionObjectFromBroadphase
void removeCollisionObjectFromBroadphase(const COW::Ptr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Remove the collision object from broadphase.
Definition: bullet_utils.cpp:1368
tesseract_collision::tesseract_collision_bullet::BULLET_LENGTH_TOLERANCE
const btScalar BULLET_LENGTH_TOLERANCE
Definition: bullet_utils.h:64
name
std::string name
tesseract_collision::ContactResult::subshape_id
std::array< int, 2 > subshape_id
Some shapes like octomap and mesh have subshape (boxes and triangles)
Definition: types.h:96
tesseract_collision::tesseract_collision_bullet::TesseractBridgedManifoldResult::addContactPoint
void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth) override
Definition: bullet_utils.cpp:952
tesseract_collision::tesseract_collision_bullet::BULLET_MARGIN
const btScalar BULLET_MARGIN
Definition: bullet_utils.h:62
tesseract_collision::ObjectPairKey
std::pair< std::string, std::string > ObjectPairKey
Definition: common.h:40
tesseract_collision::tesseract_collision_bullet::convertBtToEigen
Eigen::Vector3d convertBtToEigen(const btVector3 &v)
Definition: bullet_utils.cpp:67
tesseract_collision::tesseract_collision_bullet::CastHullShape::getPreferredPenetrationDirection
void getPreferredPenetrationDirection(int index, btVector3 &penetrationVector) const override
Definition: bullet_utils.cpp:626
tesseract_collision::tesseract_collision_bullet::DiscreteBroadphaseContactResultCallback::DiscreteBroadphaseContactResultCallback
DiscreteBroadphaseContactResultCallback(ContactTestData &collisions, double contact_distance, bool verbose=false)
Definition: bullet_utils.cpp:1011
tesseract_collision::tesseract_collision_bullet::GetAverageSupport
void GetAverageSupport(const btConvexShape *shape, const btVector3 &localNormal, btScalar &outsupport, btVector3 &outpt)
Definition: bullet_utils.cpp:640
tesseract_collision::tesseract_collision_bullet::TesseractCollisionPairCallback::results_callback_
BroadphaseContactResultCallback & results_callback_
Definition: bullet_utils.h:336
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::getCollisionGeometries
const CollisionShapesConst & getCollisionGeometries() const
Definition: bullet_utils.cpp:523
tesseract_collision::tesseract_collision_bullet::CastHullShape::getAabb
void getAabb(const btTransform &t_w0, btVector3 &aabbMin, btVector3 &aabbMax) const override
getAabb's default implementation is brute force, expected derived classes to implement a fast dedicat...
Definition: bullet_utils.cpp:574
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::Ptr
std::shared_ptr< CollisionObjectWrapper > Ptr
Definition: bullet_utils.h:96
tesseract_geometry::Mesh::ConstPtr
std::shared_ptr< const Mesh > ConstPtr
tesseract_collision::tesseract_collision_fcl::KinematicFilter
@ KinematicFilter
Definition: fcl_utils.h:69
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::addSingleResult
btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) override
Definition: bullet_utils.cpp:1227
tesseract_collision::tesseract_collision_bullet::TesseractOverlapFilterCallback::needBroadphaseCollision
bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const override
Definition: bullet_utils.cpp:1151
bullet_utils.h
Tesseract ROS Bullet environment utility function.
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper
This is a tesseract bullet collsion object.
Definition: bullet_utils.h:89
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::contact_distance_
double contact_distance_
Definition: bullet_utils.h:411
tesseract_collision::tesseract_collision_bullet::TesseractOverlapFilterCallback::TesseractOverlapFilterCallback
TesseractOverlapFilterCallback(bool verbose=false)
Definition: bullet_utils.cpp:1149
tesseract_geometry::GeometryType::SPHERE
@ SPHERE
tesseract_common::VectorVector3d
std::vector< Eigen::Vector3d > VectorVector3d
tesseract_collision::tesseract_collision_bullet::refreshBroadphaseProxy
void refreshBroadphaseProxy(const COW::Ptr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Refresh the broadphase data structure.
Definition: bullet_utils.cpp:1408
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback::addSingleResult
virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)=0
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_data
std::vector< std::shared_ptr< BulletCollisionShape > > m_data
This manages the collision shape pointer so they get destroyed.
Definition: bullet_utils.h:147
tesseract_collision::tesseract_collision_bullet::CastHullShape::m_t01
btTransform m_t01
Definition: bullet_utils.h:159
tesseract_geometry::GeometryType::CAPSULE
@ CAPSULE
tesseract_collision::CollisionShapesConst
std::vector< CollisionShapeConstPtr > CollisionShapesConst
Definition: types.h:51
tesseract_collision::tesseract_collision_bullet::CastHullShape::getLocalScaling
const btVector3 & getLocalScaling() const override
Definition: bullet_utils.cpp:614
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::clone
std::shared_ptr< CollisionObjectWrapper > clone()
This clones the collision objects but not the collision shape wich is const.
Definition: bullet_utils.cpp:539
OcTreeBaseImpl< OcTreeNode, AbstractOccupancyOcTree >::begin
iterator begin(unsigned char maxDepth=0) const
tesseract_collision::ContactResult::type_id
std::array< int, 2 > type_id
A user defined type id that is added to the contact shapes.
Definition: types.h:90
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::verbose_
bool verbose_
Definition: bullet_utils.h:389
r
S r
TESSERACT_COMMON_IGNORE_WARNINGS_POP
Definition: create_convex_hull.cpp:37
tesseract_collision::ContactTestData::res
ContactResultMap * res
Distance query results information.
Definition: types.h:352
bullet_collision_shape_cache.h
This is a static cache mapping tesseract geometry shared pointers to bullet collision shapes to avoid...
tesseract_collision::tesseract_collision_bullet::TesseractCollisionPairCallback::dispatch_info_
const btDispatcherInfo & dispatch_info_
Definition: bullet_utils.h:334
tesseract_collision::tesseract_collision_bullet::TesseractOverlapFilterCallback::verbose_
bool verbose_
Definition: bullet_utils.h:361
tesseract_collision::ContinuousCollisionType::CCType_Time0
@ CCType_Time0
tesseract_geometry::Octree::ConstPtr
std::shared_ptr< const Octree > ConstPtr
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::addSingleResult
btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) override
Definition: bullet_utils.cpp:1194
tesseract_collision::tesseract_collision_bullet::TesseractCollisionPairCallback::processOverlap
bool processOverlap(btBroadphasePair &pair) override
Definition: bullet_utils.cpp:1118
tesseract_collision::tesseract_collision_bullet::BulletCollisionShapeCache::insert
static void insert(const std::shared_ptr< const tesseract_geometry::Geometry > &key, const std::shared_ptr< BulletCollisionShape > &value)
Insert a new entry into the cache.
Definition: bullet_collision_shape_cache.cpp:45
tesseract_collision::tesseract_collision_bullet::BULLET_SUPPORT_FUNC_TOLERANCE
const btScalar BULLET_SUPPORT_FUNC_TOLERANCE
Definition: bullet_utils.h:63
tesseract_collision::tesseract_collision_bullet::CastHullShape::getName
const char * getName() const override
Definition: bullet_utils.cpp:583
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_collisionFilterMask
short int m_collisionFilterMask
Definition: bullet_utils.h:106
tesseract_collision::tesseract_collision_bullet::CastHullShape::CastHullShape
CastHullShape(btConvexShape *shape, const btTransform &t01)
Definition: bullet_utils.cpp:560
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_type_id
int m_type_id
A user defined type id.
Definition: bullet_utils.h:141
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::CastCollisionCollector
CastCollisionCollector(ContactTestData &collisions, COW::Ptr cow, double contact_distance, bool verbose=false)
Definition: bullet_utils.cpp:1216
tesseract_collision::tesseract_collision_bullet::DiscreteBroadphaseContactResultCallback::addSingleResult
btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) override
Definition: bullet_utils.cpp:1018
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_shape_poses
tesseract_common::VectorIsometry3d m_shape_poses
Definition: bullet_utils.h:145
tesseract_collision::ContactResultMap::find
ConstIteratorType find(const KeyType &key) const
Definition: types.cpp:268
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::m_enabled
bool m_enabled
Definition: bullet_utils.h:107
tesseract_collision::ContactResult::distance
EIGEN_MAKE_ALIGNED_OPERATOR_NEW double distance
The distance between two links.
Definition: types.h:88
type
type
tesseract_collision::ContactResult::cc_transform
std::array< Eigen::Isometry3d, 2 > cc_transform
The transform of link in world coordinates at its desired final location. Note: This is not the locat...
Definition: types.h:120
tesseract_collision::CollisionShapeConstPtr
std::shared_ptr< const tesseract_geometry::Geometry > CollisionShapeConstPtr
Definition: types.h:49
tesseract_collision::tesseract_collision_bullet::CastHullShape::setMargin
void setMargin(btScalar margin) override
Definition: bullet_utils.cpp:620
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback::verbose_
bool verbose_
Definition: bullet_utils.h:268
tesseract_geometry::GeometryType::BOX
@ BOX
tesseract_geometry::ConvexMesh::ConstPtr
std::shared_ptr< const ConvexMesh > ConstPtr
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::needsCollision
bool needsCollision(btBroadphaseProxy *proxy0) const override
Definition: bullet_utils.cpp:1209
OcTreeBaseImpl< OcTreeNode, AbstractOccupancyOcTree >::end
const iterator end() const
tesseract_collision::tesseract_collision_bullet::BulletCollisionShapeCache::get
static std::shared_ptr< BulletCollisionShape > get(const std::shared_ptr< const tesseract_geometry::Geometry > &key)
Retrieve the cache entry by key.
Definition: bullet_collision_shape_cache.cpp:54
octomap.h
tesseract_common::makeOrderedLinkPair
LinkNamesPair makeOrderedLinkPair(const std::string &link_name1, const std::string &link_name2)
tesseract_collision::ContactResult::transform
std::array< Eigen::Isometry3d, 2 > transform
The transform of link in world coordinates.
Definition: types.h:102
tesseract_geometry::GeometryType::OCTREE
@ OCTREE
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback
The BroadphaseContactResultCallback is used to report contact points.
Definition: bullet_utils.h:264
tesseract_collision::tesseract_collision_bullet::CastHullShape::m_shape
btConvexShape * m_shape
Definition: bullet_utils.h:158
tesseract_collision::tesseract_collision_bullet::TesseractCollisionPairCallback::TesseractCollisionPairCallback
TesseractCollisionPairCallback(const btDispatcherInfo &dispatchInfo, btCollisionDispatcher *dispatcher, BroadphaseContactResultCallback &results_callback)
Definition: bullet_utils.cpp:1111
tesseract_collision::tesseract_collision_bullet::CastHullShape::getNumPreferredPenetrationDirections
int getNumPreferredPenetrationDirections() const override
Definition: bullet_utils.cpp:624
tesseract_collision::tesseract_collision_bullet::BULLET_DEFAULT_CONTACT_DISTANCE
const btScalar BULLET_DEFAULT_CONTACT_DISTANCE
Definition: bullet_utils.h:66
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::cow_
const COW::Ptr cow_
Definition: bullet_utils.h:387
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::CollisionObjectWrapper
CollisionObjectWrapper()=default
tesseract_collision::ContactResult::nearest_points
std::array< Eigen::Vector3d, 2 > nearest_points
The nearest point on both links in world coordinates.
Definition: types.h:98
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::sameObject
bool sameObject(const CollisionObjectWrapper &other) const
Check if two CollisionObjectWrapper objects point to the same source object.
Definition: bullet_utils.cpp:512
tesseract_geometry::GeometryType::CONVEX_MESH
@ CONVEX_MESH
tesseract_geometry::Cylinder::ConstPtr
std::shared_ptr< const Cylinder > ConstPtr
tesseract_collision::ContactResult::nearest_points_local
std::array< Eigen::Vector3d, 2 > nearest_points_local
The nearest point on both links in local(link) coordinates.
Definition: types.h:100
tesseract_collision::tesseract_collision_bullet::convertEigenToBt
btVector3 convertEigenToBt(const Eigen::Vector3d &v)
Definition: bullet_utils.cpp:62
tesseract_collision::processResult
ContactResult * processResult(ContactTestData &cdata, ContactResult &contact, const std::pair< std::string, std::string > &key, bool found)
processResult Processes the ContactResult based on the information in the ContactTestData
Definition: common.cpp:112
tesseract_collision::tesseract_collision_bullet::updateCollisionObjectFilters
void updateCollisionObjectFilters(const std::vector< std::string > &active, const COW::Ptr &cow)
Update a collision objects filters.
Definition: bullet_utils.cpp:442
tesseract_collision::tesseract_collision_bullet::BroadphaseContactResultCallback::contact_distance_
double contact_distance_
Definition: bullet_utils.h:267
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::getName
const std::string & getName() const
Get the collision object name.
Definition: bullet_utils.cpp:508
tesseract_collision::ContactResult::link_names
std::array< std::string, 2 > link_names
The two links that are in contact.
Definition: types.h:92
tesseract_collision::tesseract_collision_bullet::DiscreteCollisionCollector::DiscreteCollisionCollector
DiscreteCollisionCollector(ContactTestData &collisions, COW::Ptr cow, btScalar contact_distance, bool verbose=false)
Definition: bullet_utils.cpp:1183
tesseract_collision::ContactResult
Definition: types.h:81
tesseract_collision::tesseract_collision_bullet::CastHullShape::updateCastTransform
void updateCastTransform(const btTransform &t01)
Definition: bullet_utils.cpp:565
tesseract_collision::tesseract_collision_bullet::getLinkTransformFromCOW
btTransform getLinkTransformFromCOW(const btCollisionObjectWrapper *cow)
This transversus the parent tree to find the base object and return its world transform This should b...
Definition: bullet_utils.cpp:684
tesseract_geometry::Capsule::ConstPtr
std::shared_ptr< const Capsule > ConstPtr
tesseract_collision::tesseract_collision_bullet::TesseractBroadphaseBridgedManifoldResult::addContactPoint
void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth) override
Definition: bullet_utils.cpp:1062
tesseract_geometry::OctreeSubType::BOX
@ BOX
tesseract_collision::tesseract_collision_bullet::CollisionObjectWrapper::manage
void manage(const std::shared_ptr< BulletCollisionShape > &t)
Definition: bullet_utils.cpp:556
tesseract_collision::ContactResult::cc_type
std::array< ContinuousCollisionType, 2 > cc_type
The type of continuous contact.
Definition: types.h:113
tesseract_collision::tesseract_collision_bullet::CastCollisionCollector::verbose_
bool verbose_
Definition: bullet_utils.h:412
tesseract_collision::tesseract_collision_bullet::TesseractBroadphaseBridgedManifoldResult::TesseractBroadphaseBridgedManifoldResult
TesseractBroadphaseBridgedManifoldResult(const btCollisionObjectWrapper *obj0Wrap, const btCollisionObjectWrapper *obj1Wrap, BroadphaseContactResultCallback &result_callback)
Definition: bullet_utils.cpp:1054
tesseract_geometry::OctreeSubType::SPHERE_INSIDE
@ SPHERE_INSIDE
verbose
bool verbose
OcTreeBaseImpl< OcTreeNode, AbstractOccupancyOcTree >::getTreeDepth
unsigned int getTreeDepth() const


tesseract_collision
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:01:52