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\$
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();

|improve this answer|||||
\$\endgroup\$
  • \$\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 Apr 14 '14 at 20:11
  • \$\begingroup\$ It goes inside the internalTick implementation of the first snippet replacing the comment. \$\endgroup\$ – msell Apr 15 '14 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 Apr 19 '15 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.