I’ve recently been playing with physics in Spark AR, and I thought I would share the journey so far. I’ve also made a project and an npm package that might help kickstart your physics exploration.
This is by no means a complete guide to physics engines, but it should be enough to get you started. For my experiments so far, I’ve been using Cannon.js.
The way I think about physics engines, is that there’s a visual world and a physics world. Rendering a simulation is all about keeping the two worlds in sync.
The physics engine keeps track of the object positions based on forces. To keep these two worlds in sync, we need to bind the positions of everything in the two worlds together. You don’t have to explicitly say where a scene object should move or how it should behave, the physics engine handles all of that for us!
To help you along with the daunting task of integrating a physics engine, I’ve started an npm package to help with the binding of the Spark world and the Cannon physics world.
How to use
The easiest way to get started will be to use the template within the example folder on the repository.
Run this command in the terminal at the directory of the example project. It will install all the dependencies.
Now you have all the dependencies run
npm run build
This should build a new script.js file in the physicsTest project.
Open up the physicsTest project, and you should see boxes and spheres falling down.
The main source file is the index.js in the src folder of the example. Look in there to see how I use the npm package for binding objects together.
The module has helpers for keeping together the movement in the Cannon world and the Spark world. It does this by taking something I’ve called World Objects. World Objects contain a scene object and a physics body. Keeping the two parts together makes updating and syncing positions way more straightforward.
When we have our World Objects created, we pass them to the constructor, which sets up the Cannon world and adds our objects. It also exposes the original Cannon class so that it can be used as standard.
On every loop, you call update. It iterates over all the World Objects and updates the scene object’s position and rotation based on its physics object. It also steps the physics world forward by a delta time to get the new positions for all the objects.
Spark seems to have no sense of a global variable/scope. However, in the Cannon module, it assigns a value to a ‘performance’ variable, that doesn’t seem to get explicitly declared. To fix this, in the Cannon module, I added the variable ‘performance’ into the source at /src/world/World.js on line 501. That is why the package has a local version of the cannon library that isn’t from npm.
Another pitfall is that the ground plane will be on the wrong axis at the start. That’s where this line comes in to flip it back 90 degrees to where it should be.
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2)
Here’s one I made earlier
The first effect I made with the physics engine was a bowling simulation on Instagram which you can try here: https://www.instagram.com/a/r/?effect_id=2299621396769037
Here’s the repository for that project:
A bowling simulation in Spark AR with Cannon.js. Contribute to ashleymarkfletcher/spark-ar-bowling development by…
This project shows a slightly more practical approach to how you might apply physics to an effect, rather than just having objects falling to the ground. It also shows how to use the original cannon object in combination with the module.
Without too much extra code, we can start to interact with the objects by applying impulses to the physics objects.
What I’ve learned
The reactive programming in Spark AR clashes with the more traditional style of Cannon.js, which causes quite a bit of a performance hit. An example of this has no frame update loop to plug into. My approach was to just use an interval for the update loop. This type of approach causes a lot of warnings that popup for using too many callbacks. So this is worth noting when starting your own physics-based effects.
Depending on your use case, you might get away with using physics in production. However, it might be too intensive on resources in Spark AR to get something more advanced.
This is only the beginning of the physics integration. There’s lots more to do so if you have anything to add just open a pull request or issue on GitHub.
Syncing positions from Spark to Cannon is still missing in the module. I ran into a lot of issues getting positions of objects as values, so any help on this would be appreciated! This is where the reactive programming becomes the biggest challenge.
Over the next couple of weeks, I’ll start documenting the module and include any contributions made. So keep an eye out for improvements and progress updates.
If you want any more info on physics just drop me a message on Instagram: alt.reality