Scaling Ammo.js World: Impact on Physics Stability
Scaling the entire simulation world in ammo.js (the JavaScript port of the Bullet Physics engine) by a factor of 10 has a profound impact on simulation stability, collision accuracy, and performance. While scaling up can resolve issues related to extremely small fast-moving objects, it also introduces challenges regarding gravity, collision margins, and time-step calculations. Understanding how ammo.js handles units of measurement is critical to ensuring a stable, realistic physics simulation after scaling.
The Optimal Scale of Bullet Physics
The underlying Bullet Physics engine is optimized for objects sized between 0.05 and 10.0 units (ideally where 1 unit equals 1 meter). If your original simulation featured very small objects—such as pebbles, small debris, or thin walls measuring under 0.05 units—scaling the world up by a factor of 10 improves numerical precision. It prevents floating-point round-off errors and minimizes the chances of objects clipping or falling through one another, a phenomenon known as “tunneling.”
However, if your objects were already within the optimal size range, scaling them up by 10 (making them 10 to 100 units large) can cause objects to behave sluggishly, as the engine perceives them as massive, slow-moving structures.
Necessary Adjustments for Scaling Up
Simply multiplying the size of your 3D meshes and collision shapes by 10 is not enough. To maintain stability and realistic behavior, several parameters must be adjusted proportionally:
1. Gravity and Forces
If you scale the world dimensions up by 10, objects must travel 10 times the absolute distance to cover the same relative distance. If you keep the default gravity at -9.8 units/s², falling objects will appear to move in slow motion. To maintain the same relative acceleration, you must scale gravity up by the same factor: * New Gravity: -98.0 units/s²
Similarly, linear forces and impulses applied to rigid bodies must be scaled up to overcome the increased inertia of larger scale shapes.
2. Collision Margins
Ammo.js relies on a “collision margin” (defaulting to 0.04 units) around shapes to detect contacts before they penetrate. * Relative Shrinkage: When you scale your objects up by 10, a margin of 0.04 units becomes relatively 10 times smaller compared to the object’s volume. This can lead to visible jittering or penetration because the buffer zone is too thin. * Adjustment: You should increase the collision margins of your shapes proportionally to maintain the same buffer ratio relative to the object sizes.
3. Velocities and Time Steps
With a larger scale, objects will move at higher absolute velocities
(e.g., 100 units/s instead of 10 units/s) to cover the same visual
distance in the same time frame. * Increased Tunneling
Risk: Fast-moving objects are prone to passing completely
through thin colliders within a single physics step. *
Adjustment: To counter this, you must decrease the
physics time step (fixedTimeStep) and increase the maximum
number of substeps in your world step function:
javascript // Example: Standard step vs adjusted step for high velocity physicsWorld.stepSimulation(deltaTime, 10, 1/120);
Using a step size of 1/120 or 1/240 seconds instead of the default 1/60
seconds ensures the engine calculates collisions frequently enough to
catch fast-moving, scaled-up objects.
4. Inertia and Mass
While mass is a relative scalar value in physics engines, the moment
of inertia tensor is calculated based on the shape’s dimensions. Because
the dimensions are 10 times larger, the calculated inertia tensors will
be significantly larger. If you do not recalculate the local inertia of
your rigid bodies using their new scaled shapes, rotation behaviors will
become erratic and unstable. Always call
calculateLocalInertia on the scaled collision shapes before
constructing the rigid bodies.