How to add Libbulletjme to an existing project

Adding Libbulletjme to an existing Java project is a 6-step process:

  1. Add libraries to the classpath.

  2. Load the native library.

  3. Create and configure a physics space.

  4. Create and configure collision objects and add them to the physics space.

  5. Simulate the physics space.

  6. Test and tune as necessary.

Add a libraries to classpath

Libbulletjme requires at least 2 libraries: a JVM library and a native library.

Pre-built Libbulletjme libraries are available from from Maven Central.

Build types: use "Debug" native libraries for development and troubleshooting, then switch to "Release" libraries for performance testing and production.

Build flavors: use "Dp" to simulate large worlds (>1000 units in diameter) otherwise use "Sp".

Gradle-built Android projects

Libbulletjme comes pre-built for Android as a pair of AARs (one for each build type). Each AAR includes both the JVM library and all necessary native libraries.

I suggest starting out with the Debug-flavored AAR. Add to the relevant "build.gradle" or "build.gradle.kts" file:

repositories {
    mavenCentral()
}
dependencies {
    implementation(
            group: "com.github.stephengold",
            name: "Libbulletjme-Android",
            version: "22.0.1",
            classifier: "SpDebug",
            ext: "aar"
    )
}

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

Gradle-built desktop projects

Libbulletjme comes pre-built for desktops as a platform-independent JVM library plus a set of (separately-packaged) native libraries.

Because of how releases are built, the desktop JVM library is released under 6 distinct names (artifact IDs). In contrast, each desktop native library is specific to a particular platform, build type, and flavor.

I suggest starting with the platform-independent JVM library plus the "SpDebug" native library for your development environment. For a "Linux on x86_64" environment, add to the relevant "build.gradle" or "build.gradle.kts" file:

repositories {
    mavenCentral()
}
dependencies {
    // JVM library:
    implementation("com.github.stephengold:Libbulletjme-Windows64:22.0.1")

    // native libraries:
    runtimeOnly("com.github.stephengold:Libbulletjme-Linux64:22.0.1:SpDebug")
        // Native libraries for other platforms could be added.
}
  • For a 64-bit MS-Windows environment, replace "Linux64" with "Windows64".

  • For an "Apple silicon" Mac environment, replace "Linux64" with "MacOSX_ARM64".

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

Load the native library

You must load Libbulletjme’s native library before instantiating any physics objects.

Android projects

Add to your physics initialization:

System.loadLibrary("bulletjme");

Desktop projects

The JSnapLoader library may be used for this purpose. Add to the relevant "build.gradle" or "build.gradle.kts" file:

dependencies {
    implementation("io.github.electrostat-lab:snaploader:1.0.0-stable")
}

Add to your physics initialization:

import electrostatic4j.snaploader.LibraryInfo;
import electrostatic4j.snaploader.LoadingCriterion;
import electrostatic4j.snaploader.NativeBinaryLoader;
import electrostatic4j.snaploader.filesystem.DirectoryPath;
import electrostatic4j.snaploader.platform.NativeDynamicLibrary;
import electrostatic4j.snaploader.platform.util.PlatformPredicate;

// ...

LibraryInfo info = new LibraryInfo(
        new DirectoryPath("linux/x86-64/com/github/stephengold"),
        "bulletjme", DirectoryPath.USER_DIR);
NativeBinaryLoader loader = new NativeBinaryLoader(info);
NativeDynamicLibrary[] libraries = new NativeDynamicLibrary[]{
    new NativeDynamicLibrary("native/linux/arm64", PlatformPredicate.LINUX_ARM_64),
    new NativeDynamicLibrary("native/linux/arm32", PlatformPredicate.LINUX_ARM_32),
    new NativeDynamicLibrary("native/linux/x86_64", PlatformPredicate.LINUX_X86_64),
    new NativeDynamicLibrary("native/osx/arm64", PlatformPredicate.MACOS_ARM_64),
    new NativeDynamicLibrary("native/osx/x86_64", PlatformPredicate.MACOS_X86_64),
    new NativeDynamicLibrary("native/windows/x86_64", PlatformPredicate.WIN_X86_64)
};
loader.registerNativeLibraries(libraries).initPlatformLibrary();
loader.loadLibrary(LoadingCriterion.INCREMENTAL_LOADING);

Create a physics space

There are many constructors and options. Here’s the simplest way:

import com.jme3.bullet.PhysicsSpace;
PhysicsSpace physicsSpace = new PhysicsSpace(PhysicsSpace.BroadphaseType.DBVT);

Create and add objects

Collision objects come in many different types:

  • bodies (PhysicsBody)

    • soft bodies (PhysicsSoftBody)

      • deformables (ReducedDeformableBody)

    • rigid bodies (PhysicsRigidBody)

      • vehicles (PhysicsVehicle)

  • ghost objects (PhysicsGhostObject)

  • characters (PhysicsCharacter)

  • colliders (MultiBodyCollider)

Here’s a code fragment that creates 2 objects, a ghost object and a rigid body that share a common shape:

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

Collision objects aren’t simulated unless they’re added to a physics space. The best way is to use addCollisionObject():

physicsSpace.addCollisionObject(ghost1);
physicsSpace.addCollisionObject(body1);

Simulate the physics space

To simulate a single 20-millisecond step:

float timeStep = 0.02f; // in seconds
int maxSteps = 0; // for a single step of the specified duration
physicsSpace.update(timeStep, maxSteps);

In real-time simulation, the interval between updates will vary. However, it’s best to use steps of equal size.

To attempt simulation of a specific time interval using the configured step size:

physicsSpace.update(intervalSeconds);

HelloLibbulletjme

HelloLibbulletjme (also in Kotlin) is a complete console application (no graphics) that serves as a starting point for using Libbulletjme.

It illustrates:

  1. loading a native library

  2. creating a PhysicsSpace

  3. creating 2 collision objects and adding them to the space

  4. simulating 50 steps

HelloLibbulletjme is the first in a series of tutorial apps designed for hands-on learning. I expect you to not only study the source code, but to actually run the app as well. Take time now to set up a software development environment for this purpose!

For instance, if you install Git and a Java Development Kit, you should be able to launch tutorial apps from a command shell, like so:

  1. git clone https://github.com/stephengold/LbjExamples.git

  2. cd LbjExamples

  3. ./gradlew :apps:HelloLibbulletjme

Summary

  • Two libraries are required: a JVM library and a native library.

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