7

1 つの (ボール) が別のオブジェクト (ターゲット) に触れたことを検出し、その接触のインパルスを知りたいと考えています。

連絡先を検出する 3 つの方法を知っている

gContactAddedCallback

また

    int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
    for (int i=0;i<numManifolds;i++)
    {
        btRigidBody* obA = static_cast<btRigidBody*>(contactManifold->getBody0());
        btRigidBody* obB = static_cast<btRigidBody*>(contactManifold->getBody1());
        // May be there is contact obA and obB

        btPersistentManifold* contactManifold =  m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
        int numContacts = contactManifold->getNumContacts();
        for (int j=0;j<numContacts;j++)
        {
            btManifoldPoint& pt = contactManifold->getContactPoint(j);
            if (pt.getDistance()<0.f)
            {
                // One contact point is inside of another object
                // But some contacts are ignored
            }
        }
    }

また

直線速度と角速度の変化を確認します。(接触があったのか、どのオブジェクトが速度を変化させたのか、それがオブジェクトか減衰か、重力か、何らかの力場かは明らかではありません。


連絡先インパルスを含む連絡先情報が欲しいです。一部の接触は 1 フレームのシミュレーションで解決され、他のものは 2 フレームでインパルスが 2 倍低くなることに気付きました。(コードのデバッグを行いました。) 完全なインパルスで 1 つの連絡先通知を取得するのに最適です。

私がリストした方法のどれも、連絡先の完全な情報を提供してくれません。ボールがターゲットの近くを飛んでいて、ターゲットに触れていない場合でも、発射されることがあります。

それを行うために予想される方法は何ですか?

このような情報は、接触エネルギーが高い場合に衝撃音を再生したり、アニメーションを開始したりするために使用できます。

4

1 に答える 1

3

このコードは、可能な方向を示しているはずです

// some global constants needed

enum collisiontypes {
    NOTHING         = 0,    // things that don't collide
    BALL_BODY       = 1<<2, // is ball
    TARGET_BODY     = 1<<3  // is target
};

int ballBodyCollidesWith    = TARGET_BODY | BALL_BODY;  // balls collide with targets and other balls
int targetBodyCollidesWith  = BALL_BODY;    // targets collide with balls

// ...
// bodies creation

dynamicsWorld->addRigidBody(ballBody, BALL_BODY, ballBodyCollidesWith);

dynamicsWorld->addRigidBody(targetBody, TARGET_BODY, targetBodyCollidesWith);

//...
// find out whether a ball collides with a target

int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
    btRigidBody* obA = static_cast<btRigidBody*>(contactManifold->getBody0());
    btRigidBody* obB = static_cast<btRigidBody*>(contactManifold->getBody1());
    // May be there is contact obA and obB

    // ignore bodies that are not balls or targets
    if (
        (!(obA->getCollisionFlags() | BALL_TYPE) && !(obB->getCollisionFlags() | BALL_TYPE))    // there is no BALL_TYPE colliding
        ||
        (!(obA->getCollisionFlags() | TARGET_TYPE) && !(obB->getCollisionFlags() | TARGET_TYPE))    // there is no TARGET_TYPE colliding
        )
        continue; // no more searching needed

    btPersistentManifold* contactManifold =  m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
    int numContacts = contactManifold->getNumContacts();
    for (int j=0;j<numContacts;j++)
    {
        btManifoldPoint& pt = contactManifold->getContactPoint(j);

        printf("%f\n", pt.getAppliedImpulse()); // log to see the variation range of getAppliedImpulse and to chose the appropriate impulseThreshold
        if (pt.getAppliedImpulse() > impulseThreshold)
        {
                // increase score or something
                break; // no more searching needed
        }
    }
}
于 2012-11-22T19:36:44.520 に答える