Ejemplo n.º 1
0
void BulletPhysics::BulletInternalTickCallback(btDynamicsWorld* world, btScalar timeStep)
{
	// called after bullet sdk performs its internal step

	CB_ASSERT(world);
	CB_ASSERT(world->getWorldUserInfo());

	BulletPhysics* bulletPhysics = static_cast<BulletPhysics*>(world->getWorldUserInfo());
	CollisionPairs currentTickCollisionPairs;

	// look at all existing collisions
	btDispatcher* dispatcher = world->getDispatcher();
	const int numManifolds = dispatcher->getNumManifolds();
	for (int i = 0; i < numManifolds; i++)
	{
		// get the manifold which is the data corresponding to a contact point between two colliders
		const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
		CB_ASSERT(manifold);

		// get the colliding bodies
		const btRigidBody* body0 = static_cast<const btRigidBody *>(manifold->getBody0());
		const btRigidBody* body1 = static_cast<const btRigidBody *>(manifold->getBody1());

		// swap them if need be
		const bool swapped = body0 > body1;
		const btRigidBody* sortedBody0 = swapped ? body1 : body0;
		const btRigidBody* sortedBody1 = swapped ? body0 : body1;

		// insert the collision pair into the set
		const CollisionPair pair = std::make_pair(sortedBody0, sortedBody1);
		currentTickCollisionPairs.insert(pair);
		
		// if this is a new contact, send an event
		if (bulletPhysics->m_PreviousTickCollisionPairs.find(pair) == bulletPhysics->m_PreviousTickCollisionPairs.end())
		{
			bulletPhysics->SendCollisionPairAddEvent(manifold, body0, body1);
		}
	}

	CollisionPairs removedCollisionPairs;

	// use set difference to see which collisions existed last tick but are no longer colliding
	std::set_difference(bulletPhysics->m_PreviousTickCollisionPairs.begin(), bulletPhysics->m_PreviousTickCollisionPairs.end(),
		currentTickCollisionPairs.begin(), currentTickCollisionPairs.end(),
		std::inserter(removedCollisionPairs, removedCollisionPairs.begin()));

	// send collision exit events
	for (auto it = removedCollisionPairs.begin(); it != removedCollisionPairs.end(); ++it)
	{
		const btRigidBody* body0 = it->first;
		const btRigidBody* body1 = it->second;

		bulletPhysics->SendCollisionPairRemoveEvent(body0, body1);
	}

	// update the collision pairs
	bulletPhysics->m_PreviousTickCollisionPairs = currentTickCollisionPairs;
}
void BulletOpenGLApplication::CheckForCollisionEvents() {
	// keep a list of the collision pairs we
	// found during the current update
	CollisionPairs pairsThisUpdate;

	// iterate through all of the manifolds in the dispatcher
	for (int i = 0; i < m_pDispatcher->getNumManifolds(); ++i) {
		
		// get the manifold
		btPersistentManifold* pManifold = m_pDispatcher->getManifoldByIndexInternal(i);
		
		// ignore manifolds that have 
		// no contact points.
		if (pManifold->getNumContacts() > 0) {
			// get the two rigid bodies involved in the collision
			const btRigidBody* pBody0 = static_cast<const btRigidBody*>(pManifold->getBody0());
			const btRigidBody* pBody1 = static_cast<const btRigidBody*>(pManifold->getBody1());
    
			// always create the pair in a predictable order
			// (use the pointer value..)
			bool const swapped = pBody0 > pBody1;
			const btRigidBody* pSortedBodyA = swapped ? pBody1 : pBody0;
			const btRigidBody* pSortedBodyB = swapped ? pBody0 : pBody1;
			
			// create the pair
			CollisionPair thisPair = std::make_pair(pSortedBodyA, pSortedBodyB);
			
			// insert the pair into the current list
			pairsThisUpdate.insert(thisPair);

			// if this pair doesn't exist in the list
			// from the previous update, it is a new
			// pair and we must send a collision event
			if (m_pairsLastUpdate.find(thisPair) == m_pairsLastUpdate.end()) {
				CollisionEvent((btRigidBody*)pBody0, (btRigidBody*)pBody1);
			}
		}
	}
	
	// create another list for pairs that
	// were removed this update
	CollisionPairs removedPairs;
	
	// this handy function gets the difference beween
	// two sets. It takes the difference between
	// collision pairs from the last update, and this 
	// update and pushes them into the removed pairs list
	std::set_difference( m_pairsLastUpdate.begin(), m_pairsLastUpdate.end(),
	pairsThisUpdate.begin(), pairsThisUpdate.end(),
	std::inserter(removedPairs, removedPairs.begin()));
	
	// iterate through all of the removed pairs
	// sending separation events for them
	for (CollisionPairs::const_iterator iter = removedPairs.begin(); iter != removedPairs.end(); ++iter) {
		SeparationEvent((btRigidBody*)iter->first, (btRigidBody*)iter->second);
	}
	
	// in the next iteration we'll want to
	// compare against the pairs we found
	// in this iteration
	m_pairsLastUpdate = pairsThisUpdate;
}