# Frustum

Class · category: Math

Source: https://github.com/playcanvas/engine/blob/970d89f6d3bc6667f4e1f88153abd6e7e82ed52c/src/core/shape/frustum.js#L65

A frustum is a shape that defines the viewing space of a camera. It can be used to determine
visibility of points and bounding spheres. Typically, you would not create a Frustum shape
directly, but instead query [CameraComponent#frustum](https://api.playcanvas.com/engine/classes/CameraComponent.md#frustum).

A frustum is six [Plane](https://api.playcanvas.com/engine/classes/Plane.md)s, read and written with [getPlane](https://api.playcanvas.com/engine/classes/Frustum.md#getplane) and [setPlane](https://api.playcanvas.com/engine/classes/Frustum.md#setplane),
and normally derived from a camera's combined view-projection matrix with [setFromMat4](https://api.playcanvas.com/engine/classes/Frustum.md#setfrommat4).
[containsPoint](https://api.playcanvas.com/engine/classes/Frustum.md#containspoint) and [containsAabb](https://api.playcanvas.com/engine/classes/Frustum.md#containsaabb) return a boolean. [containsSphere](https://api.playcanvas.com/engine/classes/Frustum.md#containssphere) returns 0
for a sphere outside, 1 for one that intersects and 2 for one fully inside, so callers can skip
finer tests for objects that are entirely visible. None of the tests allocate.

**Example**

```ts
// Skip work for objects the camera cannot see
const frustum = entity.camera.frustum;
if (frustum.containsAabb(meshInstance.aabb)) {
    // visible: update it
}
```

## Constructors

### constructor

```ts
new Frustum()
```

Create a new Frustum instance.

**Example**

```ts
const frustum = new Frustum();
```

## Methods

### add

```ts
add(other: Frustum): Frustum
```

Expands this frustum to also contain another frustum. The other frustum's 8 corner points
are computed, and each of this frustum's planes is pushed outwards just far enough to
contain them all. The result is a conservative convex volume that contains both frustums.
This is useful for multi-view rendering such as stereo XR, where culling should keep
objects visible in any view.

Note: keeping each plane's orientation makes this correct for arbitrary frusta, including
the asymmetric per-eye projections of XR headsets, where matching planes of the two eyes
have different normals and a per-plane "outermost" selection would wrongly cut into the
combined volume at a distance.

**Parameters**

- `other` ([`Frustum`](https://api.playcanvas.com/engine/classes/Frustum.md)): The other frustum to add.

**Returns** [`Frustum`](https://api.playcanvas.com/engine/classes/Frustum.md): Self for chaining.

### clone

```ts
clone(): Frustum
```

Returns a clone of the specified frustum.

**Returns** [`Frustum`](https://api.playcanvas.com/engine/classes/Frustum.md): A duplicate frustum.

**Example**

```ts
const frustum = new Frustum();
const clone = frustum.clone();
```

### containsAabb

```ts
containsAabb(aabb: BoundingBox): boolean
```

Tests whether an axis aligned bounding box intersects the frustum.

The test is conservative in the same way the plane based sphere test is: a box lying just
outside a frustum corner can be reported as intersecting. It is however always at least as
tight as testing the box's bounding sphere, since the extent of a box along a plane normal
never exceeds the radius of its bounding sphere.

Unlike [Frustum#containsSphere](https://api.playcanvas.com/engine/classes/Frustum.md#containssphere), a box completely inside the frustum is not
distinguished from one merely intersecting it. Detecting that costs a comparison per plane
and no caller needs it.

**Parameters**

- `aabb` ([`BoundingBox`](https://api.playcanvas.com/engine/classes/BoundingBox.md)): The bounding box to test.

**Returns** `boolean`: True if the bounding box intersects or is inside the frustum, false if it
is completely outside.

### containsPoint

```ts
containsPoint(point: Vec3): boolean
```

Tests whether a point is inside the frustum. Note that points lying in a frustum plane are
considered to be outside the frustum.

**Parameters**

- `point` ([`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md)): The point to test.

**Returns** `boolean`: True if the point is inside the frustum, false otherwise.

### containsSphere

```ts
containsSphere(sphere: BoundingSphere): number
```

Tests whether a bounding sphere intersects the frustum. If the sphere is outside the
frustum, zero is returned. If the sphere intersects the frustum, 1 is returned. If the
sphere is completely inside the frustum, 2 is returned. Note that a sphere touching a
frustum plane from the outside is considered to be outside the frustum.

**Parameters**

- `sphere` ([`BoundingSphere`](https://api.playcanvas.com/engine/classes/BoundingSphere.md)): The sphere to test.

**Returns** `number`: 0 if the bounding sphere is outside the frustum, 1 if it intersects the
frustum and 2 if it is contained by the frustum.

### copy

```ts
copy(src: Frustum): Frustum
```

Copies the contents of a source frustum to a destination frustum.

**Parameters**

- `src` ([`Frustum`](https://api.playcanvas.com/engine/classes/Frustum.md)): A source frustum to copy to the destination frustum.

**Returns** [`Frustum`](https://api.playcanvas.com/engine/classes/Frustum.md): Self for chaining.

**Example**

```ts
const src = entity.camera.frustum;
const dst = new Frustum();
dst.copy(src);
```

### getPlane

```ts
getPlane(index: number, result: Plane): Plane
```

Returns one of the frustum's six planes. The planes are ordered right, left, bottom, top,
far, near, and their normals point inwards.

**Parameters**

- `index` (`number`): The index of the plane, from 0 to 5.
- `result` ([`Plane`](https://api.playcanvas.com/engine/classes/Plane.md)): The plane to write to.

**Returns** [`Plane`](https://api.playcanvas.com/engine/classes/Plane.md): The supplied plane, containing the frustum plane.

**Example**

```ts
const plane = new Plane();
entity.camera.frustum.getPlane(0, plane);
```

### setFromMat4

```ts
setFromMat4(matrix: Mat4): void
```

Updates the frustum shape based on the supplied 4x4 matrix.

**Parameters**

- `matrix` ([`Mat4`](https://api.playcanvas.com/engine/classes/Mat4.md)): The matrix describing the shape of the frustum.

**Example**

```ts
// Create a perspective projection matrix
const projection = new Mat4();
projection.setPerspective(45, 16 / 9, 1, 1000);

// Create a frustum shape that is represented by the matrix
const frustum = new Frustum();
frustum.setFromMat4(projection);
```

### setPlane

```ts
setPlane(index: number, plane: Plane): Frustum
```

Sets one of the frustum's six planes. The plane is normalized as it is stored, as the
frustum's tests require unit length normals. The planes are ordered right, left, bottom, top,
far, near, and their normals must point inwards.

**Parameters**

- `index` (`number`): The index of the plane, from 0 to 5.
- `plane` ([`Plane`](https://api.playcanvas.com/engine/classes/Plane.md)): The plane to store.

**Returns** [`Frustum`](https://api.playcanvas.com/engine/classes/Frustum.md): Self for chaining.
