Ammo with BabylonJS & Angular

Hi there,

Can someone help please, I’m unable to get AmmoJS to work with my project setup. I was initially using OimoJS but had to switch to AmmoJS. I have read the docs and followed the steps but still having issues. see below:

Error

TypeError: Cannot set properties of undefined (setting 'Ammo')

Code

Ammo().then(() => {
    scene.enablePhysics(new Vector3(0, -9.81, 0), new AmmoJSPlugin(true, Ammo));
});

Currently Using

Angular 9

Package

"ammo.js": "github:kripken/ammo.js",
"babylonjs": "^5.0.0-alpha.45",
"babylonjs-loaders": "^5.0.0-alpha.45",
"babylonjs-materials": "^5.0.0-alpha.45",

This is indeed strange it does not work… Could you share a repro ?

I wonder if the latest ammo build was well from master @Cedric ?

Hi @sebavan,

Thanks for looking into this :slight_smile:

Playground as requested:
https://www.babylonjs-playground.com/#A1AKJS#1

Ammo is already initialized for you in the playground: Fix Ammo Init in playground download · sebavan/Babylon.js@2422919 · GitHub

Got it :slight_smile: how do you propose I repro?

Would a tiny project be ok? or is it possible to repro in playground?

I guess here a mini github project would be necessary.

I’m wondering if the emscriptem Promise instead provides what you need. Did you try:

Ammo().then(ammo => {
    scene.enablePhysics(new Vector3(0, -9.81, 0), new AmmoJSPlugin(true, ammo));
});
1 Like

@brianzinn Just tried the snippet, still no luck! I will repro with a mini-project.

Error

Error: Uncaught (in promise): TypeError: Cannot set properties of undefined (setting 'Ammo')

Hi guys,

Here is a github mini-project as requested.
https://github.com/voxelcubesdev/babylonjs-ammojs-test

1 Like

You have 2 choices:

  1. you use ammojs-typed and change your file like this:
....

import Ammo from 'ammojs-typed'

...

	protected addPhysicsToScene(scene: Scene, sphere: any, ground: any): void {
		Ammo().then((ammo: any) => {
			scene.enablePhysics(new Vector3(0, -9.81, 0), new AmmoJSPlugin(true, ammo));

			sphere.physicsImpostor = new PhysicsImpostor(
				sphere,
				PhysicsImpostor.BoxImpostor,
				{
					mass: 1,
					friction: 0.1,
					restitution: 0.1,
				},
				this.scene
			);
	
			// Move the sphere upward 1/2 its height
			sphere.position.y = 5;

			ground.physicsImpostor = new PhysicsImpostor(
				ground,
				PhysicsImpostor.BoxImpostor,
				{
					mass: 0,
					friction: 0.1,
					restitution: 0.1,
				},
				this.scene
			);
		});
	}

	public createScene(): void {
...
		
		this.addPhysicsToScene(this.scene, sphere, ground);

		// this.scene.registerBeforeRender(() => {});
	}

...
}

This is still pretty bad as you should await the promise and not only fire and forget but at least it will work.

The second solution is to rely on ammo directly and in this case from solution 1. you only change:

import Ammo from 'ammojs-typed' to import * as Ammo from 'ammo.js'; but you need to add a typings file for it in your project like in app you create a ammo.d.ts file containing:

declare module 'ammo.js';

You would basically lose ammo typings except if you manually create them in the d.ts file but will be on latest.

2 Likes

Many thanks @sebavan, I will test both out and keep you posted. Although I’m gravitating towards the second option. :slight_smile:

@sebavan Ok, I tried both methods and all worked great and as expected except that I had to remove the solution due to some new issues I was getting with Cannon and Ammo. So I’m back to using OimoJS but the good news is I found a solution to the inital issue why I had to switch physics engine :slight_smile:

Thank you guys for all your help, really appreciate it. :slight_smile:

1 Like

See related thread below.

https://forum.babylonjs.com/t/physics-bounding-box-rotation/23919/8