Most efficient way of being notified of new actual contacts

Post Reply
N0vember
Posts: 10
Joined: Sat Mar 06, 2010 6:39 pm

Most efficient way of being notified of new actual contacts

Post by N0vember »

Hello,

I am looking for the most efficient way to be be notified of new and removed contacts in the collision detection. By new contacts I don't mean new broadphase overlaps, but real contacts, real collisions.

I know of the "traditional" way which is in the wiki, and consists of using btGhostObjects to cache overlapping pairs, and then regularly go through every pair, check if there is contact, and then if there is contact, add it, and if there is no contact, remove it.
However supposing I have an existing list of contacts which I want to keep up to date, it is really inefficient, as I have to each time compare for each contact in the btGhostObject cache against my own list of contacts.

That's why I have been wanting a simple callback inside bullet collision detection narrow phase that would tell me when a real contact happens (depth < 0.f) and when a real contact is removed. Only then would performance be really satisfying with a lot of objects colliding all the time.

So I have been starting to cook my own, but I would like some pointers :
- I just made my own subclass of btCollisionDispatcher and changed just one line of code, instead of giving a btManifoldResult to the collision detection algorithm, it instead gives my own subclassed CallbackManifoldResult.
- However, since btManifoldResult is a temporary construct and the only persistent data is stored in the manifolds, the only way I could add a persistent flag storing whether or not there is actual collision was through altering the source of btPersistentManifold to add one boolean.
- Now to react to new collisions is simple, my own variation of btManifoldResult just checks if added contact points have a negative to zero distance, and if that means a yet non-colliding manifolds now collides, it then calls the appropriate callback I setup
- Now to react to removing of collisions is more trickier

So I am interested in two kinds of pointers :
- First, how would one detect the fact that the collision isn't happening anymore ? I guess it has to do with the update of manifold contact points and sometimes their removal
- Second, I'm interested in general criticism from someone who is more bullet-savy than my as to how to achieve this behavior.

Code: Select all

	CallbackManifoldResult::CallbackManifoldResult(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
		: btManifoldResult(body0Wrap, body1Wrap)
	{}

	void CallbackManifoldResult::addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth)
	{
		if(depth < 0.f && !m_manifoldPtr->m_collides)
		{
			m_manifoldPtr->m_collides = true;
			// Callback would go here -> add the contact
		}

		btManifoldResult::addContactPoint(normalOnBInWorld, pointInWorld, depth);
	}

Code: Select all

	CallbackCollisionDispatcher::CallbackCollisionDispatcher(btCollisionConfiguration* configuration)
		: btCollisionDispatcher(configuration)
	{}

	void CallbackCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
	{
                [...]
			if(collisionPair.m_algorithm)
			{
				// ----------------      This is the line we changed    ---------------------------
 				CallbackManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap);
                [...]
	}
Last edited by N0vember on Thu Nov 06, 2014 11:42 pm, edited 1 time in total.
N0vember
Posts: 10
Joined: Sat Mar 06, 2010 6:39 pm

Re: Most efficient way of being notified of new actual conta

Post by N0vember »

No pointers ?
This is not something trivial, as confirmed by profiling.
For a hundred of objects, some colliding with dozens of others :
- Going manually through the contacts for each object every frame and comparing about a list of contacts for added / removed
takes more than 5 times as much time as the performDiscreteCollisionDetection call itself which does all the work

Granted, my way of comparing for add and remove is not the most efficient, but still, it would be much more efficient to have the zero overhead that would be achieved with a collision callback.
Post Reply