Disable Relatively Sized Contact Breaking Threshold
Posted: Thu Dec 06, 2018 9:17 pm
Hi all,
With discrete collision detection, it was found that a btCompoundShape was determining that it was in collision with an object at a larger threshold than an individual primitive btCollisionShape like a capsule. The capsule was able to get much closer to the target object.
From some digging around the code, I found that the btPersistentManifold defaults to using a relative threshold. This threshold appears to be relative to the size of the bounding sphere of an entire shape (or compound) - the larger it is, the larger the threshold. That is why the compound shape has a larger threshold than the individual shape.
As the code mentions, I can use the default gContactBreakingThreshold if I set the Dispatcher Flags appropriately. By setting it to btCollisionDispatcher::CD_STATIC_STATIC_REPORTED, I was able to get the compound shape to detect collisions at a much closer distance. From what I can see, this setting change does not affect any other parts of Bullet. I also know that there is a setContactBreakingThreshold function for the manifolds but I would like to avoid having to call this numerous times on the fly - I'd much rather configure an optional parameter.
My questions are:
With discrete collision detection, it was found that a btCompoundShape was determining that it was in collision with an object at a larger threshold than an individual primitive btCollisionShape like a capsule. The capsule was able to get much closer to the target object.
From some digging around the code, I found that the btPersistentManifold defaults to using a relative threshold. This threshold appears to be relative to the size of the bounding sphere of an entire shape (or compound) - the larger it is, the larger the threshold. That is why the compound shape has a larger threshold than the individual shape.
Code: Select all
btPersistenManifold* btCollisionDispatcher::getNewManifold(...)
{
(...)
//optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ?
btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold) , body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold)) :
gContactBreakingThreshold ;
(...)
Code: Select all
void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const
{
btTransform tr;
tr.setIdentity();
btVector3 aabbMin,aabbMax;
getAabb(tr,aabbMin,aabbMax);
radius = (aabbMax-aabbMin).length()*btScalar(0.5);
center = (aabbMin+aabbMax)*btScalar(0.5);
}
btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const
{
return getAngularMotionDisc() * defaultContactThreshold;
}
btScalar btCollisionShape::getAngularMotionDisc() constbtScalar btCollisionShape::getAngularMotionDisc() const
{
///@todo cache this value, to improve performance
btVector3 center;
btScalar disc;
getBoundingSphere(center,disc);
disc += (center).length();
return disc;
}
My questions are:
- Does anyone know if this is change would affect something else that I am not aware of?
- Are there other solutions to this relative contact threshold?