2个机构之间的子弹碰撞回调

时间:2013-11-30 13:07:13

标签: c++ callback collision bullet

我有2个物体,一个球体和一个盒子,当一个物体与另一个物体碰撞时,它会做一些动作(即破坏盒子)。

我尝试了几种方法:

  • checkCollideWith始终返回true;
  • contactPairTest - 我不明白该怎么用。 它需要3个参数,2个对象和一个回调。我认为回调可以是我的代码中的任何函数,但它不能像那样工作。

有人可以举例说明如何调用方法,例如CollissionResult(),当2 btRigidBodies碰撞时(即bodyA和bodyB)?

2 个答案:

答案 0 :(得分:6)

也许这个例子有助于解释这个概念。您必须定义一个从现有抽象类派生的新类。您可以使用回调代码覆盖其中一个抽象类方法。然后,您可以创建派生类的对象,并将其传递给要调用回调的函数。这是一种常见的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,你可以用真实的类型代替它。

这是使用对象作为回调而不是函数的要点。如果回调是一个对象,您可以根据需要为其添加数据成员,但不能对函数执行此操作。

答案 1 :(得分:0)

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

每次踏入世界后,只需执行一次即可:

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