This article shows how to implement **collision detection between bounding boxes and spheres using the Three.js** library. It is assumed that before reading this you have read our 3D collision detection introductory article first, and have basic knowledge about Three.js.

## Using `Box3`

and `Sphere`

Three.js has objects that represent **mathematical volumes** and shapes — for 3D AABB and bounding spheres we can use the ** Box3** and

**objects. Once instantiated, they have methods available to do intersection tests against other volumes.**

`Sphere`

### Instantiating boxes

To create a ** Box3 instance**, we need to provide the

**lower and upper boundaries**of the box. Usually we will want this AABB to be "linked" to an object in our 3D world (like a character.) In Three.js,

`Geometry`

instances have a `boundingBox`

property with `min`

and `max`

boundaries for the object. Keep in mind that in order for this property to be defined, you need to manually call `Geometry.computeBoundingBox`

beforehand.var knot = new THREE.Mesh( new THREE.TorusKnotGeometry(0.5, 0.1), new MeshNormalMaterial({})); knot.geometry.computeBoundingBox(); var knotBBox = new Box3( knot.geometry.boundingBox.min, knot.geometry.boundingBox.max);

**Note**: The `boundingBox`

property takes the `Geometry`

itself as reference, and not the `Mesh`

. So any transformations such as scale, position, etc. applied to the `Mesh`

will be ignored while computing the calculating box.

A more simple alternative that fixes the previous issue is to set those boundaries later on with `Box3.setFromObject`

, which will compute the dimensions taking into account a 3D entity's** transformations and any child meshes** as well.

var knot = new THREE.Mesh( new THREE.TorusKnotGeometry(0.5, 0.1), new MeshNormalMaterial({})); var knotBBox = new Box3(new THREE.Vector3(), new THREE.Vector3()); knotBBox.setFromObject(knot);

### Instantiating spheres

Instantiating** Sphere objects** is similar. We need to provide the sphere's center and radius, which can be added to the

`boundingSphere`

property available in `Geometry`

.var knot = new THREE.Mesh( new THREE.TorusKnotGeometry(0.5, 0.1), new MeshNormalMaterial({})); var knotBSphere = new Sphere( knot.position, knot.geometry.boundingSphere.radius);

Unfortunately, there is no equivalent of `Box3.setFromObject`

for Sphere instances. So if we apply transformations or change the position of the `Mesh`

, we need to manually update the bounding sphere. For instance:

knot.scale.set(2, 2, 2); knotBSphere.radius = knot.geometry.radius * 2;

### Intersection tests

#### Point vs. `Box3`

/ `Sphere`

Both `Box3`

and `Sphere`

have a ** containsPoint** method to do this test.

var point = new THREE.Vector3(2, 4, 7); knotBBox.containsPoint(point);

`Box3`

vs. `Box3`

The ** Box3.isIntersectionBox** method is available for performing this test.

knotBbox.isIntersectionBox(otherBox);

**Note**: This is different from the `Box3.containsBox`

method, which checks whether the Box3 *fully* wraps another one.

`Sphere`

vs. `Sphere`

In a similar fashion as before, there is a

method to perform this test.**Sphere.intersectsSphere**

knotBSphere.intersectsSphere(otherSphere);

`Sphere`

vs. `Box3`

Unfortunately this test is not implemented in Three.js, but we can patch Sphere to implement a Sphere vs. AABB intersection algorithm.

// expand THREE.js Sphere to support collision tests vs Box3 // we are creating a vector outside the method scope to // avoid spawning a new instance of Vector3 on every check THREE.Sphere.__closest = new THREE.Vector3(); THREE.Sphere.prototype.intersectsBox = function (box) { // get box closest point to sphere center by clamping THREE.Sphere.__closest.set(this.center.x, this.center.y, this.center.z); THREE.Sphere.__closest.clamp(box.min, box.max); var distance = this.center.distanceToSquared(THREE.Sphere.__closest); return distance < (this.radius * this.radius); };

### Demos

We have prepared some live demos to demonstrate these techniques, with source code to examine.

## Using `BoundingBoxHelper`

As an alternative to using raw `Box3`

and `Sphere`

objects, Three.js has a useful object to make handling **bounding boxes easier: BoundingBoxHelper.** This helper takes a Mesh and calculates a bounding box volume for it (including its child meshes.) This results in a new box

`Mesh`

representing the bounding box and a `Box3`

object, which is the actual bounding box.`BoundingBoxHelper`

is the **recommended** way to handle 3D collisions with bounding volumes in Three.js. You will miss sphere tests, but the tradeoffs are well worth it.

The advantages of using this helper are:

- It has an
`update()`

method that will**resize**the bounding box if the linked Mesh rotates or changes its dimensions, and update its**position**. - It
**takes into account the child meshes**when computing the size of the bounding box, so the original mesh and all its children are wrapped. - We can easily debug collisions by
**rendering**the`Mesh`

es that`BoundingBoxHelper`

creates. By default they are created with a wireframe material.

The main disadvantage is that it **only creates box bounding volumes**, so if you need spheres vs AABB tests you need to create your own `Sphere`

objects.

To use it, we need to create a** **new `BoundingBoxHelper`

instance and supply the geometry and — optionally — a color that will be used for the wireframe material.

var knot = new THREE.Mesh( new THREE.TorusKnotGeometry(0.5, 0.1), new THREE.MeshNormalMaterial({}) ); var knotBBox = new THREE.BoundingBoxHelper(knot, 0x00ff00);

If we change the `Mesh`

position, rotation, scale, etc. we need to call the `update()`

method so the `BoundingBoxHelper`

instance matches its linked `Mesh`

.

knot.position.set(-3, 2, 1); knot.rotation.x = -Math.PI / 4; // update the bounding box so it stills wraps the knot knotBBox.update();

Performing **collision tests** is done in the same way as explained in the above section — a `BoundingBoxHelper`

contains a `Box3`

instance in its `box`

property, whihc is ideal for performing the test.

// box vs box knotBBox.box.isIntersectionBox(otherBBox.box); // box vs point knotBBox.box.containsPoint(point.position);

### Demos

There are **two demos** you can take a look at on our live demos page. The first one showcases point vs. box collisions using `BoundingBoxHelper`

. The second one performs box vs. box tests.