4

Ogre3Dを使用してアプリを作成しました。すでに弾丸のオブジェクトが生成されているので、今必要なのはオブジェクト間の衝突を検出することだけです。

CollisionInterfaceDemoデモを見ましたが、実際には私のニーズと一致していません。

衝突するかどうかを知るためだけに、3つの球の間の衝突を検出するために必要な手順は何ですか(衝突点は気にしません)?

CollisionObjectを移動できるのは、その変換を設定することだけです。

4

2 に答える 2

4

Bulletを使用している場合は、いくつかのデモを見て、作業を進めることができます。

しかし、基本的に、ここに要約があります(これの多くは彼らの例から取られています):

あなたのヘッダーまたはあなたの物理システムがどこにあるか:

btDefaultCollisionConfiguration*        mPhysicsConfig;
btCollisionDispatcher*                  mPhysicsDispatcher;
btBroadphaseInterface*                  mPhysicsCache;
btSequentialImpulseConstraintSolver*    mPhysicsSolver;
btDiscreteDynamicsWorld*                mPhysicsWorld;
btAlignedObjectArray<btCollisionShape*> mPhysicsShapes;

最初(初期化):

///collision configuration contains default setup for memory, collision setup.
mPhysicsConfig = new btDefaultCollisionConfiguration();

///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
mPhysicsDispatcher = new    btCollisionDispatcher(mPhysicsConfig);

///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
mPhysicsCache = new btDbvtBroadphase();

///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
mPhysicsSolver = new btSequentialImpulseConstraintSolver;
mPhysicsWorld = new btDiscreteDynamicsWorld(mPhysicsDispatcher,mPhysicsCache,mPhysicsSolver,mPhysicsConfig);
mPhysicsWorld->setGravity(btVector3(0,-9.81f,0));

各フレーム(これは通常、更新関数に含まれます):

mPhysicsWorld->stepSimulation( timestep , 10 );

球を追加します(作成後にアクセスしやすくするためにポインターが返されるだけです):

btRigidBody* MyPhysicsSystem::CreateSphere(float sx, float px, float py, float pz, float mass)
{
    btCollisionShape* colShape = new btSphereShape(btScalar(sx));
    mPhysicsShapes.push_back(colShape);

    btTransform startTransform;
    startTransform.setIdentity();

    btScalar    tMass(mass);

    //rigidbody is dynamic if and only if mass is non zero, otherwise static
    bool isDynamic = (tMass != 0.f);

    btVector3 localInertia(0,0,0);
    if (isDynamic)
        colShape->calculateLocalInertia(tMass,localInertia);

    startTransform.setOrigin(btVector3(px,py,pz));

    //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
    btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
    btRigidBody::btRigidBodyConstructionInfo rbInfo(tMass,myMotionState,colShape,localInertia);
    btRigidBody* body = new btRigidBody(rbInfo);
    mPhysicsWorld->addRigidBody(body);
    return body;
}

そしてそれはそれについてです!

繰り返しますが:

  1. シミュレーションに必要なものを初期化します。
  2. オブジェクトを作成し、それを弾丸の「世界」に追加します。
  3. フレームごとにその世界をタイムステップで更新します。

Bulletが衝突を処理します。衝突が発生したときに機能を実行するための何らかの方法が必要な場合は、発生する衝突動作としてカスタムコールバックを割り当てることができると思います。

お役に立てれば!

于 2012-02-02T19:35:01.490 に答える
1

球間の衝突検出を扱うときは、2つのことを知っておく必要があります。各球の半径とその位置です。

次に、各球を調べて、他の球と比較する必要があります。各ペアについて、最初にそれらの間の距離を見つける必要があります。

http://www.purplemath.com/modules/distform.htm

これが基本的な2次元距離の式です。3次元にするために必要なのは、結果を平方ルート化する前に、他の2つの座標に(z2-z1)squaredを追加することだけです。

その距離が決まったら、2つの球の半径を足し合わせて、それらの間の距離と比較します。距離が半径の合計以下の場合、球は衝突しています。

私はOgre3Dに特に精通していませんが、オブジェクトを変換できれば、その位置も取得できるはずです。

于 2012-02-02T18:48:13.990 に答える