I recently wrote about the performance of JS ARToolKit WebAssembly version compared to the none WebAssembly version http://augmentmy.world/js-artoolkit-performance. Today I’d like to tell you how I made JS ARToolKit WebAssembly possible.
JS ARToolKit WebAssembly background
Some background on JS ARToolKit WebAssembly and how ARToolKit for the web is made possible. ARToolKit is an open source project which is available on many platforms like macOS, Unity3D, Android, iOS to name a few. A few years back the community contributed a JavaScript port of ARToolKit to enable ARToolKit to run inside the web browser. This was made possible by compiling ARToolKit using a technology called Emscripten. Emscripten is a compiler which takes C/C++ code and translates it into JavaScript code which is then used inside the browser.
When this project was started no one thought about WebAssembly and I’m not sure if it was even available. With the rise of WebAssembly Emscripten changed in a way to produce WebAssembly code per default which in turn broke the build chain for JSARToolKit but all I had to do to fix that was to configure Emscripten to not build WebAssembly per default. But you would like to know how I made JS ARToolKit WebAssembly possible so let us get to that.
Enabling JS ARToolKit WebAssembly
As said per default Emscripten produces WebAssembly artefacts, so what to do with them. The browser needs to load WebAsse
mbly artefacts before one can access the functions inside the WebAssembly file. In order to do that Emscripten provides a callback function. The name of this callback function is Module.instantiateWasm. What you as developer need to do is to implement this function and make sure that it is available before
loading the WebAssembly artefacts. Here a bit more background on the instantiateWasm callback:
o perform the WebAssembly instantiation action. The callback function will be called with two parameters, imports and successCallback. imports is a JS object which contains all the function imports that need to be passed to the Module when instantiating, and once instantiated, the function should call successCallback() with the WebAssembly Instance object. The instantiation can be performed either synchronously or asynchronously. The return value of this function should contain the exports object of the instantiated Module, or an empty dictionary object {} if the instantiation is performed asynchronously, or false if instantiation failed.
Have a look at this commit on GitHub to see how I implemented WebAssembly loading.
Improving it
That would have worked and provided a basic option for everyone to enable JS ARToolKit WebAssembly to work on any website. However, it would have put the burden of implementing the Module.instantiateWasm function upon every developer that wants to use JSARToolKit. To fix that I made the Module.instantiateWasm function part of JSARToolKit. This adds a lot of convenience for the users of the library and to allow this I provide a possibility to tell JSARToolKit where to look for the WebAssembly artefacts. To use it you need to define
var artoolkit_wasm_url = '<<PATH TO>>/artoolkit_wasm.wasm';
prior to loading the artoolkit_wasm.js file. It should look like this:
<script type='text/javascript'> var artoolkit_wasm_url = '../build/artoolkit_wasm.wasm'; </script> <script src="../build/artoolkit_wasm.js"></script>
Loading the WebAssembly artefact is done asynchronous. That means you need to implement a callback that informs you that everything is ready.
window.addEventListener('artoolkit-loaded', () => { //do artoolkit stuff here });
Make sure you are not calling any JSARToolKit functions before this callback has been called.
This is it now you can enjoy the fast JS ARToolKit WebAssembly library on your website and use it for your next project. Take a look at the example for a complete implementation.
This is it. Let me know if you got any questions and leave a comment below.