Collision between 2 objects

Please don't post Bullet support questions here, use the above forums instead.
seagullrace
Posts: 1
Joined: Thu May 13, 2010 9:56 am

Collision between 2 objects

Post by seagullrace »

Hi,

I'm working on a project about a seagull race, and I would like to use Bullet to detect collisions

One body is static, the other is moving, i use MotionState to move.

First I tried:

bodies[0]->checkCollideWith(bodies[1]) : but it's always send true.

Second I tried something I found on this forum

Code: Select all

btCollisionAlgorithm* pAlgorithm = myWorld->getDispatcher()->findAlgorithm( bodies[0], bodies[1] );
	btManifoldResult oManifoldResult( bodies[0], bodies[1] );
	pAlgorithm->processCollision( bodies[0], bodies[1],myWorld->getDispatchInfo(), &oManifoldResult );
	btPersistentManifold* pManifold = oManifoldResult.getPersistentManifold();

	Logger::Log() << "Post treat "<<pManifold->getNumContacts() <<"\n";
	if(pManifold->getNumContacts()>0)
		Logger::Log() << " Bingo !" <<"\n";
But I can't fing any contact. Am I missing something ?
I've been on this problem for days now, and I can't find any solution ^-^"

Could you help me please ?
Michael Stengel
Posts: 6
Joined: Tue Jul 06, 2010 4:10 pm
Location: Wolfsburg

Re: Collision between 2 objects

Post by Michael Stengel »

Hi seagullrace,
the following code works for me, to check if there is a penetration.

First solution: btGjkPairDetector

Code: Select all


// objectA and objectB are of type btCollisionObject
// objectBodyA and objectBodyB are of type btRigidBody

btVoronoiSimplexSolver sGjkSimplexSolver;
btGjkEpaPenetrationDepthSolver epaSolver;
btPointCollector gjkOutput;
{
	btGjkPairDetector convexConvex((btConvexShape*)objectA->getCollisionShape(), (btConvexShape*)objectB->getCollisionShape(),&sGjkSimplexSolver,&epaSolver);

	btGjkPairDetector::ClosestPointInput input;
	input.m_transformA = objectBodyA->getWorldTransform();
	input.m_transformB = objectBodyB->getWorldTransform();
	convexConvex.getClosestPoints(input, gjkOutput, 0);
}
if (gjkOutput.m_hasResult && gjkOutput.m_distance<0)
{
	cout << "penetration depth = " << gjkOutput.m_distance << endl;

	btVector3 contactPoint = gjkOutput.m_pointInWorld;
	btScalar distance = gjkOutput.m_distance;
	btVector3 normal = gjkOutput.m_normalOnBInWorld;
}
Second solution: contactPairTest with collision callback

Code: Select all

// perform collision test
btDrawingResult renderCallback;
dyn_world->contactPairTest(objectA,objectB, renderCallback);

// declaration of callback
struct btDrawingResult : public btCollisionWorld::ContactResultCallback
{
	virtual	btScalar	addSingleResult(btManifoldPoint& cp,	const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
	{
		std::cout << "contact!" << std::endl;
		btVector3 ptA = cp.getPositionWorldOnA();
		btVector3 ptB = cp.getPositionWorldOnB();
		btVector3 norm = cp.m_normalWorldOnB;
		return 0;
	}
};
Third solution: process collision (nearly the same as in the second solution), iterate over manifolds afterwards

Code: Select all

btCollisionAlgorithm* algo = dyn_world->getDispatcher()->findAlgorithm(objectA,objectB);
btManifoldResult contactPointResult(objectA,objectB);
algo->processCollision(objectA,objectB,dyn_world->getDispatchInfo(),&contactPointResult);

btManifoldArray manifoldArray;
algo->getAllContactManifolds(manifoldArray);
int numManifolds = manifoldArray.size();
for (int i=0;i<numManifolds;i++)
{
  btPersistentManifold* contactManifold = manifoldArray[i];
  btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
  btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
  int numContacts = contactManifold->getNumContacts();
  for (int j=0;j<numContacts;j++)
  {
     std::cout << "contact!" << std::endl;
     btManifoldPoint& pt = contactManifold->getContactPoint(j);
     btVector3 ptA = pt.getPositionWorldOnA();
     btVector3 ptB = pt.getPositionWorldOnB();
  }
}
The third solution also performs the collision response. This has to be avoided, if you only need collision detection.

But: I don't know how accurate or robust the collision detection of the Bullet GJK algorithm is. I have the feeling that contact pairs are missed from time to time. Lets say there is a contact pair in frame 1 and 3. It happends that in frame 2 this contact pair is not calculated even if it should be. You can see this on the screenshots in thread http://bulletphysics.org/Bullet/phpBB3/ ... f=9&t=5365.

I know that they are heuristics in the Bullet implementation to reduce the number of contact pairs to the "most important" ones. But i do not know details about this fact. It would be interesting, if one could deactivate this feature without great efforts.

Maybe one of the pros of the Bullet board could give his thoughts about it to clarify this issue ? I think there are many peoples who would be interested in this fact.

Michael