两个实体之间的子弹碰撞回调

bullet collision callback between 2 bodies

本文关键字:子弹 碰撞 回调 之间 实体 两个      更新时间:2023-10-16

我有两个对象,一个球体和一个长方体,当其中一个与另一个碰撞时,它们会执行一些操作(即销毁长方体)。

我尝试了几种方法:

  • checkCollideWith始终返回true
  • contactPairTest-我不知道如何使用。它需要3个参数、2个对象和一个回调。我以为回调可以是我代码中的任何函数,但它并不是这样工作的

有人能举一个例子,当两个btRigidBodies(即bodyA和bodyB)碰撞时,如何调用一个方法,例如CollissionResult()吗?

也许这个例子将有助于解释这个概念。您必须定义一个新的类,该类派生自现有的抽象类。您可以用回调代码重写其中一个抽象类方法。然后创建派生类的对象,并将其传递给要调用回调的函数。这是一种非常常见的C++技术。

struct MyContactResultCallback : public ContactResultCallback
{
    btScalar addSingleResult(btManifoldPoint& cp,
        const btCollisionObjectWrapper* colObj0Wrap,
        int partId0,
        int index0,
        const btCollisionObjectWrapper* colObj1Wrap,
        int partId1,
        in index1)
    {
        // your callback code here
    }
};
MyContactResultCallback callback;
world.contactPairTest(bodyA, bodyB, callback);

我应该补充一点,我对这个图书馆一无所知。我刚看过文件。

编辑

显示如何将上下文成员添加到MyContactResultCallback

struct MyContactResultCallback : public ContactResultCallback
{
    MyContactResultCallback(some_type* ptr) : context(ptr) {}
    btScalar addSingleResult(btManifoldPoint& cp,
        const btCollisionObjectWrapper* colObj0Wrap,
        int partId0,
        int index0,
        const btCollisionObjectWrapper* colObj1Wrap,
        int partId1,
        in index1)
    {
        context->currentPoints += 10;
    }
    some_type* context;
};
MyContactResultCallback callback(ptr_to_some_object);
world.contactPairTest(bodyA, bodyB, callback);

ptr_to_some_object是指向具有要递增的currentPoints的对象的指针。我不知道那是什么类型的对象,所以我刚刚说了some_type,你可以用真正的类型来代替它。

这就是使用对象作为回调而不是函数的意义所在。如果回调是一个对象,则可以出于任何目的向其添加数据成员,而不能对函数执行此操作。

我发现最简单的方法是检查歧管。如果您只是询问调度程序,则不需要自定义类。

每次踏入世界后都执行此操作:

    btDispatcher* dp = world->getDispatcher();
    const int numManifolds = dp->getNumManifolds();
    for ( int m=0; m<numManifolds; ++m )
    {
            btPersistentManifold* man = dp->getManifoldByIndexInternal( m );
            const btRigidBody* obA = static_cast<const btRigidBody*>(man->getBody0());
            const btRigidBody* obB = static_cast<const btRigidBody*>(man->getBody1());
            const void* ptrA = obA->getUserPointer();
            const void* ptrB = obB->getUserPointer();
            // use user pointers to determine if objects are eligible for destruction.
            ...
            const int numc = man->getNumContacts();
            float totalImpact = 0.0f;
            for ( int c=0; c<numc; ++c )
                    totalImpact += man->getContactPoint(c).m_appliedImpulse;
            if ( totalImpact > threshold )
            {
                    // Here you can break one, or both shapes, if so desired.
            }
    }