I'm currently trying to implement additional filtering options for dynamic rigidbodies.
The goal is to be able to filter/iterate through all contact points of a collission before the forces/collisionresponses are applied by the stepSimulation.
There exists a callback in bullet
Code: Select all
bool gContactAddedCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
There are also dedicated testing functions like
Code: Select all
void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
What i need is a callback where i have the ability to iterate through all manifoldPoints of a obj<>obj collision before the dynamic rigidbody physics responses are applied. (For the purpose of iterating through them and compare them to each other for filtering purposes.)
To illustrate a small pseudocode where exactly i want the callback to be injected:
Code: Select all
//stepWorld
for each rigidbody A
create contactpointList C
for each rigidbody B
if A != B
perform collision check and add points to C
customCallback(C) // custom filtering <<<<<<<<<<<<<<
performCollisionResponse(C)
Anyone an idea if there already exists something similar in the codebase? (Or any hints as to how this could be properly intergrated?)
-----------------
/Edit: Found a solution for those who stumble upon this topic in the future.
Basically i had to inject a custom callback in the btCollisionWorld class which exposes the dispatcher.
Code: Select all
//at the top of btCollisionWorld.h
//================ custom addition ==================
typedef void (*CustomManifoldIterCallback)(btDispatcher* dispatcher);
extern CustomManifoldIterCallback gCustomManifoldIterCallback;
Code: Select all
//btCollisionWorld.cpp
CustomManifoldIterCallback gCustomManifoldIterCallback = 0;
Code: Select all
void btCollisionWorld::performDiscreteCollisionDetection()
{
BT_PROFILE("performDiscreteCollisionDetection");
btDispatcherInfo& dispatchInfo = getDispatchInfo();
updateAabbs();
computeOverlappingPairs();
btDispatcher* dispatcher = getDispatcher();
{
BT_PROFILE("dispatchAllCollisionPairs");
if (dispatcher)
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(), dispatchInfo, m_dispatcher1);
}
if (gCustomManifoldIterCallback)
{
(*gCustomManifoldIterCallback)(dispatcher);
}
}
Code: Select all
void MyCustomManifoldIterCallback(btDispatcher* dispatcher)
{
int numManifolds = dispatcher->getNumManifolds();
//iterate through all collisions
for (int i = 0; i < numManifolds; i++)
{
btPersistentManifold* contactManifold = dispatcher->getManifoldByIndexInternal(i);
int numContacts = contactManifold->getNumContacts();
//iterate through contacts
for (int j = 0; j < numContacts; j++)
{
btManifoldPoint& pt = contactManifold->getContactPoint(j);
//perform filtering (adjust normals/and or remove manifoldpoints)
}
}
}
Code: Select all
gCustomManifoldIterCallback = MyCustomManifoldIterCallback;