0
\$\begingroup\$

How can I detect when 2 collision objects collide with JBullet? Currently, all body types are going to be of type RigidBody. I have quite literally been trying to find the answer of this for over 2 months, and would highly appreciate it if someone could help me.

There is some random stuff about collision callback, but that never seems to work - Either there is missing classes, or the code just does not do what I want it to do (Or is something stupid like "check every singke collision object" to do this), and just other things that mean I have never got an answer to my question.

I need to know this to allow ships and a cannonballs to be able to collide and explode. The game is fully playable and has got collision detection manually implemented, however it takes up over 50% of my I7's CPU - Far too much.

Thank you if you can answer my question.

P.S. JBullet is being used on my server, not my client.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Collision callbacks are explained in http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers. This translates quite straightforward to JBullet. However if you have already tried and failed to follow that, I'll just provide the code I have been using myself.

First set-up a callback that is called on every physics iteration:

dynamicsWorld.setInternalTickCallback(new InternalTickCallback() {
    @Override
    public void internalTick(DynamicsWorld dynamicsWorld, float timeStep) {
        // Add your collision checks or other functionality here.
    }
}, null);

To detect collisions, you need to iterate all collision contacts in your internalTick callback:

Dispatcher dispatcher = dynamicsWorld.getDispatcher();
int manifoldCount = dispatcher.getNumManifolds();
for (int i = 0; i < manifoldCount; i++) {
    PersistentManifold manifold = dispatcher.getManifoldByIndexInternal(i);
    // The following two lines are optional.
    RigidBody object1 = (RigidBody)manifold.getBody0();
    RigidBody object2 = (RigidBody)manifold.getBody1();
    MyPhysicsObject physicsObject1 = (MyPhysicsObject)object1.getUserPointer();
    MyPhysicsObject physicsObject2 = (MyPhysicsObject)object2.getUserPointer();
    boolean hit = false;
    Vector3f normal = null;
    for (int j = 0; j < manifold.getNumContacts(); j++) {
        ManifoldPoint contactPoint = manifold.getContactPoint(j);
        if (contactPoint.getDistance() < 0.0f) {
            hit = true;
            normal = contactPoint.normalWorldOnB;
            break;
        }
    }
    if (hit) {
        // Collision happened between physicsObject1 and physicsObject2. Collision normal is in variable 'normal'.
    }
}

I have specified my own object pointer for each JBullet RigidBody using CollisionObject.setUserPointer(). In the collision callback I can then compare the objects with MyPhysicsObject physicsObject1 = (MyPhysicsObject)object1.getUserPointer();

\$\endgroup\$
3
  • \$\begingroup\$ I am so sorry for being stupid - Where does the second section of code you gave me go? Also, Many thanks for the answer. I get it much more now :). \$\endgroup\$
    – joehot200
    Commented Apr 14, 2014 at 20:11
  • \$\begingroup\$ It goes inside the internalTick implementation of the first snippet replacing the comment. \$\endgroup\$
    – msell
    Commented Apr 15, 2014 at 4:52
  • \$\begingroup\$ A year later, I'm still only just coming back to JBullet. int manifoldCount = dispatcher.getNumManifolds(); appears to be returning 0, any idea why? \$\endgroup\$
    – joehot200
    Commented Apr 19, 2015 at 10:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .