The new progress was triggered by Ian Mackenzie’s work on elm-3d-scene. I highly encourage you to check his talk “A 3D rendering engine for Elm”. His presentation included an example of rendering a physical simulation.
I wanted to make such examples easy to build. It used to be hard, because elm-physics doesn’t do rendering and webgl is a pretty low-level package. With elm-3d-scene rendering will become much more approachable. And the new API of elm-physics improves it even further by using the shared vocabulary, defined in elm-geometry and elm-units.
I am going to list all the elm-physics improvements further below, but first I would like to share an example.
So what were the improvements that led to such concise code? I had to change quite a few things.
Improvements from elm-units
To support elm-units, I replaced ambiguous floats with self-documenting types.
It feels very nice to be able to pass length in meters, mass in kilograms, acceleration in meters per second squared and duration in seconds. You can use imperial units too, but don’t you dare!
Improvements from elm-geometry
Most examples need the visual representation of an object (
Mesh) to match its physical representation (
Body). Using elm-geometry to construct both representations reduces the boilerplate code. It also allowed me to simplify elm-physics API, because elm-geometry deals with construction and positioning of
Direction3d types helps to distinguish between points and normals.
Axis3d encapsulates both a point and a direction, so I could simplify the type of the hinge constraint to take two axes instead of a record with 4 attributes.
I also replaced the functions that move and rotate physical bodies with the new ones that mimic elm-geometry API, so that the user doesn’t have to learn new concepts.
Another cool feature from elm-geometry is its awareness of the coordinate systems. elm-physics exposes two: body local coordinates and world coordinates. Encoding coordinate systems in types improves the documentation and helps to avoid bugs. Types force the user to use
Frame3d in order to transform between local and world coordinates.
James Carlson found it surprising that bodies of zero mass didn’t move. Such bodies were in fact treated as if they had infinite mass. To address this, I introduced body behavior, that can either be static or dynamic. The constructor for the dynamic behavior requires mass.
The last improvement was about the center of mass of a body created from multiple shapes. Previously, the documentation didn’t even mention that the origin of the body local coordinate system had to be in the center of mass. This forced the awareness and the calculation of the offsets on the user. Ian Mackenzie suggested me to automatically calculate the center of mass offset and use it internally, while letting users choose an arbitrary body local coordinate system. The transformation between the center of mass coordinates and the user-defined body local coordinates happens when the user moves or rotates the body.
Originally, I planned to extend the functionality of elm-physics, but chose to improve the API to make it easier for users to build fun demos.
I like it when demos drive requirements. Please let me know if something that you need is missing! I hope that new features will organically fit into the existing API.