メインコンテンツへスキップ

Mat4

Interface representing a 4x4 matrix. A 4x4 matrix is represented by a 16 dimensional array of data, with elements stored in column major order. A special kind of matrix, known as a TRS matrix (for Translation, Rotation, and Scale) is common in 3D geometry for representing the position, orientation, and size of points in a 3D scene. Many special types of matrices have easily specified inverses. By specifying these ahead of time, Mat4 allows for matrix inverse to be a very fast O(1) operation. Mat4 objects are created with the ecs.math.mat4 Mat4Factory, or through operations on other Mat4 objects.

Code Example

const {mat4, quat, vec3} = ecs.math
const [targetX, targetY, targetZ] = [1, 2, 3]
const [pitch, yaw, distance] = [30, 90, 5]
// Compute orbit controls position based on target position, pitch, yaw, and distance.
const orbitPos = mat4.t(vec3.xyz(targetX, targetY, targetZ))
.times(mat4.r(quat.pitchYawRollDegrees(vec3.xyz(pitch, yaw, 0))))
.times(mat4.t(vec3.xyz(0, 0, distance)))
.times(mat4.r(quat.yDegrees(180)))

Factory

Mat4 objects are created with the ecs.math.mat4 MatFactory, with the following methods:

mat4.i()

i: () => Mat4

Identity matrix.

mat4.of()

of: (data: number[], inverseData?: number[]) => Mat4

Create the matrix with directly specified data, in column major order. An optional inverse can be specified. If the inverse is not specified, it will be computed if the matrix is invertible. If the matrix is not invertible, calling inv() will throw an error.

mat4.r()

r: (q: QuatSource) => Mat4

Create a rotation matrix from a quaternion.

mat4.rows()

rows: (dataRows: number[][], inverseDataRows?: number[][]) => Mat4

Create a matrix with specified row data, and optionally specified inverse row data. dataRows and inverseDataRows should be four arrays, each with four numbers. If the inverse is not specified, it will be computed if the matrix is invertible. If the matrix is not invertible, calling inv() will throw an error.

mat4.s()

s: (v: Vec3Source) => Mat4

Create a scale matrix. No scale element should be zero.

mat4.t()

t: (v: Vec3Source) => Mat4

Create a translation matrix.

mat4.tr()

tr: (t: Vec3Source, r: QuatSource) => Mat4

Create a translation and rotation matrix.

mat4.trs()

trs: (t: Vec3Source, r: QuatSource, s: Vec3Source) => Mat4

Create a translation, rotation and scale matrix.

Properties

Mat4 has no enumerable properties, but its underlying 16 element data array and inverseData array can be accessed with data() and inverseData() respectively.

Immutable API

The following methods perform computations based on the current value of a Mat4, but do not modify its contents. Methods that return Mat4 types return new objects. Immutable APIs are typically safer, more readable, and less error-prone than mutable APIs, but may be inefficient in situations where thousands of objects are allocated each frame. In cases where object garbage collection is a performance concern, prefer the Mutable API (below).

.clone()

clone: () => Mat4

Create a new matrix with the same components as this matrix.

.data()

data: () => number[]

Get the raw data of the matrix, in column-major order.

.decomposeTrs()

decomposeTrs: (target?: {t: Vec3, r: Quat, s: Vec3}) => {t: Vec3, r: Quat, s: Vec3}

Decompose the matrix into its translation, rotation, and scale components, assuming it was formed by a translation, rotation, and scale in that order. If ‘target’ is supplied, the result will be stored in ‘target’ and ‘target’ will be returned. Otherwise, a new {t, r, s} object will be created and returned.

.determinant()

determinant: () => number

Compute the determinant of the matrix.

.equals()

equals: (m: Mat4, tolerance: number) => boolean

Check whether two matrices are equal, with a specified floating point tolerance.

.inv()

inv: () => Mat4

Invert the matrix, or throw if the matrix is not invertible. Because Mat4 stores a precomputed inverse, this operation is very fast.

.inverseData()

inverseData: () => number[] | null

Get the raw data of the inverse matrix, in column-major order, or null if the matrix is not invertible.

.lookAt()

lookAt: (target: Vec3Source, up: Vec3Source) => Mat4

Get a matrix with the same position and scale as this matrix, but with the rotation set to look at the target.

.scale()

scale: (s: number) => Mat4

Multiply the matrix by a scalar. Scaling by 0 throws an error.

.transpose()

transpose: () => Mat4

Get the transpose of the matrix.

.times()

times: (m: Mat4) => Mat4

Multiply the matrix by another matrix.

.timesVec()

timesVec: (v: Vec3Source, target?: Vec3) => Vec3

Multiply the matrix by a vector using homogeneous coordinates.

Mutable API

The following methods perform computations based on the current value of a Mat4, and modify its contents in place. They are parallel to methods in the mutable API above. Methods that return Mat4 types return a reference to the current object for convenient method chaining. Mutable APIs can be more performant than Immutable APIs, but are typically less safe, less readable, and more error-prone. In cases where a section of code will likely not be called many times on a given frame, consider using the Immutable API (above).

This next example is equivalent to the Immutable API example above, but allocates two Mat4 objects instead of seven:

const {mat4, quat, vec3} = ecs.math
const [targetX, targetY, targetZ] = [1, 2, 3]
const [pitch, yaw, distance] = [30, 90, 5]
// Compute orbit controls position based on target position, pitch, yaw, and distance.
const a = mat4.i()
const b = mat4.i()
const v = vec3.zero()
const q = quat.zero()
const orbitPos = a.makeT(v.setXyz(targetX, targetY, targetZ))
.setTimes(b.makeR(q.makePitchYawRollDegrees(v.setXyz(pitch, yaw, 0))))
.setTimes(b.makeT(v.setXyz(0, 0, distance)))
.setTimes(b.makeR(q.makeYDegrees(180)))

.setInv()

setInv: () => Mat4

Invert the matrix, or throw if the matrix is not invertible. Because Mat4 stores a precomputed inverse, this operation is very fast. Store the result in this Mat4 and return this Mat4 for chaining.

.setLookAt()

setLookAt: (target: Vec3Source, up: Vec3Source) => Mat4

Set the matrix rotation to look at the target, keeping translation and scale unchanged. Store the result in this Mat4 and return this Mat4 for chaining.

.setPremultiply()

setPremultiply: (m: Mat4) => Mat4

Sets this matrix the result of m times this matrix. Store the result in this Mat4 and return this Mat4 for chaining.

.setScale()

setScale: (s: number) => Mat4

Multiply each element of the matrix by a scaler. Scaling by 0 throws an error. Store the result in this Mat4 and return this Mat4 for chaining.

.setTimes()

setTimes: (m: Mat4) => Mat4

Multiply the matrix by another matrix. Store the result in this Mat4 and return this Mat4 for chaining.

.setTranspose()

setTranspose: () => Mat4

Set the matrix to its transpose. Store the result in this Mat4 and return this Mat4 for chaining.

Set API

The following methods set the value of the current Mat4 object without regard to its current content, replacing whatever was there before.

.makeI()

makeI: () => Mat4

Set the matrix to the identity matrix. Store the result in this Mat4 and return this Mat4 for chaining.

.makeR()

makeR: (r: QuatSource) => Mat4

Set this matrix to a rotation matrix from the specified quaternion. Store the result in this Mat4 and return this Mat4 for chaining.

.makeRows()

makeRows: (rowData: number[][], inverseRowData?: number[][]) => Mat4

Create a matrix with specified row data, and optionally specified inverse row data. dataRows and inverseDataRows should be four arrays, each with four numbers. If the inverse is not specified, it will be computed if the matrix is invertible. If the matrix is not invertible, calling inv() will throw an error.

.makeS()

makeS: (s: Vec3Source) => Mat4

Set this matrix to a scale matrix from the specified vector. No element of the vector should be zero. Store the result in this Mat4 and return this Mat4 for chaining.

.makeT()

makeT: (t: Vec3Source) => Mat4

Set this matrix to a translation matrix from the specified vector. Store the result in this Mat4 and return this Mat4 for chaining.

.makeTr()

makeTr: (t: Vec3Source, r: QuatSource) => Mat4

Set this matrix to a translation and rotation matrix from the specified vector and quaternion. Store the result in this Mat4 and return this Mat4 for chaining.

.makeTrs()

makeTrs: (t: Vec3Source, r: QuatSource, s: Vec3Source) => Mat4

Set this matrix to a translation, rotation, and scale matrix from the specified vectors and quaternion. Store the result in this Mat4 and return this Mat4 for chaining.

.set()

set: (data: number[], inverseData?: number[]) => Mat4

Sets the value of the matrix and inverse to the provided values. If no inverse is provided, one will be computed if possible. If the matrix is not invertible, calling inv() will throw an error. Store the result in this Mat4 and return this Mat4 for chaining.