Home

Awesome

jolt-jni

The Jolt-jni Project provides JVM bindings for Jolt Physics, to facilitate physics simulation in JVM languages such as Java and Kotlin.

Source code (in Java and C++) is provided under an MIT license.

<a name="toc"></a>

Contents of this document

<a name="translate"></a>

Translating Jolt Physics applications into Java

There’s close correspondence between the class/method names of Jolt Physics and jolt-jni. For example:

Things become slightly more interesting when C++ templates and public member data are involved. For instance:

For a couple well-known Jolt Physics examples, line-for-line translations into Java are provided.

Jump to the table of contents

<a name="add"></a>

How to add jolt-jni to an existing project

Jolt-jni comes pre-built as a platform-independent JVM library plus a set of native libraries, all downloadable from Maven Central.

Current jolt-jni releases provide the JVM library under 6 distinct names (artifact IDs). They also provide 24 native libraries, each specific to a particular platform, build type, and build flavor.

Your runtime classpath should include a JVM library plus 1-to-6 native libraries: a native library for each platform on which the code will run.

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 meters in diameter) otherwise use "Sp".

Gradle-built projects

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

repositories {
    mavenCentral()
}
dependencies {
    // JVM library:
    implementation("com.github.stephengold:jolt-jni-Linux64:0.9.3")

    // native libraries:
    runtimeOnly("com.github.stephengold:jolt-jni-Linux64:0.9.3:DebugSp")
    // Native libraries for other platforms could be added.
}

Jump to the table of contents

<a name="build"></a>

How to build jolt-jni from source

Initial build

  1. Install a Java Development Kit (JDK), if you don't already have one.
  2. Point the JAVA_HOME environment variable to your JDK installation: (In other words, set it to the path of a directory/folder containing a "bin" that contains a Java executable. That path might look something like "C:\Program Files\Eclipse Adoptium\jdk-17.0.3.7-hotspot" or "/usr/lib/jvm/java-17-openjdk-amd64/" or "/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home" .)
  1. Download and extract the jolt-jni source code from GitHub:
  1. (optional) Edit the "gradle.properties" file to configure the build.
  2. Run the Gradle wrapper:

After a successful build, artifacts will be found in "build/libs".

Other tasks

You can run the "hello world" example app:

You can run various scenes in the "performance test" example app:

You can install the artifacts to your local Maven repository:

You can restore the project to a pristine state:

Jump to the table of contents

<a name="free"></a>

Freeing native objects

In long-running applications, it's important to free objects that are no longer in use, lest the app run out of memory.

Here it's important to distinguish between JVM objects and native objects. A handful jolt-jni classes are implemented entirely in Java, notably: Color, Float3, Plane, Quat, RVec3, UVec4, Vec3, and Vec4. Apart from these special classes, every JVM object in jolt-jni is an instance of JoltPhysicsObject, which implies it has a corresponding native object assigned to it.

For instance, when a jolt-jni app instantiates a matrix using new Mat44(), both a JVM object and a native object are created. The app can't access the native object directly; it can only invoke methods exposed by the JVM object.

While JVM objects get reclaimed automatically (in batches, by a garbage collector) after they become unreachable, jolt-jni provides several mechanisms for reclaiming native objects.

In the simple case of a matrix instantiated using matrix = new Mat44(), the native object can be freed:

In native code, convention dictates that when a class allocates memory, it assumes responsibility for freeing it. For this reason, jolt-jni applications cannot free objects created implicitly by Jolt Physics.

For instance, when an app invokes getBodyLockInterface() on a PhysicsSystem, a new JVM object is returned. However, that JVM object refers to a pre-existing native object (the one Jolt Physics allocated while initializing the PhysicsSystem). Thus, the application need not (and cannot) free the native object separately from the PhysicsSystem that contains it. On such "contained" objects, close() is a no-op, because the JVM object doesn't "own" its assigned native object.

Another case where a JoltPhysicsObject doesn't own its assigned native object is when the object implements reference counting. In this case, responsibility for freeing the native object (called the "target") is shared among other objects (called "references") that refer to it. Jolt-jni classes that implement reference counting are exactly those that implement the RefTarget interface. They include BaseCharacter, Constraint, ConstraintSettings, GroupFilter, PhysicsMaterial, PhysicsScene, Ragdoll, Shape, ShapeSettings, VehicleController, and all their subclasses. On RefTarget objects, close() is (again) a no-op, because the JVM object doesn't own its assigned native object.

The simplest way to create a reference is to invoke target.toRef(). References are themselves instances of JoltPhysicsObject, of course. (And please note that jolt-jni reference counting is completely orthogonal to Java references, strong, weak, or otherwise.)

The only way to free the assigned native object of a RefTarget is to decrement its reference count from one to zero. This implies creating one or more references and then freeing them all, either explicitly, implicitly, or automatically.

As long as a reference is active, its target cannot be freed. Nor can a target be freed if no reference to it has been created (because in that case its reference count is already zero). Nor can it be freed if reference counting is disabled by invoking target.setEmbedded().

Jump to the table of contents

<a name="links"></a>

External links

Jump to the table of contents