I'm trying to make a ring tossing game in JMonkey, but when I tried using a Torus it just bounces over the pins(because of the collision spreads over the hollow centre).
I've been looking for a way to get the Torus to work, and alternatives for the ring, but I can't find anything which works.
Any tips or hints for a fix are really appreciated.
By default, the physics engine (Bullet) uses simple shapes that make calculating collisions easy and fast. The torus probably looks like a box to the physics engine. To make it hollow you can convert the mesh of the torus into a CollisionShape
that Bullet accepts.
Available classes are listed here: http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:physics
The GImpactCollisionShape
is one that will work for dynamic, concave objects. It comes with a constructor that conveniently converts your mesh.
However, a complex shape means more work for the engine. It's often sufficient to use a rough approximation as CollisionShape. Here's an example that uses a complex torus for display and a simpler one for the physics simulation:
public void simpleInitApp() {
Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/ShowNormals.j3md");
// Create pin
Cylinder cylinderMesh = new Cylinder(4, 12, 1.0f, 7.0f, true);
Geometry pin = new Geometry("Pin", cylinderMesh);
pin.setMaterial(mat);
pin.rotate(90 * FastMath.DEG_TO_RAD, 0, 0);
// Create a smooth ring
Torus torusMesh = new Torus(64, 48, 1.0f, 3.0f);
Geometry ring = new Geometry("Ring", torusMesh);
ring.setMaterial(mat);
ring.rotate(90 * FastMath.DEG_TO_RAD, 0, 0);
ring.rotate(0, 51 * FastMath.DEG_TO_RAD, 0);
ring.setLocalTranslation(0, 10, 0);
rootNode.attachChild(pin);
rootNode.attachChild(ring);
// Define the shape that the ring uses for collision checks
Torus simpleTorusMesh = new Torus(16, 12, 1.0f, 3.0f);
GImpactCollisionShape collisionShape = new GImpactCollisionShape(simpleTorusMesh);
ring.addControl(new RigidBodyControl(collisionShape, 0.1f));
// Default CollisionShape for the pin
pin.addControl(new RigidBodyControl(0));
BulletAppState bulletState = new BulletAppState();
stateManager.attach(bulletState);
bulletState.getPhysicsSpace().add(pin);
bulletState.getPhysicsSpace().add(ring);
cam.setLocation(new Vector3f(20, 5, 35));
cam.lookAt(new Vector3f(0, 4, 0), Vector3f.UNIT_Y);
flyCam.setMoveSpeed(30);
}