API

Using A Physics Engine

Introduction

Babylon.js has a plugin system for physics engines that enables users to add physics interactions to scene objects. Unlike the internal collision system, a physics engine calculates objects' body dynamics and emulates "real-life" interactions between them. So if two objects collide, they will "bounce" off one another, just like you would expect from a real-life object.

The plugin system allows us to use well-established physics engines and integrate them into the render loop. Apart from very advanced usage, there is no need to interact directly with the physics engine. Babylon.js does the work for you.

Which physics engine is integrated

There is a plugin for the Havok Physics engine.

Read about the Babylon.js Havok plugin and how to use it directly.

Basic usage

Enabling the physics engine

To enable the physics engine, call the scene's enablePhysics function:

import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin";
import { Scene } from "@babylonjs/core/scene";
var scene = new Scene(engine);
var gravityVector = new Vector3(0, -9.81, 0);
var physicsPlugin = new HavokPlugin();
scene.enablePhysics(gravityVector, physicsPlugin);

Both parameters are optional. The default parameters are shown in the example. This is the same as calling:

scene.enablePhysics();
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin";
scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin());

Calling this function will create a new PhysicsEngine object that handles the physics interactions.

The physics engine is now enabled and is running during the render loop.

Your first physics scene

Here we present a minimal example of a physics-enabled scene, using Aggregates for faster creation:

import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera";
import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder";
import { PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin";
import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate";
import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin";
import { Scene } from "@babylonjs/core/scene";
var createScene = function () {
// This creates a basic Babylon Scene object (non-mesh)
var scene = new Scene(engine);
// This creates and positions a free camera (non-mesh)
var camera = new FreeCamera("camera1", new Vector3(0, 5, -10), scene);
// This targets the camera to scene origin
camera.setTarget(Vector3.Zero());
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
var light = new HemisphericLight("light", new Vector3(0, 1, 0), scene);
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;
// Our built-in 'sphere' shape.
var sphere = MeshBuilder.CreateSphere("sphere", { diameter: 2, segments: 32 }, scene);
// Move the sphere upward at 4 units
sphere.position.y = 4;
// Our built-in 'ground' shape.
var ground = MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, scene);
// initialize plugin
var hk = new HavokPlugin();
// enable physics in the scene with a gravity
scene.enablePhysics(new Vector3(0, -9.8, 0), hk);
// Create a sphere shape and the associated body. Size will be determined automatically.
var sphereAggregate = new PhysicsAggregate(sphere, PhysicsShapeType.SPHERE, { mass: 1, restitution: 0.75 }, scene);
// Create a static box shape.
var groundAggregate = new PhysicsAggregate(ground, PhysicsShapeType.BOX, { mass: 0 }, scene);
return scene;
};
Simple scene

Physicalize GLTF

An extra step is needed to physicalize meshes imported from glTF in a left-handed scene. Insert an extra transform node just before the __root__ so the loader's right-to-left-handed conversion is transparent to the physics engine. See Coordinate Systems and Handedness for an explanation of the imported root.

import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
const trParent = new TransformNode("tr", scene);
const root = scene.getMeshByName("__root__");
root.setParent(trParent);
Simple scene with gltf

Debugging your scene

Use the physics debug display when your scene and dynamics don't behave the way you think they should. It will display geometry the way the physics engine sees the world. There are two ways to invoke the display.

Programmatically

import { PhysicsViewer } from "@babylonjs/core/Debug/physicsViewer";
physicsViewer = new PhysicsViewer();
for (const mesh of scene.rootNodes) {
if (mesh.physicsBody) {
const debugMesh = physicsViewer.showBody(mesh.physicsBody);
}
}

This snippet creates the PhysicsViewer and then adds every PhysicsBody available from the scene's meshes.

Using the Inspector

You can turn on and off the Physics Viewer on the Debug Tab of the Inspector:

Inspector Physics Viewer