How to add Minie to an existing project

If you’re creating a JMonkeyEngine desktop application from scratch, the BasicGame-on-Gradle project provides a good starting point.

Adding Minie to an existing JMonkeyEngine project is a 7-step process:

  1. Remove any libraries that might interfere with Minie.

  2. Add libraries to the classpath.

  3. Load the native library.

  4. Create, configure, and attach a BulletAppState, if the application doesn’t already do so.

  5. Configure the PhysicsSpace, if the application doesn’t already do so.

  6. Create physics controls, collision objects, and joints and add them to the physics space, if the application doesn’t already do so.

  7. Test and tune as necessary.

Remove libraries that might interfere

If any directory where the application might run contains files named "libbulletjme.so" or "bulletjme.dll" or "libbulletjme.dylib", you should remove those files. Those filenames are used by JMonkeyEngine when it loads the native library, and you don’t want it to load the wrong one!

Also, Minie replaces (and is thus incompatible with) the following JMonkeyEngine libraries:

  • jme3-bullet

  • jme3-bullet-native

  • jme3-bullet-native-android, and

  • jme3-jbullet.

Before adding Minie, you should remove these libraries from the project so they won’t interfere with Minie.

Gradle-built projects

  1. Look for artifacts with those names in the dependencies section(s) of the project’s "*.gradle" file(s).

  2. Remove those dependencies.

Maven-built projects

  1. Look for artifacts with those IDs in the dependencies section(s) of the project’s "pom.xml" file.

  2. Remove those dependencies.

Ant-built projects

Open the project’s properties in the IDE (JME SDK or NetBeans):

  1. Right-click on the project (not its assets) in the "Projects" window.

  2. Select Properties to open the "Project Properties" dialog.

  3. Under "Categories:", click on Libraries.

  4. Click on the Compile tab.

  5. Look for incompatible libraries in the "Compile-time Libraries" listbox. Select them and click on the Remove button.

  6. Click on the OK button to exit the "Project Properties" dialog.

Add libraries to the classpath

Minie comes pre-built as a single library that includes both Java classes and native libraries. The Minie library depends on:

and those libraries depend on other JVM libraries.

For projects built using Gradle or Maven, it’s usually sufficient to specify the dependency on the Minie Library. Build tools should automatically resolve the remaining dependencies.

Gradle-built projects

Add to the project’s "build.gradle" file:

repositories {
    mavenCentral()
}
dependencies {
    implementation 'com.github.stephengold:Minie:8.0.0'
}

For some older versions of Gradle, it’s necessary to replace implementation with compile.

Maven-built projects

Add to the project’s "pom.xml" file:

<repositories>
    <repository>
      <id>mvnrepository</id>
      <url>https://repo1.maven.org/maven2/</url>
    </repository>
</repositories>

<dependency>
  <groupId>com.github.stephengold</groupId>
  <artifactId>Minie</artifactId>
  <version>8.0.0</version>
</dependency>

Ant-built projects

Ant doesn’t know about transitive dependencies, so you’ll need to resolve them manually. Furthermore, in order to use the latest Minie release, you’ll need version 3.6.1 JMonkeyEngine libraries. (You can still use a JME 3.2 or 3.3 SDK, however.) For more information about the libraries Minie depends on, see the Library version dependencies page.

Download the Minie library and its dependencies from GitHub and/or Maven Central:

You’ll definitely want the class JARs and probably the "-sources" and "-javadoc" JARs as well.

Open the project’s properties in the IDE (JME SDK or NetBeans):

  1. Right-click on the project (not its assets) in the "Projects" window.

  2. Select Properties to open the "Project Properties" dialog.

  3. Under "Categories:", click on Libraries.

  4. Click on the Compile tab.

  5. Add the Heart class JAR:

    1. Click on the Add JAR/Folder button.

    2. Navigate to the download directory.

    3. Select the "Minie-8.0.0.jar" file.

    4. Click on the Open button.

  6. (optional) Add JARs for javadoc and sources:

    1. Click on the Edit button.

    2. Click on the Browse…​ button to the right of "Javadoc:"

    3. Select the "Minie-8.0.0-javadoc.jar" file.

    4. Click on the Open button.

    5. Click on the Browse…​ button to the right of "Sources:"

    6. Select the "Minie-8.0.0-sources.jar" file.

    7. Click on the Open button button again.

    8. Click on the OK button to close the "Edit Jar Reference" dialog.

  7. Add the other JVM libraries in a similar manner.

  8. Click on the OK button to exit the "Project Properties" dialog.

Load the native library

In a conventional JMonkeyEngine application, the required native libraries get loaded automatically by Application.start().

If your application doesn’t invoke Application.start(), load Minie’s native library before instantiating any physics objects:

NativeLibraryLoader.loadNativeLibrary("bulletjme", true);

For Minie to work on Android platforms running Marshmallow (6.0) or higher, make sure the extractNativeLibs flag is set to true in the "application" element of the "AndroidManifest.xml" manifest.

Attach a BulletAppState

Strictly speaking, Minie doesn’t require a BulletAppState. However, the appstate does provide a convenient interface for configuring, accessing, updating, and debugging a PhysicsSpace.

If the application already has a BulletAppState, that code might work with Minie. If not, here is a snippet to guide you:

import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;

// ...

@Override
public void simpleInitApp() {
    BulletAppState bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);

Initialization order matters. A BulletAppState can’t be instantiated until the native library is loaded, which (for desktop apps) occurs during Application.start(). That’s why the following snippet fails:

static BulletAppState bulletAppState = new BulletAppState();

By default, debug visualization is disabled. To enable it, use:

bulletAppState.setDebugEnabled(true); // default=false

Other BulletAppState parameters, used to customize debug visualization, are described on the troubleshooting page.

Techniques to simulate physics without using BulletAppState are described on the physics-without-appstates page.

Configure the PhysicsSpace

Attaching a BulletAppState instantiates a PhysicsSpace that the application can access immediately:

PhysicsSpace space = bulletAppState.getPhysicsSpace();

Physics simulation can run with a fixed time step or a variable time step. The default configuration is a fixed time step of 1/60th of a second with up to 4 simulation steps per frame.

To configure a variable time step with a maximum of 0.25 seconds:

space.setMaxSubSteps(0);
space.setMaxTimeStep(0.25f);

To configure a fixed time step of 0.01 second with up to 6 simulation steps per frame:

space.setAccuracy(0.01f);
space.setMaxSubSteps(6);
setAccuracy() has no effect when maxSubSteps==0, while setMaxTimeStep() has no effect when maxSubSteps>0.

Each physics space has a gravity vector, which is typically applied to bodies as they get added to the space. To simulate a zero-gravity environment, set the gravity of the space to zero:

space.setGravity(Vector3f.ZERO);

Create and add collision objects

Collision objects come in many different types:

  • bodies (PhysicsBody)

    • soft bodies (PhysicsSoftBody)

    • rigid bodies (PhysicsRigidBody)

      • vehicles (PhysicsVehicle)

  • ghost objects (PhysicsGhostObject)

  • characters (PhysicsCharacter)

  • colliders (MultiBodyCollider)

You can either create them directly, using the constructors:

float radius = 2f;
CollisionShape sphere2 = new SphereCollisionShape(radius);
PhysicsGhostObject ghost1 = new PhysicsGhostObject(sphere2);
float mass = 1f;
PhysicsRigidBody body1 = new PhysicsRigidBody(sphere2, mass);

or indirectly, by adding physics controls to scene-graph spatials:

float radius = 2f;
CollisionShape sphere2 = new SphereCollisionShape(radius);

Node ghostNode1 = new Node("ghostNode1");
GhostControl gc1 = new GhostControl(sphere2);
ghostNode1.addControl(gc1);

Node rigidNode1 = new Node("rigidNode1");
float mass = 1f;
RigidBodyControl rbc1 = new RigidBodyControl(sphere2, mass);
rigidNode1.addControl(rbc1);

Either way, the objects aren’t simulated unless they’re added to a space.

Summary

  • Before adding Minie to an application, remove all other physics libraries.

  • BulletAppState provides a convenient interface for configuring, accessing, updating, and debugging a physics space.

  • Collision objects can be created 2 ways:

    • directly, using the constructors

    • indirectly, by adding physics controls to the scene graph.

  • Collision objects aren’t simulated unless they’re added to a space.