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>
64 return btVector3{
static_cast<btScalar
>(v[0]),
static_cast<btScalar
>(v[1]),
static_cast<btScalar
>(v[2]) };
69 return Eigen::Vector3d{
static_cast<double>(v.x()),
static_cast<double>(v.y()),
static_cast<double>(v.z()) };
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()) };
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)) };
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]);
98 const Eigen::Matrix3d& rot = t.matrix().block<3, 3>(0, 0);
99 const Eigen::Vector3d& tran = t.translation();
106 Eigen::Isometry3d i = Eigen::Isometry3d::Identity();
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);
119 return std::make_shared<BulletCollisionShape>(std::make_shared<btBoxShape>(btVector3(a, b, c)));
124 return std::make_shared<BulletCollisionShape>(
125 std::make_shared<btSphereShape>(
static_cast<btScalar
>(geom->getRadius())));
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)));
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));
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));
151 int vertice_count = geom->getVertexCount();
152 int triangle_count = geom->getFaceCount();
154 const Eigen::VectorXi& triangles = *(geom->getFaces());
156 auto collision_shape = std::make_shared<BulletCollisionShape>();
157 if (vertice_count > 0 && triangle_count > 0)
164 collision_shape->children.reserve(
static_cast<std::size_t
>(triangle_count));
165 for (
int i = 0; i < triangle_count; ++i)
168 assert(triangles[4L * i] == 3);
169 for (
unsigned x = 0; x < 3; ++x)
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]);
177 std::shared_ptr<btCollisionShape> subshape = std::make_shared<btTriangleShapeEx>(v[0], v[1], v[2]);
178 if (subshape !=
nullptr)
180 collision_shape->children.push_back(subshape);
182 btTransform geomTrans;
183 geomTrans.setIdentity();
184 compound->addChildShape(geomTrans, subshape.get());
187 collision_shape->top_level = compound;
188 return collision_shape;
190 CONSOLE_BRIDGE_logError(
"The mesh is empty!");
196 int vertice_count = geom->getVertexCount();
197 int triangle_count = geom->getFaceCount();
200 if (vertice_count > 0 && triangle_count > 0)
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])));
207 return std::make_shared<BulletCollisionShape>(convex_hull_shape);
209 CONSOLE_BRIDGE_logError(
"The mesh is empty!");
219 std::vector<std::shared_ptr<btCollisionShape>> managed_shapes;
221 switch (geom->getSubType())
225 for (
auto it = octree.
begin(
static_cast<unsigned char>(octree.
getTreeDepth())), end = octree.
end(); it != end;
228 if (it->getOccupancy() >= occupancy_threshold)
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);
237 std::shared_ptr<btCollisionShape> childshape = managed_shapes.at(it.getDepth());
238 if (childshape ==
nullptr)
240 childshape = std::make_shared<btBoxShape>(btVector3(length, length, length));
242 managed_shapes.at(it.getDepth()) = childshape;
245 subshape->addChildShape(geomTrans, childshape.get());
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)
254 if (managed_shape !=
nullptr)
255 collision_shape->children.push_back(managed_shape);
258 return collision_shape;
262 for (
auto it = octree.
begin(
static_cast<unsigned char>(octree.
getTreeDepth())), end = octree.
end(); it != end;
265 if (it->getOccupancy() >= occupancy_threshold)
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())));
273 std::shared_ptr<btCollisionShape> childshape = managed_shapes.at(it.getDepth());
274 if (childshape ==
nullptr)
276 childshape = std::make_shared<btSphereShape>(
static_cast<btScalar
>((size / 2)));
278 managed_shapes.at(it.getDepth()) = childshape;
281 subshape->addChildShape(geomTrans, childshape.get());
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)
290 if (managed_shape !=
nullptr)
291 collision_shape->children.push_back(managed_shape);
294 return collision_shape;
298 for (
auto it = octree.
begin(
static_cast<unsigned char>(octree.
getTreeDepth())), end = octree.
end(); it != end;
301 if (it->getOccupancy() >= occupancy_threshold)
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())));
309 std::shared_ptr<btCollisionShape> childshape = managed_shapes.at(it.getDepth());
310 if (childshape ==
nullptr)
313 std::make_shared<btSphereShape>(
static_cast<btScalar
>(std::sqrt(2 * ((size / 2) * (size / 2)))));
315 managed_shapes.at(it.getDepth()) = childshape;
318 subshape->addChildShape(geomTrans, childshape.get());
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)
327 if (managed_shape !=
nullptr)
328 collision_shape->children.push_back(managed_shape);
331 return collision_shape;
335 CONSOLE_BRIDGE_logError(
"This bullet shape type (%d) is not supported for geometry octree",
336 static_cast<int>(geom->getSubType()));
342 const auto& meshes = geom->getMeshes();
349 auto shape = std::make_shared<BulletCollisionShape>(compound_mesh);
352 for (
const auto& mesh : meshes)
355 if (subshape !=
nullptr)
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());
369 if (shape !=
nullptr)
372 switch (geom->getType())
388 shape =
createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Cylinder>(geom));
400 shape =
createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Capsule>(geom));
412 shape =
createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::ConvexMesh>(geom));
424 shape =
createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::CompoundMesh>(geom));
431 CONSOLE_BRIDGE_logError(
"This geometric shape type (%d) is not supported using BULLET yet",
432 static_cast<int>(geom->getType()));
465 : m_name(std::move(
name)), m_type_id(type_id), m_shapes(std::move(shapes)), m_shape_poses(std::move(shape_poses))
479 setCollisionShape(shape->top_level.get());
485 manage(std::make_shared<BulletCollisionShape>(compound));
489 setCollisionShape(compound.get());
491 for (std::size_t j = 0; j <
m_shapes.size(); ++j)
494 if (subshape !=
nullptr)
498 compound->addChildShape(geomTrans, subshape->top_level.get());
505 setWorldTransform(trans);
520 [](
const Eigen::Isometry3d& t1,
const Eigen::Isometry3d& t2) { return t1.isApprox(t2); });
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;
541 auto clone_cow = std::make_shared<CollisionObjectWrapper>();
542 clone_cow->m_name =
m_name;
546 clone_cow->m_data =
m_data;
547 clone_cow->setCollisionShape(getCollisionShape());
548 clone_cow->setWorldTransform(getWorldTransform());
552 clone_cow->setBroadphaseHandle(
nullptr);
562 m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
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;
576 m_shape->getAabb(t_w0, aabbMin, aabbMax);
577 btVector3 min1, max1;
579 aabbMin.setMin(min1);
580 aabbMax.setMax(max1);
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.");
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.");
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.");
616 static btVector3 out(1, 1, 1);
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.");
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.");
640 void GetAverageSupport(
const btConvexShape* shape,
const btVector3& localNormal, btScalar& outsupport, btVector3& outpt)
642 btVector3 ptSum(0, 0, 0);
643 btScalar ptCount = 0;
644 btScalar maxSupport = -1000;
646 const auto* pshape =
dynamic_cast<const btPolyhedralConvexShape*
>(shape);
647 if (pshape !=
nullptr)
649 int nPts = pshape->getNumVertices();
651 for (
int i = 0; i < nPts; ++i)
654 pshape->getVertex(i, pt);
656 btScalar sup = pt.dot(localNormal);
672 outsupport = maxSupport;
673 outpt = ptSum / ptCount;
679 outpt = shape->localGetSupportingVertex(localNormal);
680 outsupport = localNormal.dot(outpt);
686 if (cow->m_parent !=
nullptr)
688 if (cow->m_parent->m_parent !=
nullptr)
690 assert(cow->m_parent->m_parent->m_parent ==
nullptr);
691 return cow->m_parent->m_parent->getWorldTransform();
694 return cow->m_parent->getWorldTransform();
697 return cow->getWorldTransform();
702 const std::shared_ptr<const tesseract_common::ContactAllowedValidator>& validator,
711 const btCollisionObjectWrapper* colObj0Wrap,
713 const btCollisionObjectWrapper* colObj1Wrap,
724 const auto it = collisions.
res->
find(pc);
725 bool found = (it != collisions.
res->
end() && !it->second.empty());
738 btTransform tf0_inv = tf0.inverse();
739 btTransform tf1_inv = tf1.inverse();
745 if (cd0->getCollisionGeometries().size() == 1)
748 contact.
shape_id[0] = (index0 < 0) ? 0 : index0;
750 if (cd1->getCollisionGeometries().size() == 1)
753 contact.
shape_id[1] = (index1 < 0) ? 0 : index1;
763 contact.
type_id[0] = cd0->getTypeID();
764 contact.
type_id[1] = cd1->getTypeID();
765 contact.
distance =
static_cast<double>(cp.m_distance1);
768 if (
processResult(collisions, contact, pc, found) ==
nullptr)
775 const btCollisionObjectWrapper* cow,
776 const btVector3& pt_world,
777 const btVector3& normal_world,
778 const btTransform& link_tf_inv,
781 assert(
dynamic_cast<const CastHullShape*
>(cow->getCollisionShape()) !=
nullptr);
782 const auto* shape =
static_cast<const CastHullShape*
>(cow->getCollisionShape());
783 assert(shape !=
nullptr);
786 const btTransform& shape_tfWorld0 = cow->getWorldTransform();
787 btTransform shape_tfWorld1 = cow->getWorldTransform() * shape->m_t01;
795 btVector3 shape_normalLocal0 = normal_world * shape_tfWorld0.getBasis();
796 btVector3 shape_normalLocal1 = normal_world * shape_tfWorld1.getBasis();
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;
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;
810 btScalar shape_sup0 = normal_world.dot(shape_ptWorld0);
811 btScalar shape_sup1 = normal_world.dot(shape_ptWorld1);
832 btScalar l0c = (pt_world - shape_ptWorld0).length();
833 btScalar l1c = (pt_world - shape_ptWorld1).length();
836 convertBtToEigen(link_tf_inv * (shape_tfWorld0 * ((shape_ptLocal0 + shape_ptLocal1) / 2.0)));
845 col->
cc_time[link_index] =
static_cast<double>(l0c / (l0c + l1c));
851 const btCollisionObjectWrapper* colObj0Wrap,
853 const btCollisionObjectWrapper* colObj1Wrap,
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());
866 const auto it = collisions.
res->
find(pc);
867 bool found = (it != collisions.
res->
end() && !it->second.empty());
879 btTransform tf0_inv = tf0.inverse();
880 btTransform tf1_inv = tf1.inverse();
886 if (cd0->getCollisionGeometries().size() == 1)
889 contact.
shape_id[0] = (index0 < 0) ? 0 : index0;
891 if (cd1->getCollisionGeometries().size() == 1)
894 contact.
shape_id[1] = (index1 < 0) ? 0 : index1;
904 contact.
type_id[0] = cd0->getTypeID();
905 contact.
type_id[1] = cd1->getTypeID();
906 contact.
distance =
static_cast<double>(cp.m_distance1);
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;
927 if (castShapeIsFirst)
946 const btCollisionObjectWrapper* obj1Wrap,
947 btCollisionWorld::ContactResultCallback& resultCallback)
948 : btManifoldResult(obj0Wrap, obj1Wrap), m_resultCallback(resultCallback)
953 const btVector3& pointInWorld,
956 bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
957 btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
962 localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
963 localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
967 localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
968 localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
971 btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth);
972 newPt.m_positionWorldOnA = pointA;
973 newPt.m_positionWorldOnB = pointInWorld;
978 newPt.m_partId0 = m_partId1;
979 newPt.m_partId1 = m_partId0;
980 newPt.m_index0 = m_index1;
981 newPt.m_index1 = m_index0;
985 newPt.m_partId0 = m_partId0;
986 newPt.m_partId1 = m_partId1;
987 newPt.m_index0 = m_index0;
988 newPt.m_index1 = m_index1;
992 const btCollisionObjectWrapper* obj0Wrap = isSwapped ? m_body1Wrap : m_body0Wrap;
993 const btCollisionObjectWrapper* obj1Wrap = isSwapped ? m_body0Wrap : m_body1Wrap;
995 newPt, obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1);
999 double contact_distance,
1001 : collisions_(collisions), contact_distance_(contact_distance), verbose_(
verbose)
1012 double contact_distance,
1019 const btCollisionObjectWrapper* colObj0Wrap,
1022 const btCollisionObjectWrapper* colObj1Wrap,
1033 double contact_distance,
1040 const btCollisionObjectWrapper* colObj0Wrap,
1043 const btCollisionObjectWrapper* colObj1Wrap,
1055 const btCollisionObjectWrapper* obj0Wrap,
1056 const btCollisionObjectWrapper* obj1Wrap,
1058 : btManifoldResult(obj0Wrap, obj1Wrap), result_callback_(result_callback)
1063 const btVector3& pointInWorld,
1069 bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
1070 btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
1075 localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
1076 localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1080 localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
1081 localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
1084 btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth);
1085 newPt.m_positionWorldOnA = pointA;
1086 newPt.m_positionWorldOnB = pointInWorld;
1091 newPt.m_partId0 = m_partId1;
1092 newPt.m_partId1 = m_partId0;
1093 newPt.m_index0 = m_index1;
1094 newPt.m_index1 = m_index0;
1098 newPt.m_partId0 = m_partId0;
1099 newPt.m_partId1 = m_partId1;
1100 newPt.m_index0 = m_index0;
1101 newPt.m_index1 = m_index1;
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);
1112 btCollisionDispatcher* dispatcher,
1114 : dispatch_info_(dispatchInfo), dispatcher_(dispatcher), results_callback_(results_callback)
1128 btCollisionObjectWrapper obj0Wrap(
nullptr, cow0->getCollisionShape(), cow0, cow0->getWorldTransform(), -1, -1);
1129 btCollisionObjectWrapper obj1Wrap(
nullptr, cow1->getCollisionShape(), cow1, cow1->getWorldTransform(), -1, -1);
1132 if (pair.m_algorithm ==
nullptr)
1134 pair.m_algorithm =
dispatcher_->findAlgorithm(&obj0Wrap, &obj1Wrap,
nullptr, BT_CLOSEST_POINT_ALGORITHMS);
1137 if (pair.m_algorithm !=
nullptr)
1143 pair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap,
dispatch_info_, &contactPointResult);
1168 if (shapes.empty() || shape_poses.empty() || (shapes.size() != shape_poses.size()))
1170 CONSOLE_BRIDGE_logDebug(
"ignoring link %s",
name.c_str());
1174 auto new_cow = std::make_shared<COW>(
name, type_id, shapes, shape_poses);
1176 new_cow->m_enabled = enabled;
1179 CONSOLE_BRIDGE_logDebug(
"Created collision object for link %s", new_cow->getName().c_str());
1185 btScalar contact_distance,
1187 : collisions_(collisions), cow_(std::move(cow)), contact_distance_(contact_distance), verbose_(
verbose)
1189 m_closestDistanceThreshold = contact_distance;
1190 m_collisionFilterGroup =
cow_->m_collisionFilterGroup;
1191 m_collisionFilterMask =
cow_->m_collisionFilterMask;
1195 const btCollisionObjectWrapper* colObj0Wrap,
1198 const btCollisionObjectWrapper* colObj1Wrap,
1218 double contact_distance,
1220 : collisions_(collisions), cow_(std::move(cow)), contact_distance_(contact_distance), verbose_(
verbose)
1222 m_closestDistanceThreshold =
static_cast<btScalar
>(contact_distance);
1223 m_collisionFilterGroup =
cow_->m_collisionFilterGroup;
1224 m_collisionFilterMask =
cow_->m_collisionFilterMask;
1228 const btCollisionObjectWrapper* colObj0Wrap,
1231 const btCollisionObjectWrapper* colObj1Wrap,
1256 if (btBroadphaseProxy::isConvex(new_cow->getCollisionShape()->getShapeType()))
1258 assert(
dynamic_cast<btConvexShape*
>(new_cow->getCollisionShape()) !=
nullptr);
1259 auto* convex =
static_cast<btConvexShape*
>(new_cow->getCollisionShape());
1260 assert(convex->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE);
1263 auto shape = std::make_shared<CastHullShape>(convex, tf);
1264 assert(shape !=
nullptr);
1266 new_cow->manage(std::make_shared<BulletCollisionShape>(shape));
1267 new_cow->setCollisionShape(shape.get());
1269 else if (btBroadphaseProxy::isCompound(new_cow->getCollisionShape()->getShapeType()))
1271 assert(
dynamic_cast<btCompoundShape*
>(new_cow->getCollisionShape()) !=
nullptr);
1272 auto* compound =
static_cast<btCompoundShape*
>(new_cow->getCollisionShape());
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)
1281 if (btBroadphaseProxy::isConvex(compound->getChildShape(i)->getShapeType()))
1283 auto* convex =
static_cast<btConvexShape*
>(compound->getChildShape(i));
1284 assert(convex->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE);
1286 btTransform geomTrans = compound->getChildTransform(i);
1288 auto subshape = std::make_shared<CastHullShape>(convex, tf);
1289 assert(subshape !=
nullptr);
1291 collision_shape->children.push_back(subshape);
1293 new_compound->addChildShape(geomTrans, subshape.get());
1295 else if (btBroadphaseProxy::isCompound(compound->getChildShape(i)->getShapeType()))
1297 auto* second_compound =
static_cast<btCompoundShape*
>(compound->getChildShape(i));
1298 auto new_second_compound =
1301 for (
int j = 0; j < second_compound->getNumChildShapes(); ++j)
1303 assert(!btBroadphaseProxy::isCompound(second_compound->getChildShape(j)->getShapeType()));
1304 assert(
dynamic_cast<btConvexShape*
>(second_compound->getChildShape(j)) !=
nullptr);
1306 auto* convex =
static_cast<btConvexShape*
>(second_compound->getChildShape(j));
1307 assert(convex->getShapeType() != CUSTOM_CONVEX_SHAPE_TYPE);
1309 btTransform geomTrans = second_compound->getChildTransform(j);
1311 auto subshape = std::make_shared<CastHullShape>(convex, tf);
1312 assert(subshape !=
nullptr);
1314 collision_shape->children.push_back(subshape);
1316 new_second_compound->addChildShape(geomTrans, subshape.get());
1319 btTransform geomTrans = compound->getChildTransform(i);
1321 collision_shape->children.push_back(new_second_compound);
1327 new_compound->addChildShape(geomTrans, new_second_compound.get());
1332 throw std::runtime_error(
"I can only collision check convex shapes and compound shapes made of convex shapes");
1341 new_cow->manage(collision_shape);
1342 new_cow->setCollisionShape(collision_shape->top_level.get());
1343 new_cow->setWorldTransform(cow->getWorldTransform());
1348 throw std::runtime_error(
"I can only collision check convex shapes and compound shapes made of convex shapes");
1356 const std::unique_ptr<btBroadphaseInterface>& broadphase,
1357 const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1360 btVector3 aabb_min, aabb_max;
1361 cow->getAABB(aabb_min, aabb_max);
1364 assert(cow->getBroadphaseHandle() !=
nullptr);
1365 broadphase->setAabb(cow->getBroadphaseHandle(), aabb_min, aabb_max, dispatcher.get());
1369 const std::unique_ptr<btBroadphaseInterface>& broadphase,
1370 const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1372 btBroadphaseProxy* bp = cow->getBroadphaseHandle();
1376 broadphase->getOverlappingPairCache()->cleanProxyFromPairs(bp, dispatcher.get());
1377 broadphase->destroyProxy(bp, dispatcher.get());
1378 cow->setBroadphaseHandle(
nullptr);
1383 const std::unique_ptr<btBroadphaseInterface>& broadphase,
1384 const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1386 btVector3 aabb_min, aabb_max;
1387 cow->getAABB(aabb_min, aabb_max);
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()));
1397 const std::unique_ptr<btBroadphaseInterface>& broadphase,
1398 const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1405 broadphase->getOverlappingPairCache()->cleanProxyFromPairs(cow->getBroadphaseHandle(), dispatcher.get());
1409 const std::unique_ptr<btBroadphaseInterface>& broadphase,
1410 const std::unique_ptr<btCollisionDispatcher>& dispatcher)
1412 if (cow->getBroadphaseHandle() !=
nullptr)
1414 broadphase->destroyProxy(cow->getBroadphaseHandle(), dispatcher.get());
1416 btVector3 aabb_min, aabb_max;
1417 cow->getAABB(aabb_min, aabb_max);
1420 int type{ cow->getCollisionShape()->getShapeType() };
1421 cow->setBroadphaseHandle(broadphase->createProxy(aabb_min,
1425 cow->m_collisionFilterGroup,
1426 cow->m_collisionFilterMask,