Tracing the problem back to btManifoldResult::addContactPoint I noticed that the contact information is added to the manifold *before* the contact callback is issued. Moving the callback back a few steps seems to have resolved the problem.
Is this a bug, or am I misinterpreting how this is supposed to work?
Before my change:
Code: Select all
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
assert(m_manifoldPtr);
//order in manifold needs to match
if (depth > m_manifoldPtr->getContactBreakingThreshold())
return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
btVector3 localA;
btVector3 localB;
if (isSwapped)
{
localA = m_rootTransB.invXform(pointA );
localB = m_rootTransA.invXform(pointInWorld);
} else
{
localA = m_rootTransA.invXform(pointA );
localB = m_rootTransB.invXform(pointInWorld);
}
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
newPt.m_positionWorldOnA = pointA;
newPt.m_positionWorldOnB = pointInWorld;
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1);
newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1);
//BP mod, store contact triangles.
newPt.m_partId0 = m_partId0;
newPt.m_partId1 = m_partId1;
newPt.m_index0 = m_index0;
newPt.m_index1 = m_index1;
///todo, check this for any side effects
if (insertIndex >= 0)
{
//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
} else
{
m_manifoldPtr->AddManifoldPoint(newPt);
}
//User can override friction and/or restitution
if (gContactAddedCallback &&
//and if either of the two bodies requires custom material
((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
(m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
{
//experimental feature info, for per-triangle material etc.
btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
(*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
}
}
Code: Select all
...
newPt.m_partId0 = m_partId0;
newPt.m_partId1 = m_partId1;
newPt.m_index0 = m_index0;
newPt.m_index1 = m_index1;
//User can override friction and/or restitution
if (gContactAddedCallback &&
//and if either of the two bodies requires custom material
((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
(m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
{
//experimental feature info, for per-triangle material etc.
btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
(*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
}
///todo, check this for any side effects
if (insertIndex >= 0)
{
//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
} else
{
m_manifoldPtr->AddManifoldPoint(newPt);
}
...