Friday, December 13, 2019

java - JBullet - Detecting when 2 objects collide?


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.



Answer




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


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...