//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 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; } } } } }
virtual bool processOverlap(btBroadphasePair& pair) { BT_PROFILE("btCollisionDispatcher::processOverlap"); (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo); return false; }
void ModelPhysics::near_callback(btBroadphasePair & collisionPair, btCollisionDispatcher & dispatcher, const btDispatcherInfo & dispatchInfo) { ModelBody * pBody0 = static_cast<ModelBody*>(collisionPair.m_pProxy0->m_clientObject); ModelBody * pBody1 = static_cast<ModelBody*>(collisionPair.m_pProxy1->m_clientObject); dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo); }
//вызываеться при столкновении геометрий 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); }
static void MyNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) { const btBroadphaseProxy* proxy = s_LastHeldBody ? s_LastHeldBody->getBroadphaseProxy(): NULL; if (collisionPair.m_pProxy0 == proxy || collisionPair.m_pProxy1 == proxy) { // cancel collision return; } // Do your collision logic here // Only dispatch the Bullet collision information if you want the physics to continue dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo); }
void near_callback( btBroadphasePair &btbroadphasepair, btCollisionDispatcher &btdispatcher, const btDispatcherInfo &btdispatcherinfo ) { if( ( player->btrigidbody == btbroadphasepair.m_pProxy0->m_clientObject || player->btrigidbody == btbroadphasepair.m_pProxy1->m_clientObject ) && ( enemy->btrigidbody == btbroadphasepair.m_pProxy0->m_clientObject || enemy->btrigidbody == btbroadphasepair.m_pProxy1->m_clientObject ) ) { game_over = 1; } btdispatcher.defaultNearCallback( btbroadphasepair, btdispatcher, btdispatcherinfo ); }
void BulletWrapper::init() { assert(!m_Broadphase && !m_CollisionConfiguration && !m_Dispatcher && !m_Solver && !m_DynamicsWorld); m_Broadphase = new btDbvtBroadphase(); m_CollisionConfiguration = new btDefaultCollisionConfiguration(); m_Dispatcher = new btCollisionDispatcher(m_CollisionConfiguration); m_Dispatcher->setNearCallback(MyNearCallback); m_Solver = new btSequentialImpulseConstraintSolver; m_DynamicsWorld = new btDiscreteDynamicsWorld(m_Dispatcher, m_Broadphase, m_Solver, m_CollisionConfiguration); //m_DynamicsWorld->setGravity(btVector3(0, -10, 0)); m_DynamicsWorld->setGravity(btVector3(0, 0, 0)); }
void Planar2D::initPhysics() { m_guiHelper->setUpAxis(1); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_simplexSolver = new btVoronoiSimplexSolver(); m_pdSolver = new btMinkowskiPenetrationDepthSolver(); m_convexAlgo2d = new btConvex2dConvex2dAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver); m_box2dbox2dAlgo = new btBox2dBox2dCollisionAlgorithm::CreateFunc(); m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,m_convexAlgo2d); m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,m_convexAlgo2d); m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,m_convexAlgo2d); m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,m_box2dbox2dAlgo); m_broadphase = new btDbvtBroadphase(); //m_broadphase = new btSimpleBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->getSolverInfo().m_erp = 1.f; //m_dynamicsWorld->getSolverInfo().m_numIterations = 4; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.),btScalar(50.),btScalar(150.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-43,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btScalar u= btScalar(1*SCALING-0.04); btVector3 points[3] = {btVector3(0,u,0),btVector3(-u,-u,0),btVector3(u,-u,0)}; btConvexShape* childShape0 = new btBoxShape(btVector3(btScalar(SCALING*1),btScalar(SCALING*1),btScalar(0.04))); btConvexShape* colShape= new btConvex2dShape(childShape0); //btCollisionShape* colShape = new btBox2dShape(btVector3(SCALING*1,SCALING*1,0.04)); btConvexShape* childShape1 = new btConvexHullShape(&points[0].getX(),3); btConvexShape* colShape2= new btConvex2dShape(childShape1); btConvexShape* childShape2 = new btCylinderShapeZ(btVector3(btScalar(SCALING*1),btScalar(SCALING*1),btScalar(0.04))); btConvexShape* colShape3= new btConvex2dShape(childShape2); m_collisionShapes.push_back(colShape); m_collisionShapes.push_back(colShape2); m_collisionShapes.push_back(colShape3); m_collisionShapes.push_back(childShape0); m_collisionShapes.push_back(childShape1); m_collisionShapes.push_back(childShape2); //btUniformScalingShape* colShape = new btUniformScalingShape(convexColShape,1.f); colShape->setMargin(btScalar(0.03)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); // float start_x = START_POS_X - ARRAY_SIZE_X/2; // float start_y = START_POS_Y; // float start_z = START_POS_Z - ARRAY_SIZE_Z/2; btVector3 x(-ARRAY_SIZE_X, 8.0f,-20.f); btVector3 y; btVector3 deltaX(SCALING*1, SCALING*2,0.f); btVector3 deltaY(SCALING*2, 0.0f,0.f); for (int i = 0; i < ARRAY_SIZE_X; ++i) { y = x; for (int j = i; j < ARRAY_SIZE_Y; ++j) { startTransform.setOrigin(y-btVector3(-10,0,0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(0,0,0); switch (j%3) { #if 1 case 0: rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape,localInertia); break; case 1: rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape3,localInertia); break; #endif default: rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape2,localInertia); } btRigidBody* body = new btRigidBody(rbInfo); //body->setContactProcessingThreshold(colShape->getContactBreakingThreshold()); body->setActivationState(ISLAND_SLEEPING); body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); m_dynamicsWorld->addRigidBody(body); body->setActivationState(ISLAND_SLEEPING); // y += -0.8*deltaY; y += deltaY; } x += deltaX; } } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); }
virtual bool processOverlap(btBroadphasePair& pair) { (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo); return false; }