Ammo: TypeError on reloading Playground (Need to click Play button to bypass error)

Please refer to the Playground (https://playground.babylonjs.com/#DU4FPJ#171), which is identical to the PG from Advanced Animation Methods | Babylon.js Documentation (except Cannon is replaced with Ammo)

When I click on the PG link, I see the error: Cannot read property 'dy' of undefined, as shown in the image below:

This error can be bypassed by clicking the Play button of the PG

I reproed this error in a local project to see the error’s stack trace:

TypeError: Cannot read property 'dy' of undefined
    at b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration_btSoftBodyRigidBodyCollisionConfiguration_0 (ammo.js:511)
    at new YD (ammo.js:886)
    at new AmmoJSPlugin (ammoJSPlugin.ts:84)

I wonder if it’s due to Ammo not fully loaded on page refresh, but is fully loaded by the time we click the Play button on the PG

I think I misunderstood how Ammo is loaded. This seems to resolve the error: https://playground.babylonjs.com/#DU4FPJ#173

Changed createScene to async and added await Ammo(); before new BABYLON.AmmoJSPlugin.

Wait there is something definitely strange here. @MackeyK24 I might need to revert your latest ammo changes.

I will test if it is related before.

The await Ammo() fix above was inspired by @MackeyK24’s post: Use wasm version of ammo.js and also the official Ammo example: ammo.js/worker.js at master · kripken/ammo.js · GitHub

I wonder if the developer should call await Ammo() (or Ammo().then()) or if Babylon should abstract this away from the developer in its AmmoJSPlugin

I was eventually hoping to load the .wasm variant of Ammo, so maybe allowing the developer to explicitly call Ammo().then() is beneficial

For reference, to load the .wasm variant, I think we could use ammo.js/worker.wasm.js at master · kripken/ammo.js · GitHub :

var config = {
  locateFile: () => '../../builds/ammo.wasm.wasm'
}

Ammo(config).then(function(Ammo) {

});

The thing is the way ammo was compiled in 4.2 (the one in the dist folder) is fully functionnal and working, so I ll revert the new update from @MackeyK24 for the time being at least until we fully get what changed in between both versions.

1 Like

The deploy revert should be up in 30 minutes, The PRs involved are:

1 Like

@gbz it looks like the module generation changed in the Ammo.js file, we ll check with @MackeyK24 soon and update again accordingly.

1 Like

Thank you so much @sebavan and @MackeyK24! :slight_smile:

And yes I do think it is only that the initialization changed but not being sure how, I guess it is safer to have @MackeyK24 and @Cedric having a look before integrating the new release.

1 Like

@sebavan and @Cedric … There has been build changes with ammo.js/kripken build system since the version of ammo.js in the 4.2 dist folder. (Built With Emscripten 1.39)

First the Emscripten build system has changed (Version 1.39 is the last version using older emscripten compilers)

Second the actual build system for the Bullet C++ src is now cmake. So all the switches have changed as well (or relocated to make files)

Third… the module setup is a bit different as well. Aa a matter of fact there is now a onload.js that is supposed to setup the the main Ammo object as a module

All this is a bit different than the ammo.js ( build with emscripten <= 1.39)

I initially had problem with the new system as well until kripken told me hold to build with the new system.

If there are issues with how or what ammo.js is doing on the playground, we need to find and address this (otherwise we are gonna be stuck with the older version of ammo.js built with the old emscripten compiler system that is in the 4.2 dist folder).

Now the main thing that is different from the version i built that is in the 4.2 dist folder (besides using the new build system itself) is the CLOSURE options is set to true. I never really used that before but when trying to figure out the new build system DCLOSURE=1 was one of the options that was given to me. So maybe the google closure cimpiler has something to do with it.

I can try and rebuild WITHOUT the closure.

But as far as i know … This is only way to build the CURRENT ammo.js using the CURRENT emscripten

To configure and build ammo into the builds directory, run the following:

$ cmake -B builds
$ cmake --build builds
There are also some key options that can be specified during cmake configuration, for example:

$ cmake -B builds -DCLOSURE=1                # compile with closure
$ cmake -B builds -DTOTAL_MEMORY=268435456   # allocate a 256MB heap
$ cmake -B builds -DALLOW_MEMORY_GROWTH=1    # enable a resizable heap
On windows, you can build using cmake's mingw generator:

> cmake -B builds -G 'MinGW Makefiles'
> cmake --build builds
Note that if you have not installed emscripten via the emsdk, you can configure its location with -DEMSCRIPTEN_ROOT.

Now i am using the these new builds (including the wasm version) in my toolkit and am driving around just fine… there are a few demos of my driving using these new ammo.js builds. Now i load my wasm a bit different than may be loading on the playground. But it works perfectly for me

var finalSceneLoadReady = function() {

    // Ammo.js ready... can load scene here
}

var bulletPhysicsLoader = function() {
    try {
        if (typeof Ammo !== "undefined") {
            Ammo().then(function() {  finalSceneLoadReady(); });
        } else {
            finalSceneLoadReady();
        }
    } catch (ex4) {
        console.error(ex4.message || "Unknown Bullet Exception");
    }
}

I will continue to use the latest ammo.js (with new build system in Babylon Toolkit). But I would luv for the playground to have the same features of ammo.js that i am using in the Babylon Toolkit. Hopefully we can find the issue with the playground and new builds :slight_smile:

Anyways… How would i make a new build out and test on the playground ???

1 Like

From build docs of Ammo.js

Pushing a new build in builds/ammo.js should be done only after the following steps:

  • Configure with closure enabled: cmake -B builds -DCLOSURE=1
  • Build both the asm.js and wasm libraries: cmake --build builds
  • Make sure they pass all automatic tests: npm test
  • Run the WebGL demo in examples/webgl_demo and make sure it looks ok, using something like firefox examples/webgl_demo/ammo.html (chrome will need a webserver as it doesn’t like file:// urls)

After much playing around today, I found that the Ammo build MackeyK24 commited compiles well in the browser and in a Node.js server with and without .wasm (using the code below)

In Browser:

// in index.html
// js
<script src="lib/ammo/ammo.js"></script>

// wasm
<script src="lib/ammo/ammo.wasm.js"></script>
// also have ammo.wasm.wasm in lib/

await Ammo();
const physEngine = new BABYLON.AmmoJSPlugin(false);

In Node.js server:

// @ts-ignore
import * as ammo from './ammo'; // js
// with ammo.js in your webpack entry folder

// @ts-ignore
import * as ammo from './ammo.wasm'; // wasm
// with ammo.wasm.js in your webpack entry folder
// also have ammo.wasm.wasm in your webpack output folder

// @ts-ignore
const Ammo = await ammo.default();
const physEngine = new BABYLON.AmmoJSPlugin(false, Ammo);

Maybe I’m doing something wrong, but I had trouble getting .wasm to work with the reverted Ammo

Edit:
The following should also work in a Node.js server:

// @ts-ignore
import { default as Ammo } from './ammo'; // js
// with ammo.js in your webpack entry folder

// @ts-ignore
import { default as Ammo } from './ammo.wasm'; // wasm
// with ammo.wasm.js in your webpack entry folder
// also have ammo.wasm.wasm in your webpack output folder

const physEngine = new BABYLON.AmmoJSPlugin(false, await Ammo());

Coooool I am gonna try to update over the week end and update the doc.

1 Like

So are the builds ok or do I have to make a new ammo.js build ?

I ll let you know on Monday after trying it our :slight_smile:

1 Like

@MackeyK24 your previous PR is ok, no need to recompile so far.

About the changes, I am trying to reach out to the team to see what the most acceptable solution is.

I hate that it is a huge breaking change cause now all the previous PG using Ammo will not work despite the init being straightforward.

I am currently in favor of adding documentation regarding the initialization of ammo but not specially handle it in the plugin cause adding some kind of initAsync in the plugin sounds redundant to the await Ammo() call :slight_smile:

Also I think I could add the initialization in the playground to ensure at least PG back compat but not user code back compat.

Any thoughts ?

1 Like

The fix will be deployed in about 1 hour, so in the playground, the playground will take care of the init so that we save back compat of PGs.

Outside of PG you ll need to await Ammo() as I added in the doc accordingly.

this will be using the latest version provided by @MackeyK24 last time.

2 Likes