How Libbulletjme works

For physics simulation and collision detection, Libbulletjme uses the Bullet Physics SDK, a mature, open-source, 3-D physics simulator, released under a Zlib license.

To enable efficient simulation of moving meshes, Libbulletjme also incorporates Khaled Mamou’s Volumetric-Hierarchical Approximate Convex Decomposition (V-HACD) algorithm.

Native libraries

Bullet and V-HACD are written in C++, so Libbulletjme uses the Java Native Interface (JNI) to access their objects and methods.

All C++ source code in Libbulletjme (a modified partial snapshot of Bullet, a snapshot of V-HACD, and some "glue code") resides in its "native" directory. Before instantiating physics objects, a Libbulletjme application must dynamically load a native library of this code, compiled for the platform on which the app is executing.

Libbulletjme publishes native libraries for 14 different platforms:

  • Windows (32-bit and 64-bit),

  • Linux (x86-64, x86, arm, armhf, and aarch64),

  • macOS (x86-64, IA-32, and ARM64), and

  • Android (armeabi-v7a, arm64-v8a, x86, and x86_64).

32-bit and 64-bit versions of the same operating system count as distinct platforms!

For each platform, Libbulletjme builds 2 types of libraries:

  • "Debug" (for development use) and

  • "Release" (for production use).

Furthermore, native libraries come in various flavors, including:

All these native libraries share a common API, so a single JVM library suffices.

Collision objects, spaces, and shapes

Collision detection is organized around collision objects that interact in the context of a collision space. Collision objects can be soft (varying shape) or rigid (non-varying shape). Rigid objects can be mobile (moving) or static (non-moving). And mobile objects can be dynamic (driven by forces, torques, and impulses) or kinematic (driven directly by external calculations).

In Libbulletjme, collision spaces that simulate forces, torques, and impulses are referred to as physics spaces.

Each rigid collision object references a collision shape that describes the shape of its surface. Most collision shapes are scalable, allowing you to grow or shrink objects simply by varying the shape’s scale factors.

Coordinate systems and units

A collision object’s absolute location and orientation are quantified in physics-space coordinates, based on a right-handed Cartesian coordinate system.

With notable exceptions, Libbulletjme doesn’t specify real-world units for distance. Instead, its documentation refers to physics-space units (psu), which could be light-years or millimeters, depending on the application. Nor does Libbulletjme specify which axis serves as the "up" direction. If you use a Y-up coordinate system with a psu of one meter, then Libbulletjme’s default gravity will be roughly correct for the Earth’s surface. However, there are good reasons to use physics-space units other than meters.

Locations relative to a collision object’s center and subject to its rotation are quantified using local coordinates. The documentation distinguishes scaled local coordinates (measured in psu) from shape coordinates (which depend on scale factors).

Discrete time and collision detection

Within a physics space, simulation occurs in discrete steps of short duration. While it’s possible to vary these durations from step to step, a fixed duration (or time step) tends to yield more reproducible results.

Each simulation step consists of 4 phases:

  1. forward dynamics part one, to apply known forces and torques and predict the next position of each collision object,

  2. broadphase collision detection, to quickly determine (using axis-aligned bounding boxes) which object pairs might possibly collide,

  3. narrowphase collision detection, to compute actual contacts (if any) between between objects, and

  4. forward dynamics part 2, to apply contact forces, solve constraints, and update positions.

For fast-moving objects, Libbulletjme offers optional continuous collision detection (CCD) using swept spheres.

Direct buffers, garbage collection, and threading

Direct buffers used in Libbulletjme should have native byte order.

All other native objects created by Libbulletjme are carefully tracked using weak references.

Successful initialization of a native library causes Libbulletjme to start a daemon thread named "Physics Cleaner". Its purpose is to free any tracked native objects whose corresponding java objects have been garbage collected.

As a performance enhancement, Libbulletjme can parallelize certain for-loops on platforms that support OpenMP. To enable this feature, a multithreaded (Mt) native library must be loaded.

Next steps

For more detail about Bullet physics, download and read the Bullet User Manual.

To gain hands-on experience, proceed to the first tutorial page.