Disable Relatively Sized Contact Breaking Threshold

Post Reply
sugarbear8oh3
Posts: 1
Joined: Wed Dec 05, 2018 11:46 pm

Disable Relatively Sized Contact Breaking Threshold

Post by sugarbear8oh3 »

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.

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;
}
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:
  • 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?
Post Reply