# Bounding volume collision detection with THREE.js

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 `Sphere` objects. Once instantiated, they have methods available to do intersection tests against other volumes.

### 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,
```

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);
```

### Intersection tests

#### Point versus `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` versus `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` versus `Sphere`

In a similar fashion as before, there is a `Sphere.intersectsSphere` method to perform this test.

`knotBSphere.intersectsSphere(otherSphere);`

#### `Sphere` versus `Box3`

Unfortunately this test is not implemented in Three.js, but we can patch Sphere to implement a Sphere versus 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);
};```

### 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 versus box collisions using `BoundingBoxHelper`. The second one performs box versus box tests. Tags: