Exemple #1
0
//by default, Bullet will use this near callback
void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
		btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
		btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;

		if (dispatcher.needsCollision(colObj0,colObj1))
		{
			//dispatcher will keep algorithms persistent in the collision pair
			if (!collisionPair.m_algorithm)
			{
				collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1);
			}

			if (collisionPair.m_algorithm)
			{
				btManifoldResult contactPointResult(colObj0,colObj1);
				
				if (dispatchInfo.m_dispatchFunc == 		btDispatcherInfo::DISPATCH_DISCRETE)
				{
					//discrete collision detection query
					collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult);
				} else
				{
					//continuous collision detection query, time of impact (toi)
					btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
					if (dispatchInfo.m_timeOfImpact > toi)
						dispatchInfo.m_timeOfImpact = toi;

				}
			}
		}

}
		void run() {
			btCollisionObject *obj0 = (btCollisionObject *)m_pair.m_pProxy0->m_clientObject;
			btCollisionObject *obj1 = (btCollisionObject *)m_pair.m_pProxy1->m_clientObject;

			// Check for invalid numbers being passed through
			btAssert(obj0->getWorldTransform() == obj0->getWorldTransform());
			btAssert(obj1->getWorldTransform() == obj1->getWorldTransform());

			btCollisionObjectWrapper obj0Wrap(0, obj0->getCollisionShape(), obj0, obj0->getWorldTransform(), -1, -1);
			btCollisionObjectWrapper obj1Wrap(0, obj1->getCollisionShape(), obj1, obj1->getWorldTransform(), -1, -1);

			if (!m_pair.m_algorithm) {
				m_pair.m_algorithm = m_pDispatcher->findAlgorithm(&obj0Wrap, &obj1Wrap);
			}

			if (m_pair.m_algorithm) {
				btManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap);
				
				if (m_pInfo->m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) {
					m_pair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, *m_pInfo, &contactPointResult);
				} else {
					// Continuous dispatch
					m_pair.m_algorithm->calculateTimeOfImpact(obj0, obj1, *m_pInfo, &contactPointResult);
				}
			}
		}
float collisionTester::collisionTest(btCollisionObject * objectA, btCollisionObject * objectB, btCollisionAlgorithm * algo){
    
    float dist = 99999;
    
    btCollisionObjectWrapper ob0(0,objectA->getCollisionShape(),objectA, objectA->getWorldTransform());
    btCollisionObjectWrapper ob1(0,objectB->getCollisionShape(),objectB, objectB->getWorldTransform());
//    
//	btCollisionAlgorithm* algo = collisionWorld->getDispatcher()->findAlgorithm(&ob0, &ob1);
    
	btManifoldResult contactPointResult(&ob0,&ob1);
	algo->processCollision(&ob0,&ob1,collisionWorld->getDispatchInfo(),&contactPointResult);
	
	btManifoldArray manifoldArray;
	algo->getAllContactManifolds(manifoldArray);
    
	int numManifolds = manifoldArray.size();
	for(int i=0;i<numManifolds;i++)
	{
		btPersistentManifold* contactManifold = manifoldArray[i];
		const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
        //	btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
        
	
		int numContacts = contactManifold->getNumContacts();
		bool swap = obA == objectA;
        
        //printf("numManifolds=%i, numContact = %i \n", numManifolds, numContacts);
        
		for (int j=0;j<numContacts;j++)
		{
			btManifoldPoint& pt = contactManifold->getContactPoint(j);
            
//          glDisable(GL_DEPTH_TEST);
//			glBegin(GL_LINES);
//			glColor3f(0, 0, 1);
			btVector3 ptA = swap ?pt.getPositionWorldOnA():pt.getPositionWorldOnB();
			btVector3 ptB = swap ? pt.getPositionWorldOnB():pt.getPositionWorldOnA();
//			glVertex3d(ptA.x(),ptA.y(),ptA.z());
//			glVertex3d(ptB.x(),ptB.y(),ptB.z());
            
            //contactPts.push_back(ptA);
            //contactPts.push_back(ptB);
            
//			glEnd();

            float distTmp = pt.getDistance();
            if(distTmp<dist)
                dist=distTmp;
                        
		}
        
		//you can un-comment out this line, and then all points are removed
		contactManifold->clearManifold();	
	}
    
    return dist;
}
Exemple #4
0
///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
///it reports one or more contact points (including the one with deepest penetration)
void	btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
{
	btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
	if (algorithm)
	{
		btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
		//discrete collision detection query
		algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult);

		algorithm->~btCollisionAlgorithm();
		getDispatcher()->freeCollisionAlgorithm(algorithm);
	}

}
Exemple #5
0
void Uncollider::nearCallback(btBroadphasePair &collisionPair,
  btCollisionDispatcher &dispatcher, const btDispatcherInfo &dispatchInfo) {

  btCollisionObject *colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
  btCollisionObject *colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;

  if (dispatcher.needsCollision(colObj0, colObj1)) {
    btCollisionObjectWrapper obj0Wrap(nullptr, colObj0->getCollisionShape(),
      colObj0, colObj0->getWorldTransform(), -1, -1);
    btCollisionObjectWrapper obj1Wrap(nullptr, colObj1->getCollisionShape(),
      colObj1, colObj1->getWorldTransform(), -1, -1);

    btManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap);

    if (not collisionPair.m_algorithm) {
#if (BT_BULLET_VERSION >=286)
      collisionPair.m_algorithm =
        dispatcher.findAlgorithm(&obj0Wrap, &obj1Wrap,
                                 contactPointResult.getPersistentManifold(),
                                 ebtDispatcherQueryType::BT_CONTACT_POINT_ALGORITHMS);
#else
      collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap, &obj1Wrap);
#endif
    }
    if (collisionPair.m_algorithm) {
      if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) {
        collisionPair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatchInfo,
          &contactPointResult);
        for (int i = 0; i < contactPointResult.getPersistentManifold()->getNumContacts(); ++i) {
          const btManifoldPoint &pt = contactPointResult.getPersistentManifold()->
            getContactPoint(i);
          const btVector3 &cp = pt.getPositionWorldOnA();
          if (isPointInUncollideVolume(cp)) {
            contactPointResult.getPersistentManifold()->removeContactPoint(i--);
          }
        }
      } else {
        btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0, colObj1,
          dispatchInfo, &contactPointResult);
        if (dispatchInfo.m_timeOfImpact > toi) {
          dispatchInfo.m_timeOfImpact = toi;
        }
      }
    }
  }
}
//вызываеться при столкновении геометрий
void PhysicsManager::mNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{

    btCollisionObject* colObj0 = static_cast<btCollisionObject*>(collisionPair.m_pProxy0->m_clientObject);
    btCollisionObject* colObj1 = static_cast<btCollisionObject*>(collisionPair.m_pProxy1->m_clientObject);

    if(dispatcher.needsCollision(colObj0,colObj1)) 
    {
        btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform());
        btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform());
            //dispatcher will keep algorithms persistent in the collision pair
        if (!collisionPair.m_algorithm) 
        {
            collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap);
        }

        if (collisionPair.m_algorithm)
        {
            btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap);

            if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) 
            {
                  //discrete collision detection query
                collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult);
            } 
            else 
            {
                  //continuous collision detection query, time of impact (toi)
                btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
                if (dispatchInfo.m_timeOfImpact > toi) 
                {
                    dispatchInfo.m_timeOfImpact = toi;
                }
            }

            if (contactPointResult.getPersistentManifold()->getNumContacts()>0)  //только сдесь мы уверены что есть пересечения 
            {
                GameLogic::getSingletonPtr()->CollideBody(colObj0, colObj1);
            }
        }
    }
    dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo);
}
Exemple #7
0
	virtual bool	process(const btBroadphaseProxy* proxy)
	{
		btCollisionObject*	collisionObject = (btCollisionObject*)proxy->m_clientObject;
		if (collisionObject == m_collisionObject)
			return true;

		//only perform raycast if filterMask matches
		if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
		{
			btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
			if (algorithm)
			{
				btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
				//discrete collision detection query
				algorithm->processCollision(m_collisionObject,collisionObject, m_world->getDispatchInfo(),&contactPointResult);

				algorithm->~btCollisionAlgorithm();
				m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
			}
		}
		return true;
	}
void	SpuGatheringCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher) 
{

	if (dispatchInfo.m_enableSPU)
	{
		m_maxNumOutstandingTasks = m_threadInterface->getNumTasks();

		{
			BT_PROFILE("processAllOverlappingPairs");

			if (!m_spuCollisionTaskProcess)
				m_spuCollisionTaskProcess = new SpuCollisionTaskProcess(m_threadInterface,m_maxNumOutstandingTasks);
		
			m_spuCollisionTaskProcess->setNumTasks(m_maxNumOutstandingTasks);
	//		printf("m_maxNumOutstandingTasks =%d\n",m_maxNumOutstandingTasks);

			m_spuCollisionTaskProcess->initialize2(dispatchInfo.m_useEpa);
			
		
			///modified version of btCollisionDispatcher::dispatchAllCollisionPairs:
			{
				btSpuCollisionPairCallback	collisionCallback(dispatchInfo,this);

				pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
			}
		}

		//send one big batch
		int numTotalPairs = pairCache->getNumOverlappingPairs();
		if (numTotalPairs)
		{
			btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr();
			int i;
			{
				int pairRange =	SPU_BATCHSIZE_BROADPHASE_PAIRS;
				if (numTotalPairs < (m_spuCollisionTaskProcess->getNumTasks()*SPU_BATCHSIZE_BROADPHASE_PAIRS))
				{
					pairRange = (numTotalPairs/m_spuCollisionTaskProcess->getNumTasks())+1;
				}
	
				BT_PROFILE("addWorkToTask");
				for (i=0;i<numTotalPairs;)
				{
					//Performance Hint: tweak this number during benchmarking
					
					int endIndex = (i+pairRange) < numTotalPairs ? i+pairRange : numTotalPairs;
					m_spuCollisionTaskProcess->addWorkToTask(pairPtr,i,endIndex);
					i = endIndex;
				}
			}
			{
				BT_PROFILE("PPU fallback");
				//handle PPU fallback pairs
				for (i=0;i<numTotalPairs;i++)
				{
					btBroadphasePair& collisionPair = pairPtr[i];
					if (collisionPair.m_internalTmpValue == 3)
					{
						if (collisionPair.m_algorithm)
						{
							btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
							btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
	
							if (dispatcher->needsCollision(colObj0,colObj1))
							{
							//discrete collision detection query
								btCollisionObjectWrapper ob0(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform());
								btCollisionObjectWrapper ob1(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform());

								btManifoldResult contactPointResult(&ob0,&ob1);
								
								if (dispatchInfo.m_dispatchFunc == 		btDispatcherInfo::DISPATCH_DISCRETE)
								{
									
									collisionPair.m_algorithm->processCollision(&ob0,&ob1,dispatchInfo,&contactPointResult);
								} else
								{
									//continuous collision detection query, time of impact (toi)
									btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
									if (dispatchInfo.m_timeOfImpact > toi)
										dispatchInfo.m_timeOfImpact = toi;
	
								}
							}
						}
					}
				}
			}
		}
		{
			BT_PROFILE("flush2");
			//make sure all SPU work is done
			m_spuCollisionTaskProcess->flush2();
		}

	} else
	{
		///PPU fallback
		///!Need to make sure to clear all 'algorithms' when switching between SPU and PPU
		btCollisionDispatcher::dispatchAllCollisionPairs(pairCache,dispatchInfo,dispatcher);
	}
}
void CollisionInterfaceDemo::displayCallback(void) {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	glDisable(GL_LIGHTING);

		btScalar m[16];
	
	btVector3	worldBoundsMin,worldBoundsMax;
	collisionWorld->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax);


	int i;
	for (i=0;i<numObjects;i++)
	{
		
		objects[i].getWorldTransform().getOpenGLMatrix( m );
		m_shapeDrawer->drawOpenGL(m,objects[i].getCollisionShape(),btVector3(1,1,1),getDebugMode(),worldBoundsMin,worldBoundsMax);
	}

	collisionWorld->getDispatchInfo().m_debugDraw = &debugDrawer;
	
	if (collisionWorld)
		collisionWorld->performDiscreteCollisionDetection();

	
	


#ifndef TEST_NOT_ADDING_OBJECTS_TO_WORLD
	
	collisionWorld->debugDrawWorld();
	///one way to draw all the contact points is iterating over contact manifolds in the dispatcher:

	int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
	for (i=0;i<numManifolds;i++)
	{
		btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(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++)
		{
			btManifoldPoint& pt = contactManifold->getContactPoint(j);

			glBegin(GL_LINES);
			glColor3f(0, 0, 0);
			
			btVector3 ptA = pt.getPositionWorldOnA();
			btVector3 ptB = pt.getPositionWorldOnB();

			glVertex3d(ptA.x(),ptA.y(),ptA.z());
			glVertex3d(ptB.x(),ptB.y(),ptB.z());
			glEnd();
		}

		//you can un-comment out this line, and then all points are removed
		//contactManifold->clearManifold();	
	}
#else


	glDisable(GL_TEXTURE_2D);
	for (i=0;i<numObjects;i++)
	{
		collisionWorld->debugDrawObject(objects[i].getWorldTransform(),objects[i].getCollisionShape(), btVector3(1,1,0));
	}

	btDrawingResult renderCallback;

	//collisionWorld->contactPairTest(&objects[0],&objects[1], renderCallback);
	collisionWorld->contactTest(&objects[0],renderCallback);
	
#if 0

	//another way is to directly query the dispatcher for both objects. The objects don't need to be inserted into the world

	btCollisionAlgorithm* algo = collisionWorld->getDispatcher()->findAlgorithm(&objects[0],&objects[1]);
	btManifoldResult contactPointResult(&objects[0],&objects[1]);
	algo->processCollision(&objects[0],&objects[1],collisionWorld->getDispatchInfo(),&contactPointResult);
	
	btManifoldArray manifoldArray;
	algo->getAllContactManifolds(manifoldArray);

	int numManifolds = manifoldArray.size();
	for (i=0;i<numManifolds;i++)
	{
		btPersistentManifold* contactManifold = manifoldArray[i];
		btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
	//	btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
	
		glDisable(GL_DEPTH_TEST);
		int numContacts = contactManifold->getNumContacts();
		bool swap = obA == &objects[0];

		for (int j=0;j<numContacts;j++)
		{
			btManifoldPoint& pt = contactManifold->getContactPoint(j);
		
			glBegin(GL_LINES);
			glColor3f(0, 0, 0);

			btVector3 ptA = swap ?pt.getPositionWorldOnA():pt.getPositionWorldOnB();
			btVector3 ptB = swap ? pt.getPositionWorldOnB():pt.getPositionWorldOnA();

			glVertex3d(ptA.x(),ptA.y(),ptA.z());
			glVertex3d(ptB.x(),ptB.y(),ptB.z());
			glEnd();
		}

		//you can un-comment out this line, and then all points are removed
		//contactManifold->clearManifold();	
	}
#endif


#endif
	




	//GL_ShapeDrawer::drawCoordSystem();


	btQuaternion qA = objects[0].getWorldTransform().getRotation();
	btQuaternion qB = objects[1].getWorldTransform().getRotation();


	if (!m_idle)
	{

		
		btScalar timeInSeconds = getDeltaTimeMicroseconds()/1000.f;

		btQuaternion orn;

		objects[0].getWorldTransform().getBasis().getEulerYPR(yaw,pitch,roll);
		pitch += 0.00005f*timeInSeconds;
		yaw += 0.0001f*timeInSeconds;
		objects[0].getWorldTransform().getBasis().setEulerYPR(yaw,pitch,roll);

		orn.setEuler(yaw,pitch,roll);
		objects[1].getWorldTransform().setOrigin(objects[1].getWorldTransform().getOrigin()+btVector3(0,-0.00001*timeInSeconds,0));

		//objects[0].getWorldTransform().setRotation(orn);

		
		
	}

	glFlush();
    swapBuffers();
}