c++ - Bullet Physics 最简单的碰撞示例

标签 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));

现在我有类型为 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);

我对我的敌对对象做了基本相同的事情。

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

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
}

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

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;
 }
}

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

无论如何,如果你读到这里,谢谢你!!非常感谢您提供任何建议或链接。

最佳答案

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

dynamicsWorld->addRigidBody(mPlayerObject,1,1);
dynamicsWorld->addRigidBody(mEnemyObject,1,1);
...
dynamicsWorld->setInternalTickCallback(myTickCallback);

然后我可以看到

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

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

关于c++ - Bullet Physics 最简单的碰撞示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11175694/

相关文章:

c++ - 不会链接,除非内联方法

c++ - 使用ofstream缓冲文本输出以获得性能

c++ - 为什么每次递归后我的变量都没有增加?

contacts - 子弹物理 : contacts force/impulse

c++ - 如何在 Code::Blocks 上启用 SSE/SSE2?

c++ - 如何消除空气阻力?

c++ - 在 C++ 中将对象传递给抽象类型的构造函数

c++ - 弹跳球逻辑

java - 移动速度不同?

python - 简单游戏的碰撞检测/物理