Filtering/comparing contactpoints of dynamic rigidbodies

Post Reply
Lewa
Posts: 5
Joined: Wed May 31, 2017 8:55 pm

Filtering/comparing contactpoints of dynamic rigidbodies

Post by Lewa »

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

Code: Select all

bool gContactAddedCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
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

Code: Select all

void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
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:

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)
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.

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;
and then add the callback to the performDiscreteCollisionDetection() function:

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);
	}
}
which allows us to create a callback which looks like this:

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;
Post Reply