3D Physics Engine

Hi folks, I’ve been working on something really exciting — a 3d physics engine in Elm, and have something to show!

The reason why I started this in the first place, was because of a crazy idea for the Elm Game Jam to build a physically simulated dice roller! I looked at all the existing options available in JavaScript and found Cannon.js easier to comprehend. Due to lack of knowledge in maths and physics, I wondered how far I could go by just reading and understanding the JavaScript code — turns out it was possible, and I even learned some theory on the way.

Conversion was somewhat painful, because of little mistakes that I did here and there that were not caught by the type system, e.g. vec1 |> Vec3.sub vec2 is not equivalent to vec1.sub(vec2).
I went by manually stepping through the compiled code in Chrome Dev Tools and comparing intermediate values to the same scene running in Cannon.js, I did this to discover some anomalies in the coefficients and then traced them up to find the bugs in code.

Writing tests did help me in most cases, because I could write them for both the original JavaScript library and my Elm package, and then compare the results. In some cases, when collision wasn’t working properly, I used the debugger to get into the wrong state, and manually copied all the values into the tests.

I learned that the current linear-algebra package in Elm doesn’t support things that I needed, so I had to implement things like Mat3 and Quaternion. Perhaps supporting typed arrays in Elm would make it possible to roll out Elm implementation of linear-algebra without native code.

In order to port mutable object oriented code to Elm, I had to clearly separate reads and writes, because in some places the values were mutated on read (perhaps for performance reasons). In the end, it really streamlined the algorithms, and made them easier to understand.

Because the current Elm code is much slower than the JavaScript implementation, I plan to look into performance and work on improvements in a measurable way, most likely utilizing elm-benchmark.

There are also a lot of features that I didn’t implement, because I was mostly focused on just enough API to make the dice game.


It makes me so happy to see this! :smiley:

I will be very interested in any information about performance that come from this. Seems like a great way to figure out exactly what is needed for an in-practice use of typed arrays.

I think after 0.19 we should meet to talk about the GLSL parser, and maybe there will be stuff to share about this as well. We need to talk about elm-explorations as well at some point too. I’ll message you about this.

As an aside, can’t a Mat4 pretend to be a Mat3? Putting zeros and ones in the right places? Or is it something about the operations assuming they are transformation matrices? I do not recall.


I converted linear-algebra to a pure implementation using records here: https://github.com/robert-wallis/elm-linear-algebra/tree/PureElm

But I haven’t had time to do any benchmarks. So this may save you time writing benchmarks.

Also I’m not sure it will work because GL is expecting arrays.

You’re right! Mat4 worked fine instead of Mat3. One custom thing less :tada:

As for the performance, I am going to setup a scene with many objects, and run it through multiple simulation steps in elm-benchmark. Then I will start tweaking things and see how that affects the execution time. Will definitely share my learnings!

1 Like

Cool, I am aware of another pure Elm implementation https://github.com/Zinggi/elm-webgl-math that Florian made. There is also a benchmark: https://github.com/Zinggi/elm-rainbow-star-benchmark maybe you can use it for your library too!

You’re right about the WebGL integration, if the Elm version of linear-algebra uses records or tuples, there should be an additional step to convert it into typed arrays.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.