10

衝突検出のみに 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 これは三角形メッシュの使用に関するものですが、私が実装しようとしていたものに最も近いように思えました。

とにかく、ここまで読んでくれてありがとう!!アドバイスやリンクをいただければ幸いです。

4

3 に答える 3

4

私は、3Dシーンでお互いを撃っている飛行士を使ってIOSアプリを書いています。弾丸の物理学を衝突検出に使用します。フライトをキネマティック オブジェクトとして設定し、ロジックでフライトを動かしてから、キネマティック オブジェクトの btMotionState worldTransform を更新します。次の2つのステートメントを変更するまで、衝突検出も取得しません(プレイヤーと敵の両方でマスキングとグループを同じに設定します)

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 になります。

于 2012-09-04T11:45:53.020 に答える