UNPKG

ol

Version:

OpenLayers mapping library

257 lines (234 loc) • 5.78 kB
/** * @module ol/vec/mat4 */ /** @typedef {Array<number>} Mat4 */ /** * @return {Mat4} "4x4 matrix representing a 3D identity transform." */ export function create() { return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } /** * @param {Mat4} out Flattened 4x4 matrix being reset. * @return {Mat4} Reset 4x4 matrix */ export function reset(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * @param {Mat4} mat4 Flattened 4x4 matrix receiving the result. * @param {import("../transform.js").Transform} transform Transformation matrix. * @return {Mat4} "2D transformation matrix as flattened 4x4 matrix." */ export function fromTransform(mat4, transform) { mat4[0] = transform[0]; mat4[1] = transform[1]; mat4[4] = transform[2]; mat4[5] = transform[3]; mat4[12] = transform[4]; mat4[13] = transform[5]; return mat4; } /** * Generates a orthogonal projection matrix with the given bounds * * @param {number} left Left bound of the frustum * @param {number} right Right bound of the frustum * @param {number} bottom Bottom bound of the frustum * @param {number} top Top bound of the frustum * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @param {Mat4} [out] mat4 frustum matrix will be written into * @return {Mat4} out */ export function orthographic(left, right, bottom, top, near, far, out) { out = out ?? create(); const lr = 1 / (left - right), bt = 1 / (bottom - top), nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; } /** * Scales the mat4 by the dimensions in the given vec3 * * @param {Mat4} m The matrix to scale. * @param {number} x How much to scale in the x direction. * @param {number} y How much to scale in the y direction. * @param {number} z How much to scale in the z direction. * @param {Mat4} [out] The matrix to write to. * @return {Mat4} out */ export function scale(m, x, y, z, out) { out = out ?? create(); out[0] = m[0] * x; out[1] = m[1] * x; out[2] = m[2] * x; out[3] = m[3] * x; out[4] = m[4] * y; out[5] = m[5] * y; out[6] = m[6] * y; out[7] = m[7] * y; out[8] = m[8] * z; out[9] = m[9] * z; out[10] = m[10] * z; out[11] = m[11] * z; out[12] = m[12]; out[13] = m[13]; out[14] = m[14]; out[15] = m[15]; return out; } /** * Translate a matrix. * * @param {Mat4} m the matrix to translate * @param {number} x How much to translate in the x direction. * @param {number} y How much to translate in the y direction. * @param {number} z How much to translate in the z direction. * @param {Mat4} [out] the receiving matrix * @return {Mat4} out */ export function translate(m, x, y, z, out) { out = out ?? create(); let a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; if (m === out) { out[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; out[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; out[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; out[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; } else { a00 = m[0]; a01 = m[1]; a02 = m[2]; a03 = m[3]; a10 = m[4]; a11 = m[5]; a12 = m[6]; a13 = m[7]; a20 = m[8]; a21 = m[9]; a22 = m[10]; a23 = m[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + m[12]; out[13] = a01 * x + a11 * y + a21 * z + m[13]; out[14] = a02 * x + a12 * y + a22 * z + m[14]; out[15] = a03 * x + a13 * y + a23 * z + m[15]; } return out; } /** * @param {number} x x translation. * @param {number} y y translation. * @param {number} z z translation. * @param {Mat4} [out] optional matrix to store result * @return {Mat4} out */ export function translation(x, y, z, out) { out = out ?? create(); out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = x; out[13] = y; out[14] = z; out[15] = 1; return out; } /** * Rotate a matrix around the Z axis, only affecting X and Y components. * * @param {Mat4} m the matrix to rotate * @param {number} angle How much to rotate (in radians). * @param {Mat4} [out] the receiving matrix * @return {Mat4} out */ export function rotate(m, angle, out) { out = out ?? create(); const cos = Math.cos(angle), sin = Math.sin(angle); // rotation matrix components const a11 = cos; const a12 = -sin; const a21 = sin; const a22 = cos; const b11 = m[0]; const b12 = m[1]; const b13 = m[2]; const b14 = m[3]; const b21 = m[4]; const b22 = m[5]; const b23 = m[6]; const b24 = m[7]; out[0] = a11 * b11 + a12 * b21; out[1] = a11 * b12 + a12 * b22; out[2] = a11 * b13 + a12 * b23; out[3] = a11 * b14 + a12 * b24; out[4] = a21 * b11 + a22 * b21; out[5] = a21 * b12 + a22 * b22; out[6] = a21 * b13 + a22 * b23; out[7] = a21 * b14 + a22 * b24; if (out !== m) { out[8] = m[8]; out[9] = m[9]; out[10] = m[10]; out[11] = m[11]; out[12] = m[12]; out[13] = m[13]; out[14] = m[14]; out[15] = m[15]; } return out; }