Physics simulation without appstates

The BulletAppState class provides a convenient interface for configuring, accessing, updating, and debugging a PhysicsSpace.

However, if an application doesn’t require debug visualization, it can instantiate a physics space directly and update it explicitly.

HelloUpdate is a simple application that demonstrates direct instantiation and explicit updating.

Furthermore, an application running in a headless environment (such as a server) might not even need a scene graph. By instantiating collision objects directly (not using physics controls), you can simulate physics without a scene graph.

And by using NativeLibraryLoader to explicitly load the native library, such applications can completely avoid initializing JMonkeyEngine.

HelloConsole is a console application that demonstrates explicitly loading the native library.

For applications without a scene graph, consider using Libbulletjme instead of Minie.


Both examples used the simplest PhysicsSpace constructor, which is fine for most applications. However there are actually different 8 ways to directly instantiate a physics space:

PhysicsSpace space1 = new PhysicsSpace(worldMin, worldMax, broadphase, solver);
PhysicsSpace space2 = new PhysicsSpace(worldMin, worldMax, broadphase);
PhysicsSpace space3 = new PhysicsSpace(worldMin, worldMax);
PhysicsSpace space4 = new PhysicsSpace(broadphase);
PhysicsSpace space5 = new PhysicsSoftSpace(worldMin, worldMax, broadphase);
PhysicsSpace space6
        = new MultiBodySpace(worldMin, worldMax, broadphase, solverType);
PhysicsSpace space7 = new MultiBodySpace(worldMin, worldMax, broadphase);
PhysicsSpace space8 = new PhysicsSoftSpace(broadphase);

The first 4 constructors can be used only if soft bodies and multibodies will not be added to the space. Construct a PhysicsSoftSpace to enable soft-body physics. Construct a MultiBodySpace to enable multi-body physics.

For broadphase and solver, stick with DBVT and SI respectively, unless you understand what you’re doing.

The world bounds are used only by the sweep-and-prune broadphase accelerators (AXIS_SWEEP_3 and AXIS_SWEEP_3_32). The SIMPLE and DBVT accelerators ignore them.


If the solver argument is omitted, then a Sequential Impulse (SI) solver will be used.

If the broadphase argument is omitted, then the incremental 3-D sweep-and-prune (AXIS_SWEEP_3) broadphase accelerator will be used.

If broadphase is AXIS_SWEEP_3 or AXIS_SWEEP_3_32 and the worldMin/worldMax arguments are omitted, then the physics space will extend from (-10000, -10000, -10000) to (+10000, +10000, +10000).

Updating the physics space

PhysicsSpace offers 3 update methods:

space.update(timeInterval, maxSteps, doEnded, doProcessed, doStarted);
space.update(timeInterval, maxSteps);

To single-step the simulation, specify maxSteps = 0. The time step will be timeInterval seconds. Specifying the time step this way allows it to vary from step to step, without regard for space.getAccuracy() or space.maxTimeStep().

To attempt real-time simulation, specify maxSteps > 0. The time step will be space.getAccuracy() and up to maxSteps steps will be simulated for each update.

If the maxSteps argument is omitted, space.maxSubSteps() will be used. And if space.maxSubSteps() == 0, then the time step will be capped at space.maxTimeStep() seconds (as with a BulletAppState).

If you don’t need all 3 kinds of contact callbacks, you can improve simulation efficiency by specifying false for doEnded, doProcessed, and/or doStarted.


  • It’s possible to instantiate a physics space directly and update it explicitly.

  • It’s possible to load the native library explicitly and thus avoid initializing JMonkeyEngine.

  • Physics simulation doesn’t require a scene graph.