API

Drawing Bounding Boxes

It's pretty easy to draw bounding boxes around a mesh in Babylon. You can think of a bounding box as a visual box that your object or objects fit inside perfectly. It encompasses the outer "bounds" of your object.

Let's start by drawing a bounding box around a single object. You can follow along with the default playground.

Let's say that you have a sphere in your scene that you've affectionately named "sphere".

To draw the bounding box around your sphere, all you need to do is set the showBoundingBox property to true.

Like this :

sphere.showBoundingBox = true;

Pretty simple, right?

Here is a playground where you can see it working. Drawing A Box Around A Single Object

OK, so let's make it a little more complicated. Let's say that your scene also has a ground plane in it that you've lovingly named "ground", and you'd like to draw a bounding box around the area that encompasses both the sphere and the ground.

To do this, we're going to get the minimum and maximum values of the bounding information for both meshes and compare them with special methods that compare two Vector3 values and return the minimum and maximum values. Then we'll set the sphere's bounding information to these new min and max values. Let's try it out.

Let's start by declaring four new variables that will hold the minimum and maximum bounding information for the sphere and the ground. Like this:

let sphereMin = sphere.getBoundingInfo().boundingBox.minimum;
let sphereMax = sphere.getBoundingInfo().boundingBox.maximum;
let groundMin = ground.getBoundingInfo().boundingBox.minimum;
let groundMax = ground.getBoundingInfo().boundingBox.maximum;

OK, and now let's declare two new variables and use those special methods mentioned above to compare the min and max bounding info of both meshes.

import { Vector3 } from "@babylonjs/core/Maths/math.vector";
let newMin = Vector3.Minimize(sphereMin, groundMin);
let newMax = Vector3.Maximize(sphereMax, groundMax);

So now newMin and newMax are the minimum and maximum bounds of both objects. Next, we will set the sphere's bounding information to a new set of bounding data based on newMin and newMax.

import { BoundingInfo } from "@babylonjs/core/Culling/boundingInfo";
sphere.setBoundingInfo(new BoundingInfo(newMin, newMax));

And finally, just like before, we then display the sphere's bounding box.

sphere.showBoundingBox = true;

Here it is working in a playground: Drawing A Box Around Multiple Objects

OK, so there's a problem with the technique we used above. We actually changed the bounding info of the sphere to the new bounding information that encompasses both the sphere and the ground. A better way to do this is to leave the sphere's bounding information alone and introduce parenting instead.

To start, let's create a new generic mesh like this:

import { Mesh } from "@babylonjs/core/Meshes/mesh";
let parent = new Mesh("parent", scene);

And now let's use this generic mesh as the parent of the sphere and the ground;

sphere.setParent(parent);
ground.setParent(parent);

Lastly, instead of setting the bounding information and displaying the bounding box of the sphere, let's change that to the parent instead.

import { BoundingInfo } from "@babylonjs/core/Culling/boundingInfo";
parent.setBoundingInfo(new BoundingInfo(newMin, newMax));
parent.showBoundingBox = true;

So here's what our playground looks like now. A Better Approach For Bounding Boxes

Notice something wrong? Our bounding box doesn't line up with the bounds of our objects anymore, does it? There's a good reason for that. Up to this point, we were using local coordinates instead of world coordinates. So technically the bounding box is the right size, but it's drawn around the parent mesh, which in this case has its pivot at the origin. You can clearly see the problem when you comment out this line:

sphere.position.y = 1;

See that here in this playground: A Fixed Better Approach For Bounding Boxes

Does that make a bit more sense? But what if you want to get the world bounds of the positioned objects? It's actually pretty easy to do. We'll make a couple of minor modifications to the sphereMin, sphereMax, groundMin, and groundMax values like this:

let sphereMin = sphere.getBoundingInfo().boundingBox.minimumWorld;
let sphereMax = sphere.getBoundingInfo().boundingBox.maximumWorld;
let groundMin = ground.getBoundingInfo().boundingBox.minimumWorld;
let groundMax = ground.getBoundingInfo().boundingBox.maximumWorld;

Nice! That looks more like what you were probably expecting, doesn't it?

Here's the updated playground to check out. World Transform Bounding Boxes

So what happens if you have a whole bunch of objects and you want to get the bounding box of all of them? You wouldn't want to do that manually for each one, right? So we'll introduce a loop into the mix.

Like earlier, we'll make sure that we have a parent mesh, and that each object we want to include in the bounding box will be parented to that parent mesh.

The useful technique here is that we can loop through an array of every "child mesh" of the parent. Let's start by declaring a new variable that will be an array of all of the parent's child meshes.

let childMeshes = parent.getChildMeshes();

Next, let's declare two new variables that will hold the minimum and maximum bounding values.

let min = childMeshes[0].getBoundingInfo().boundingBox.minimumWorld;
let max = childMeshes[0].getBoundingInfo().boundingBox.maximumWorld;

We're setting the starting values of these min and max variables to the world min and world max bounding information of the first child mesh.

Now we can loop through all of the child meshes and continually update the min and max values with the new bounding information of each comparative mesh. It looks like this:

import { Vector3 } from "@babylonjs/core/Maths/math.vector";
for (let i = 0; i < childMeshes.length; i++) {
let meshMin = childMeshes[i].getBoundingInfo().boundingBox.minimumWorld;
let meshMax = childMeshes[i].getBoundingInfo().boundingBox.maximumWorld;
min = Vector3.Minimize(min, meshMin);
max = Vector3.Maximize(max, meshMax);
}

Here's the playground result of those changes: Loop Through Meshes to Draw Bounding Box

We can achieve this same effect by calling getHierarchyBoundingVectors() on our parent Node.

import { BoundingInfo } from "@babylonjs/core/Culling/boundingInfo";
let { min, max } = parent.getHierarchyBoundingVectors(); //Returns the bounding vectors of a Node and all its children
parent.setBoundingInfo(new BoundingInfo(min, max));
Using getHierarchyBoundingVectors()

If we want to update the bounding box every time the parent receives a new child, we can use onAfterWorldMatrixUpdateObservable to listen for changes. However, calling getHierarchyBoundingVectors() within this observer will cause an infinite loop. To prevent this, we can check for re-entrancy on the node.

import { BoundingInfo } from "@babylonjs/core/Culling/boundingInfo";
parent.onAfterWorldMatrixUpdateObservable.add((v) => {
setTimeout(() => {
if (parent.detectReentrancy) {
return;
}
parent.detectReentrancy = true;
let { min, max } = parent.getHierarchyBoundingVectors(); //triggers observable causing infinite loop
parent.setBoundingInfo(new BoundingInfo(min, max));
setTimeout(() => {
parent.detectReentrancy = false;
});
});
});
Updating bounding box on child added

To dive even further into bounding boxes, make sure to check out the API as well.