Filtering/comparing contactpoints of dynamic rigidbodies
Posted: Sun Jan 09, 2022 2:42 pm
Hi!
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
Which allows us to do adjustements/filtering of said points (which is used for example for btAdjustInternalEdgeContacts) but it only allows us to access one single manifoldpoint at a time.
There are also dedicated testing functions like which allows us to iterate over all found points but this only works for manual collision handling. (i want to do this for dynamic objects handled by bullet.)
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:
From digging through the source code it seems that a btPersistentManifold is used to store said points although it looks like it works more like a cache and stores old as well as new contactpoints simultaneously. (haven't figured this one out yet)
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.
and then add the callback to the performDiscreteCollisionDetection() function:
which allows us to create a callback which looks like this:
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;