@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
72 lines (62 loc) • 2.51 kB
JavaScript
/**
* Inverts a 4x4 matrix
* @see Adapted from glMatrix
* @param {Float64Array|Float32Array|number[]|mat4} out
* @param {Float64Array|Float32Array|number[]|mat4} input
* @returns {boolean} true iff determinant is not 0, otherwise matrix is non-invertible and false is returned
*/
export function m4_invert(out, input) {
const a00 = input[0],
a01 = input[1],
a02 = input[2],
a03 = input[3];
const a10 = input[4],
a11 = input[5],
a12 = input[6],
a13 = input[7];
const a20 = input[8],
a21 = input[9],
a22 = input[10],
a23 = input[11];
const a30 = input[12],
a31 = input[13],
a32 = input[14],
a33 = input[15];
const b00 = a00 * a11 - a01 * a10;
const b01 = a00 * a12 - a02 * a10;
const b02 = a00 * a13 - a03 * a10;
const b03 = a01 * a12 - a02 * a11;
const b04 = a01 * a13 - a03 * a11;
const b05 = a02 * a13 - a03 * a12;
const b06 = a20 * a31 - a21 * a30;
const b07 = a20 * a32 - a22 * a30;
const b08 = a20 * a33 - a23 * a30;
const b09 = a21 * a32 - a22 * a31;
const b10 = a21 * a33 - a23 * a31;
const b11 = a22 * a33 - a23 * a32;
// Calculate the determinant
const det =
b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (det === 0) {
// determinant is 0, can't invert
return false;
}
const inv_det = 1.0 / det;
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * inv_det;
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * inv_det;
out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * inv_det;
out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * inv_det;
out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * inv_det;
out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * inv_det;
out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * inv_det;
out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * inv_det;
out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * inv_det;
out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * inv_det;
out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * inv_det;
out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * inv_det;
out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * inv_det;
out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * inv_det;
out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * inv_det;
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * inv_det;
return true;
}