Skip to content

rvandoosselaer/Jme-es-physics

Repository files navigation

jme-es-physics jme-es-physics

A Minie Zay-ES integration for jMonkeyEngine.

How to use it

⚠️ This library is still under active development! The published version on jcenter is a SNAPSHOT version and could be changed at any time.

You can include this library in your gradle project by adding this in your build.gradle file.

repositories {
    maven {
        url  "https://dl.bintray.com/remyvd/rvandoosselaer" 
    }
}

dependencies {
    implementation 'com.rvandoosselaer:jme-es-physics:1.0.0'
}

Dependencies overview:

  • jMonkeyEngine version 3.3 or higher
  • Zay-ES version 1.3.1 or higher
  • Sio2 version 1.3.0 or higher
  • Minie version 1.5.0for33 or higher
implementation "org.jmonkeyengine:jme3-core:3.3.0-beta1"
implementation "com.github.stephengold:Minie:1.5.0for33"
implementation "com.simsilica:zay-es:1.3.1"
implementation "com.simsilica:sio2:1.3.0"

Get started

To use the ES based bullet integration you need to add the BulletSystem to the GameSystemManager. The BulletSystem also needs access to the EntityData and PhysicalShapeRegistry. That's it really!

The EntityData and PhysicalShapeRegistry can be provided in the constructor when initializing the BulletSystem. Or they can be injected automatically when they are registered as system-level objects to the GameSystemManager.

entityData = systems.register(EntityData.class, new DefaultEntityData());
shapeRegistry = systems.register(PhysicalShapeRegistry.class, new DefaultPhysicalShapeRegistry());
bulletSystem = systems.register(BulletSystem.class, new BulletSystem());

// registered system level objects can be retrieved using the AbstractGameSystem.getSystem() implementation
EntityData entityData = getSystem(EntityData.class);

or

EntityData entityData = new DefaultEntityData();
PhysicalShapeRegistry shapeRegistry = new DefaultPhysicalShapeRegistry();
bulletSystem = systems.register(BulletSystem.class, new BulletSystem(entityData, shapeRegistry));

The PhysicalShapeRegistry is used to link a CollisionShape to a physical entity using a PhysicalShape component.

PhysicalShapeRegistry shapeRegistry = new DefaultPhysicalShapeRegistry();
shapeRegistry.register(new PhysicalShape("cube"), new BoxCollisionShape(new Vector3f(0.5f, 0.5f, 0.5f)));

The library has a CollisionShapeHelper class with multiple static methods to facilitate the creation of CollisionShape objects.

An entity will be picked up by the BulletSystem when it has the following components:

  • Mass
  • PhysicalShape
  • WarpPosition

Other systems can hook in on the Bullet update loop and can be notified about updates of entities in the physics space using a PhysicalEntityListener.

A PhysicalEntityListener implementation can for example be used to publish Position components on a physical entity to update the location and rotation of the Model of the entity.

bulletSystem.addPhysicalEntityListener(new PositionPublisher());

public class PositionPublisher implements PhysicalEntityListener {

    ...
    
    @Override
    public void physicalEntityUpdated(PhysicalEntity physicalEntity) {
        entityData.setComponent(physicalEntity.getEntityId(), new Position(physicalEntity.getLocation(), physicalEntity.getRotation()));
    }
    
    ...

}

Demo

Two demo applications are included as examples.

The cubes demo is an application where you can shoot boxes and balls on a platform.

You can start the cubes demo using gradle:

$ ./gradlew :demo:cubes:run

The character demo is an application where you control a physics character in a level.

You can start the character demo using gradle:

$ ./gradlew :demo:character:run

Acknowledgements

Bullet documentation

Some information gathered about bullet during the creation of the Bullet Zay-ES integration library.

Continuous collision detection

CCD is short for Continuous Collision Detection, which is a workaround for a common problem in game physics: a fast moving body might not collide with an obstacle if in one frame it is "before" the obstacle, and in the next one it is already "behind" the obstacle. At no frame the fast moving body overlaps with the obstacle, and thus no response is created. This is what CCD is for. CCD checks for collisions in between frames, and thus can prevent fast moving objects from passing through thin obstacles.

Bullet has built-in support for CCD, but bodies have to be configured properly to enable CCD checks.

When checking for collision in between frames Bullet does not use the full collision shape (or shapes) of a body - this would make continuous collision detection too slow. Instead Bullet uses a sphere shape, the so-called "swept sphere". "swept" because the sphere is swept from the original position to the new position of the body. So, in order to enable CCD checks on a body we have to setup this sphere, and a CCD motion threshold:

fastMovingRigidBody.setCcdMotionThreshold(1e-7) (eg. 1e-7 = 1 x 10^-7 = 0.0000007)
fastMovingRigidBody.setCcdSweptSphereRadius(0.50)

We have to set up the swept sphere only on the fast moving dynamic bodies. There is no need to do anything for the static or slow moving obstacles. The CcdMotionTreshold is an amount of motion that is required to activate continuous collision detection.

Set the setCcdMotionThreshold to a value >0 or 0 to disable.

Capsule collision shape

The size of the capsule is set using a radius and a height value. These values are the radius of the top and bottom semi spheres and the radius and height of the cylinder. If you want a capsule with a radius of 1 and a height of 5, you should give a radius of 1 and a height of 3 to the capsule collison constructor. The final height of the capsule is the radius of the bottom sphere + the height of the cylinder + the radius of the top sphere.

This behaviour is simplified in the CollisionShapeHelper.createCapsuleShape(float radius, float height, boolean centerAtBottom). The height value in this factory method is the final totalling height of the capsule.

About

A Minie Zay-ES integration for jMonkeyEngine.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages