2

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

我尝试了几种方法:

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

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

4

2 回答 2

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,你可以用任何真正的类型来替换它。

这就是使用对象作为回调而不是函数的要点。如果回调是一个对象,您可以将数据成员添加到您想要的任何目的,您不能对函数执行此操作。

于 2013-11-30T13:26:30.410 回答
0

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

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

    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.
            }
    }
于 2018-11-02T20:50:51.033 回答