2

I have 2 objects, a sphere and a box that, when one collides with the other, will do some action (i.e. destroy the box).

I have tried several ways:

  • checkCollideWith always returns true;
  • contactPairTest - this I do not understand how to use. It takes 3 arguments, the 2 objects and a callback. I thought that the callback can be any function in my code, but it doesn't work like that.

Could someone please give an example of how to call a method, for example CollissionResult(), when 2 btRigidBodies collide (i.e. bodyA and bodyB)?

bogdan.css
  • 355
  • 6
  • 17
  • A quick check of the doucmentation show that contactPairTest expects an object whose type is derived from the abstract class ContactResultCallback. So your question is how to do that? – john Nov 30 '13 at 13:17

2 Answers2

6

Maybe this example will help explain the concept. You have to define a new class, derived from an existing abstract class. You override one of the abstract classes methods with your callback code. You then create an object of the derived class and pass that to the function you want to call the callback. It's a common enough C++ technique.

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);

I should add that I nothing whatsoever about this library. I've just read the docs.

EDIT

Showing how to add a context member to 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 is the pointer to the object with the currentPoints that you want to increment. I don't know what type of object that is, so I've just said some_type, you can replace that with whatever the real type is.

This is the point of using an object as a callback instead of a function. If the callback is an object you can add data members to it for whatever purpose you want, you cannot do that to a function.

john
  • 85,011
  • 4
  • 57
  • 81
  • hey there. Thanks for the reply. I have tried your example, then made a myContactResultCallback object `MyContactResultCallback callback;` and then called the contactPairTest method `bt_dynamicsWorld->contactPairTest(bodyA, bodyB, callback);`. Running resulted in a error saying that the addSingleResult needed to return a value, so I added `return 0;`. This allowed the program to run, but when I collided the 2 objects, the callback was not called (the 2 object clearly collide as the bounce back) – bogdan.css Nov 30 '13 at 14:05
  • 1
    @b0Gd4N Well, I'm afraid I've helped you as much as I can (i.e. with the C++ syntax). As I said I don't know this library at all. – john Nov 30 '13 at 14:11
  • the reason it did not work was because I forgot to add the `collisionFlags` to both objects. So now I have the 2 objects colliding and calling the callback, however I am having another issue: right after the comment `// your callback code here` I have an output that reports the collision, and it works. After this I want to increment a variable that was declared as public in the header file, so it should be accessible everywhere. But when I write `currentPoints += 10`, I get an error `a nonstatic member reference must be relative to a specific object`. How can I get pass this? – bogdan.css Dec 04 '13 at 21:25
  • @b0Gd4N That's the beauty of having callbacks as objects. Add a pointer to the `MyContactResultCallback` struct. The pointer points to the object that has the variable you want to increment. Then you can use that pointer to perfrom the increment from inside `MyContactResultCallback::addSingleResult` – john Dec 05 '13 at 06:37
  • I have been struggling to make this pointer for a while now. I tried to add another param to the addSingleResult method, but then when I make a instance of the struct I get an error `addSingleResult is not overridable`. I don' really understand how exactly I have to do what you said. – bogdan.css Dec 06 '13 at 12:17
  • You add the pointer to `MyContactResultCallback`, I've updated the answer. – john Dec 06 '13 at 13:05
  • Can you elaborate on how you set the collision flags? I think I'm in an identical situation; have set up call back but not getting one. – livin_amuk Oct 14 '19 at 00:32
0

I found the easiest way is to check the manifolds. No custom classes needed if you just ask the dispatcher.

Just execute this each time after stepping the world:

    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.
            }
    }
Bram
  • 7,440
  • 3
  • 52
  • 94