Collision Shape Factory objects pass through other physical objects

I’ve got a problem: my buggy that uses a collision shape with a CollisionShapeFactory keeps passing through the castle that has got a collision shape too.

Can anyone help?

The source code:

public void simpleInitApp() {
	// TODO Auto-generated method stub
	this.assetManager.registerLocator(
			"C:/Users/Dominykas/USB/Outcasts/Assets", FileLocator.class);
	pl = new PointLight();
	pl.setRadius(0);
	pl.setColor(ColorRGBA.White);
	pl.setPosition(new Vector3f(0, 3, 0));
	rootNode.addLight(pl);
	flyCam.setEnabled(true);
	flyCam.setMoveSpeed(100);
	bas = new BulletAppState();
	stateManager.attach(bas);
	bas.setDebugEnabled(true);
	Castle c = new Castle(assetManager, rootNode, bas);
	Spatial buggy = assetManager.loadModel("Models/Vehicles/Buggy/buggy.j3o");
	Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
	mat.setTexture("DiffuseMap", assetManager.loadTexture("Models/Vehicles/Tank/tank_diffuse.png"));
	buggy.setMaterial(mat);
	rootNode.attachChild(buggy);
	buggy.setLocalTranslation(0, 60, 0);
	CollisionShape shape = CollisionShapeFactory.createMeshShape(buggy);
	RigidBodyControl buggyPhy = new RigidBodyControl(shape,1);
	buggy.addControl(buggyPhy);
	bas.getPhysicsSpace().add(buggyPhy);
}

public Castle(AssetManager assetManager, Node rootNode, BulletAppState bas) {
		this.assetManager = assetManager;
		this.rootNode = rootNode;
		this.bas = bas;
		mesh = (Node) assetManager.loadModel("Scenes/Castle/Cube.mesh.xml");
		mesh.scale(60);
		Material mat = new Material(assetManager,
				"Common/MatDefs/Light/Lighting.j3md");
		mat.setTexture("DiffuseMap", assetManager
				.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));
		mesh.setMaterial(mat.clone());
		rootNode.attachChild(mesh);
		//com.jme3.bullet.collision.shapes.CollisionShape shape = CollisionShapeFactory
				//.createMeshShape(mesh);
		phy = new RigidBodyControl(0);
		mesh.addControl(phy);
		bas.getPhysicsSpace().add(phy);
	}

In the picture you posted it seems like the vehicle lays on the ground, so collision is working. Could it be that you did place your car not high enough (start position) ?

The picture might not be very accurate but the buggy falls through the floor.

Change
CollisionShape shape = CollisionShapeFactory.createMeshShape(buggy);
to
CollisionShape shape = CollisionShapeFactory.createDynamicMeshShape(buggy);

to see if it will fix

Please see this thread

Ok, so it solves the main issue but the framerate drops to about 2-3 FPS from 60. Is there a way to fix the poor framerate?

Of course it will drop :slight_smile: because you are using mesh accurate collision shape of your buggy. And it seems it is a high poly model .
You should try to use other non mesh accurate collision shapes instead.
Like HullCollisionShape or VHACDCollisionShape or …

How do I use a HullCollisionShape with a model exactly? I know that I need to supply a Mesh as an argument but how do I make a Geometry out of the imported model?

HullCollisionShape shape =
    new HullCollisionShape(buggy.getMesh());

see wiki page
https://jmonkeyengine.github.io/wiki/jme3/advanced/physics.html#create-a-collisionshape

I don’t think you get it: buggy is a Spatial as in Spatial buggy = assetManager.loadModel(modelPath); My question now is how do I turn the buggy, or to be more specific, a submesh of it into a Geometry?

You can cast it to Geometry !!
Node and Geometry are child classes of Spatial class.

Spatial buggy = (Geometry) assetManager.loadModel("");

Maybe I’m doing it wrong because the above line throws a ClassCastException.

Edit: the stack trace:

java.lang.ClassCastException: com.jme3.scene.Node cannot be cast to com.jme3.scene.Geometry
	at vehycles.Test.simpleInitApp(Test.java:47)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:220)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:211)
	at java.lang.Thread.run(Unknown Source)
Node buggyNode=(Node) assetManager.loadModel("Models/Vehicles/Buggy/buggy.j3o");
Geometry buggyGeo=(Geometry) buggyNode.getChild("submesh name");
            Node buggyNode = (Node)assetManager.loadModel("Models/Vehicles/Buggy/buggy.j3o");
		Geometry buggyGeometry = (Geometry) buggyNode.getChild("buggy");
		Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
		mat.setTexture("DiffuseMap", assetManager.loadTexture("Models/Vehicles/Tank/tank_diffuse.png"));
		buggyNode.setMaterial(mat);
		rootNode.attachChild(buggyNode);
		buggyNode.setLocalTranslation(0, 60, 0);
		HullCollisionShape shape = new HullCollisionShape(buggyGeometry.getMesh());
		RigidBodyControl buggyPhy = new RigidBodyControl(shape,1);
		buggyNode.addControl(buggyPhy);
		bas.getPhysicsSpace().add(buggyPhy);

This code still causes ClassCastException and the stack trace points to this line:
Geometry buggyGeometry = (Geometry) buggyNode.getChild("buggy");

The thing is we don’t know how the scene graph of your model looks like. Open it in the scene composer and see if it has some subnodes.

If there are some and you don’t want to go hard coded through all those nodes, then use this method:

buggyNode.depthFirstTraversal((Spatial spatial) -> {
   if (spatial instanceof Geometry) {
    //add collision shape
   }
}
1 Like

Ok, now that I’ve taken a look at the file using JME3 Xbuf viewer the app does not crash but still the framerate is very choppy.

Edit: convex shapes appearently will not do.