My balls don't collide

Hello everyone. Today I was trying some stuff and I wasn’t able to receive collision events by using a PhysicsCollisionListener.
After making a simple program to debug the problem I found what was going on.
In the following example I make two spheres collide, the simulation looks good, however the collision listener is not called. If I change the collision shape to a box, the collision is detected and the listener is called.
I thought only mesh to mesh collision wouldn’t work (and wouldn’t work at all). Is the sphere shape simply a mesh?
How can bullet run the physics simulation fine but fail to publish the event?

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Sphere;

public class CollisionTest extends SimpleApplication {

	public static void main(String[] args) {
		new CollisionTest().start();
	}

	@Override
	public void simpleInitApp() {
		BulletAppState bulletState = new BulletAppState();
		bulletState.setDebugEnabled(true);
		stateManager.attach(bulletState);
		stateManager.attach(new State());
	}

	private class State extends AbstractAppState {
		private Spatial ball1Spatial;
		private Spatial ball2Spatial;
		private Float counter = 0f;

		@Override
		public void initialize(AppStateManager stateManager, Application app) {
			super.initialize(stateManager, app);
			space().addCollisionListener(new CollisionListener());
			ball1Spatial = createBall();
			ball2Spatial = createBall();
			resetBalls();
		}

		@Override
		public void update(float tpf) {
			counter += tpf;
			if (counter > 1) {
				counter = 0f;
				resetBalls();
			}
		}

		public Spatial createBall() {
			Spatial ball = new Geometry("ball", new Sphere(8, 8, 1));
			Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
			mat.setColor("Color", ColorRGBA.Blue);
			ball.setMaterial(mat);
			// The Sphere doesn't register collisions?
			ball.addControl(new RigidBodyControl(new SphereCollisionShape(1), 1));
			// But Box works just fine!
			// ball.addControl(new RigidBodyControl(new BoxCollisionShape(Vector3f.UNIT_XYZ)));
			rootNode.attachChild(ball);
			space().add(ball);
			return ball;
		}

		public void resetBalls() {
			moveTo(ball1Spatial, new Vector3f(-5, 2, 0));
			push(ball1Spatial, Vector3f.UNIT_X);
			moveTo(ball2Spatial, new Vector3f(5, 2, 0));
			push(ball2Spatial, Vector3f.UNIT_X.negate());

		}

		public void moveTo(Spatial ball, Vector3f loc) {
			RigidBodyControl body = ball.getControl(RigidBodyControl.class);
			body.setPhysicsLocation(loc);
			body.clearForces();
			body.setLinearVelocity(Vector3f.ZERO);
		}

		public void push(Spatial ball, Vector3f dir) {
			ball.getControl(RigidBodyControl.class).applyImpulse(dir.mult(50f), Vector3f.ZERO);
		}

		public PhysicsSpace space() {
			return stateManager.getState(BulletAppState.class).getPhysicsSpace();
		}

	}

	private class CollisionListener implements PhysicsCollisionListener {

		@Override
		public void collision(PhysicsCollisionEvent event) {
			System.out.println("When two worlds collide!");
		}

	}
}
2 Likes

The SphereCollisionShape shouldn’t be related to meshes, at least for what documentation reports.

PS: I don’t want to belittle your help request, but the title of the thread is pretty hilarious :smile:

6 Likes

That’s what I assumed. By looking at the (java) code, it calls a native method to create the sphere.

I just couldn’t resist it :laughing:

I think this joke even has multiple layers :man_facepalming:

2 Likes

Came for the title, wasn’t left disappointed!

4 Likes

@xuan I would offer some advice, but this sounds rather like a personal problem. :wink:

3 Likes

Do the balls in your code explode or something? Or they just bounce off one another?

1 Like

What happens if you remove the setPhysicsLocation (for objects already in the physics space)?

This title made my day :joy:

1 Like

I just exploded with laughter when i saw this

Same thing. Either if I initialize both spheres in the same place (they repeal each other), or if I set the translation to the spatials before adding the physics controls (they bounce against each other) no event is registered.

I’d be surprised if this were a bug and wasn’t noticed before, seems such a simple use case.

Well the balls in the wall test example do collide so… Must be an edge case or something.

Must be. I tried with the TestCollisionListener example and the bullets collide just fine.
I’ve no idea what could it be, I cannot find any significant difference.

Usual process at this point is to either make the JME test look more like your code until it breaks or make your code look more like the test until it isn’t broken.

1 Like

Okay, it took me a while but I figured out what’s wrong. It’s a bug in versions 3.2.0-alpha1 and later (latest 3.2.1-stable at time or writing), it works fine in 3.1.0-stable.
I ran all my tests running a jar built with maven, no IDEs involved.

What’s more strange is why the TestCollisionListener worked for me. I normally code in eclipse but I run the tests from the SDK and I noticed that my code did work in the SDK and the test didn’t in eclipse. So I noticed that the SDK comes bundled with a weird build of the engine (jars are called something like jme3-core-3.2.0-v3.2-prealpha-sdk1-SNAPSHOT.jar :chimpanzee_woot: ). Possibly I have an old version of the SDK.
So I ran my code using the bundled bullet-native jar and the listener was called fine, I guess it’s an old build.

If it’s of any use, these are checksums of the different libbullet.so that were unpacked on each version

checksum-3.1.0-stable.txt eb714a47f59542ec236e3b5272ea2833 libbulletjme.so -> ok
checksum-3.2.0-sdk.txt    618ec47e907311c282b3a6d37eb18898 libbulletjme.so -> ok
checksum-3.2.0-alpha1.txt 41b582fc7a9434fc7e5dc832f1f57e38 libbulletjme.so -> fail
checksum-3.2.0-beta1.txt  41b582fc7a9434fc7e5dc832f1f57e38 libbulletjme.so -> fail
checksum-3.2.0-stable.txt 41b582fc7a9434fc7e5dc832f1f57e38 libbulletjme.so -> fail
checksum-3.2.1-stable.txt 41b582fc7a9434fc7e5dc832f1f57e38 libbulletjme.so -> fail

Since this is bug in the native library I suppose I should mention I run linux 4.9.0-5-amd64

4 Likes