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.