Physics engine but on Typescript

I’m using Babylon.js from TypeScript, and would like to add a physics engine, the problem is that I’m lost about how to install configure and load the engine and making its types are available. Anyone here with experience configuring ammo.js, cannon or oimo for usage in Typescript? Any help is greatly appreciated.

Welcome @Jonathan_Acosta,

If you have babylon enabled with typescript, you should see all the plugin wrapper classes having typescript support (eg. PhysicsImpostor). If you are diving into the raw ammo, cannon or oimo physics object (this is not typically done often unless you are using specific features) you are left to find the typings for physics engine on your own. Here’s a discussion for ammo TypeScript declarations? · Issue #233 · kripken/ammo.js · GitHub and here are typings for cannon @types/cannon - npm . Finding a d.ts file or npm package with the typings you should be able to reference it in your project and then cast the objects marked as “any” in babylon to the typing you have found.

1 Like

Hi! @trevordev, thanks so much for your assistance, this makes me a lot more confident about implementing my requirements.

That being said, I’m also kindof inexperienced with TypeScript, how do you go about installing and using those types definitions? I tried yarn add @types/cannon and importing the new module but it doesn’t seem to work… I’m sure I’m missing something because of my limited experience with TS itself.

Thanks!

After installing @types/cannon, vscode will add a global type CANNON which should give autocomplete

Hmmm… I do get the autocomplete but CANNON doesn’t seem to be available right away, and I also can’t import it into my component (React). Am I missing something more here?

Maybe it has something to do with your tsconfig.json setup. Try some of the methods discussed here typescript - How to configure tsconfig.json for typings not in @types? - Stack Overflow

1 Like

To sum up the process of setting up cannon for typescript:

  • Install cannon and it’s types yarn add cannon @types/cannon.
  • No need to add it to tsconfig.json:compilerOptions.types[]
  • You can now import and use the library, for example, like this:
import cannon from 'cannon';
const physicsPlugin = new CannonJSPlugin(true, 10, cannon);
scene.enablePhysics(new Vector3(0, -9.8, 0), physicsPlugin);

Thanks to @trevordev for the prompt replies :slight_smile:

2 Likes

Hello that question seemed to be on topic to ask about my issue.
I am on the latest TypeScript and latest Babylon.

The following line:

this._physEngine = new BABYLON.CannonJSPlugin(false);

causes, the following error:

Uncaught Error: Cannot find module 'babylonjs/Maths/math'

I tried adding:

import math from "babylonjs/Maths/math";

but that did help.
It is weird because for example I use Vector3 that are imported with:

import {Vector3} from "babylonjs/Maths/math";

It seems CannonJSPlugin() constrcutor is having trouble locating what it needs from Maths?

P.S. trying to instantiate Ammo plugin instead Cannon using the below line causes the same error:
this._physEngineAmmo = new BABYLON.AmmoJSPlugin(false);

Looks like you are mixing global an import
BABYLON.AmmoJSPlugin

could you try to import the AmmoJSPlugin instead ?

If I use only that line in the constructor:
this._physEngineCannon = new BABYLON.CannonJSPlugin(false);

then the error becomes:
Uncaught ReferenceError: CANNON is not defined

Those are the imports I have in that file:
import * as BABYLON from “babylonjs”;
import {CannonJSPlugin} from “babylonjs/Physics/Plugins/cannonJSPlugin”; //I do not think that is needed though
import * as CANNON from “cannon”; //I do not think that is needed either but I put it in to test and no change

CannonJS is installed in node_modules and I did run an “npm install” after on my project folder just in case.

Could you share your file with us or a tiny repro ???

This would make it easier to troubleshoot.

Hi Seb below is the shrink-ed version of the code causing the error. Everything else worked great so far in 4.0 except for physics plugin.

import * as BABYLON from "babylonjs";

export class Game {

    private _canvas: HTMLCanvasElement;
    private _engine: BABYLON.Engine;
    private _scene: BABYLON.Scene;
    private _camera: BABYLON.FreeCamera;
    private _physEngineCannon:BABYLON.CannonJSPlugin;
    //private _physEngineAmmo:BABYLON.AmmoJSPlugin;

    public constructor(canvasElement: string) {
        this._canvas = <HTMLCanvasElement>document.getElementById(canvasElement);
        this._engine = new BABYLON.Engine(this._canvas, true, { deterministicLockstep: true, lockstepMaxSteps: 4} );
        this._scene = new BABYLON.Scene(this._engine);
        this._camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(2, 5, -10), this._scene);
        this._camera.attachControl(this._canvas, false);
        this._camera.setTarget(BABYLON.Vector3.Zero());

        //TRYING WITH CANNON:
        this._physEngineCannon = new BABYLON.CannonJSPlugin(false);
        //this._scene.enablePhysics(new Vector3(0,-9.8,0), this._physEngineCannon );
        //this._physEngineCannon.setTimeStep(1/60);

        //TRYING WITH AMMO: I GET THE SAME ERROR MESSAGE AS WITH CANNON.
        //this._physEngineAmmo = new BABYLON.AmmoJSPlugin(false);
        //this._scene.enablePhysics(new BABYLON.Vector3(0,-9.8,0), this._physEngineAmmo );
        //this._physEngineAmmo.setTimeStep(1/60);

    }

    public animate(): void {
        this._engine.runRenderLoop(() => {

            this._scene.render();
        });
        window.addEventListener('resize', () => { // The canvas/window resize event handler.
            this._engine.resize();
        });
    }

}

TS Code that instantiates the Game class on page load:

import {Game} from "./Game";

window.addEventListener('DOMContentLoaded', () => {
    let game = new Game('renderCanvas'); 
    game.animate(); // Start render loop.
});