Bullet物理最简单的碰撞示例

Azt*_*tal 9 c++ game-physics bulletphysics

我正在尝试使用Bullet Physics进行碰撞检测.我不需要它为我移动任何对象或使用回调处理渲染.我只想每帧更新对象位置,并用它来告诉我何时发生碰撞.为了得到最简单的例子,我试图找到以btBoxShape为形状的对象之间的碰撞.一切运行良好,没有崩溃或明显的内存泄漏,但我没有碰撞,所以我必须在某处犯错.我会尽量保持这个尽可能简短而不留下任何重要的东西.

这是我的世界设置功能:

collisionConfig      = new btDefaultCollisionConfiguration();
dispatcher           = new btCollisionDispatcher(collisionConfig);
overlappingPairCache = new btDbvtBroadphase();
solver               = new btSequentialImpulseConstraintSolver;
dynamicsWorld        = new btDiscreteDynamicsWorld(dispatcher, 
overlappingPairCache, solver, collisionConfig);         

dynamicsWorld->setGravity(btVector3(0.0f, -9.8f, 0.0f));
Run Code Online (Sandbox Code Playgroud)

现在我有btCollisionObject*类型的玩家和敌人对象.我把它们设置成这样:

mPlayerBox = new btBoxShape(btVector3(1,3,1));
mPlayerObject = new btCollisionObject();
mPlayerObject->setCollisionShape(mPlayerBox);
btTransform playerWorld;
playerWorld.setIdentity();
//playerPos is a D3DXVECTOR3 that holds the camera position.
playerWorld.setOrigin(btVector3(playerPos.x, playerPos.y, playerPos.z));
mPlayerObject->setWorldTransform(playerWorld);
mPlayerObject->forceActivationState(DISABLE_DEACTIVATION);//maybe not needed
dynamicsWorld->addCollisionObject(mPlayerObject);
Run Code Online (Sandbox Code Playgroud)

我对敌人的物体基本上做同样的事情.

然后每一帧我用这样的东西更新我的所有对象:

btTransform updatedWorld;
updatedWorld.setIdentity();
updatedWorld.setOrigin(btVector3(position.x, position.y, position.z));
mPlayerObject->setWorldTransform(updatedWorld);

//do the same for my enemies, and then...

dynamicsWorld->performDiscreteCollisionDetection();
//Also tried doing this with stepSimulation(deltaTime, 7), but nothing changed.
//stepSimulation seems to only be for letting Bullet set world Transforms?

//check collisions with player
dynamicsWorld->contactTest(mPlayerObject, resultCallback);
int numManifolds = dynamicsWorld->getDispatcher()->getNumManifolds();
if(numManifolds > 0)
{
   //there's a collision, execute blah blah blah
}
Run Code Online (Sandbox Code Playgroud)

最后,这是定义我的结果回调的结构:

struct rCallBack : public btCollisionWorld::ContactResultCallback
{
 btScalar rCallback::addSingleResult(btManifoldPoint& cp, const btCollisionObject*
 colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1,
 int index1)
 {
   btVector3 ptA = cp.getPositionWorldOnA();
   btVector3 ptB = cp.getPositionWorldOnB();
   return 0;
 }
}
Run Code Online (Sandbox Code Playgroud)

我看了很多演示,但它们似乎主要是将动作留给了Bullet,而且因为我在碰撞时没有任何特殊的物理速度以一定的速度移动角色,所以我很难将这些例子调整到我的应用程序.结果回调实际上来自论坛上的这篇文章:http: //bulletphysics.org/Bullet/phpBB3/viewtopic.php?t = 6816 这是关于使用三角网格,但它似乎最接近我试图实现的.

无论如何,如果你读到这里,谢谢!任何您可以提供的建议或链接都​​将非常感激.

Joh*_*hui 5

我正在编写一个 IOS 应用程序,其中飞行器在 3D 场景中互相射击。我使用子弹物理进行碰撞检测,我将飞行器设置为运动学对象,我的逻辑移动飞行器,然后更新运动学对象的 btMotionState worldTransform。我也没有得到任何碰撞检测,直到我更改以下两个语句(将玩家和敌人的遮罩和组设置为相同)

dynamicsWorld->addRigidBody(mPlayerObject,1,1);
dynamicsWorld->addRigidBody(mEnemyObject,1,1);
...
dynamicsWorld->setInternalTickCallback(myTickCallback);
Run Code Online (Sandbox Code Playgroud)

然后我可以看到

void myTickCallback(btDynamicsWorld *world, btScalar timeStep) {
    int numManifolds = world->getDispatcher()->getNumManifolds();
    printf("numManifolds = %d\n",numManifolds);
}
Run Code Online (Sandbox Code Playgroud)

当物体碰撞时 numManifolds 值变为 1。