Created
September 3, 2021 16:40
-
-
Save samwightt/146b1145527a564b656134a511665e43 to your computer and use it in GitHub Desktop.
Non-shitty angle.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////// | |
// | |
// Angel.js | |
// | |
////////////////////////////////////////////////////////////////////////////// | |
//---------------------------------------------------------------------------- | |
// | |
// Helper functions | |
// | |
//---------------------------------------------------------------------------- | |
export function radians(degrees: number) { | |
return (degrees * Math.PI) / 180.0; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Vector Constructors | |
// | |
type Vec2 = [number, number]; | |
export function vec2(): Vec2; | |
export function vec2(pointOne: number): Vec2; | |
export function vec2(pointOne: number, pointTwo: number): Vec2; | |
export function vec2(pointOne?: number, pointTwo?: number): Vec2 { | |
if (!pointOne) return [0.0, 0.0]; | |
else if (!pointTwo) return [pointOne, 0.0]; | |
else return [pointOne, pointTwo]; | |
} | |
type Vec3 = [number, number, number]; | |
export function vec3(): Vec3; | |
export function vec3(pointOne: number): Vec3; | |
export function vec3(one: number, two: number): Vec3; | |
export function vec3(one: number, two: number, three: number): Vec3; | |
export function vec3( | |
pointOne?: number, | |
pointTwo?: number, | |
pointThree?: number | |
): Vec3 { | |
if (!pointOne) { | |
return [0.0, 0.0, 0.0]; | |
} else if (!pointTwo) { | |
return [pointOne, 0.0, 0.0]; | |
} else if (!pointThree) { | |
return [pointOne, pointTwo, 0.0]; | |
} else return [pointOne, pointTwo, pointThree]; | |
} | |
type Vec4 = [number, number, number, number]; | |
export function vec4(): Vec4; | |
export function vec4(one: number): Vec4; | |
export function vec4(one: number, two: number): Vec4; | |
export function vec4(one: number, two: number, three: number): Vec4; | |
export function vec4( | |
one: number, | |
two: number, | |
three: number, | |
four: number | |
): Vec4; | |
export function vec4( | |
one?: number, | |
two?: number, | |
three?: number, | |
four?: number | |
) { | |
if (!one) return [0.0, 0.0, 0.0, 0.0]; | |
else if (!two) return [one, 0.0, 0.0, 0.0]; | |
else if (!three) return [one, two, 0.0, 0.0]; | |
else if (!four) return [one, two, three, 0.0]; | |
else return [one, two, three, four]; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Matrix Constructors | |
// | |
type Mat2 = [Vec2, Vec2]; | |
export function mat2(): Mat2; | |
export function mat2(one: number): Mat2; | |
export function mat2(one: Vec2, two: Vec2): Mat2; | |
export function mat2(one?: number | Vec2, two?: Vec2): Mat2 { | |
if (!one || (one && !two)) return [vec2(), vec2()]; | |
else if (typeof one === "number") { | |
return [vec2(one, 0.0), vec2(0.0, one)]; | |
} else return [one, two as Vec2]; | |
} | |
//---------------------------------------------------------------------------- | |
type Mat3 = [Vec3, Vec3, Vec3]; | |
export function mat3(): Mat3; | |
export function mat3(num: number): Mat3; | |
export function mat3(one: Vec3, two: Vec3, three: Vec3): Mat3; | |
export function mat3(one?: number | Vec3, two?: Vec3, three?: Vec3): Mat3 { | |
if (!one || (one && !two && !three)) return [vec3(), vec3(), vec3()]; | |
else if (typeof one === "number") | |
return [vec3(one, 0.0, 0.0), vec3(0.0, one, 0.0), vec3(0.0, 0.0, one)]; | |
else return [one, two as Vec3, three as Vec3]; | |
} | |
//---------------------------------------------------------------------------- | |
type Mat4 = [Vec4, Vec4, Vec4, Vec4]; | |
export function mat4(): Mat4; | |
export function mat4(num: number): Mat4; | |
export function mat4(one: Vec4, two: Vec4, three: Vec4, four: Vec4): Mat4; | |
export function mat4( | |
one?: number | Vec4, | |
two?: Vec4, | |
three?: Vec4, | |
four?: Vec4 | |
): Mat4 { | |
if (!one || (one && (!two || !three || !four))) | |
return [vec4(), vec4(), vec4(), vec4()]; | |
else if (typeof one === "number") | |
return [ | |
vec4(one, 0.0, 0.0, 0.0), | |
vec4(0.0, one, 0.0, 0.0), | |
vec4(0.0, 0.0, one, 0.0), | |
vec4(0.0, 0.0, 0.0, one), | |
]; | |
else return [one, two as Vec4, three as Vec4, four as Vec4]; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Generic Mathematical Operations for Vectors and Matrices | |
// | |
type Vector = Vec2 | Vec3 | Vec4 | number[]; | |
type Matrix = Mat2 | Mat3 | Mat4 | number[][]; | |
type VectorOrMatrix = Vector | Matrix; | |
function isMatrix(u: VectorOrMatrix): u is Matrix { | |
return Array.isArray(u[0]); | |
} | |
export function equal(u: VectorOrMatrix, v: VectorOrMatrix): boolean { | |
if (u.length != v.length) { | |
return false; | |
} | |
if (isMatrix(u) && isMatrix(v)) { | |
for (var i = 0; i < u.length; ++i) { | |
if (u[i].length != v[i].length) { | |
return false; | |
} | |
for (var j = 0; j < u[i].length; ++j) { | |
if (u[i][j] !== v[i][j]) { | |
return false; | |
} | |
} | |
} | |
} else if ((isMatrix(u) && !isMatrix(v)) || (!isMatrix(u) && isMatrix(v))) { | |
return false; | |
} else { | |
for (var i = 0; i < u.length; ++i) { | |
if (u[i] !== v[i]) { | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
//---------------------------------------------------------------------------- | |
export function add<M extends Matrix>(matrixOne: M, matrixTwo: M): M; | |
export function add<V extends Vector>(vectorOne: V, vectorTwo: V): V; | |
export function add(u: VectorOrMatrix, v: VectorOrMatrix): VectorOrMatrix { | |
if (isMatrix(u) && isMatrix(v)) { | |
let result: number[][] = []; | |
if (u.length != v.length) { | |
throw new Error("add(): trying to add matrices of different dimensions"); | |
} | |
for (var i = 0; i < u.length; ++i) { | |
if (u[i].length != v[i].length) { | |
throw new Error( | |
"add(): trying to add matrices of different dimensions" | |
); | |
} | |
result.push([]); | |
for (var j = 0; j < u[i].length; ++j) { | |
result[i].push(u[i][j] + v[i][j]); | |
} | |
} | |
return result as Matrix; | |
} else if ((isMatrix(u) && !isMatrix(v)) || (!isMatrix(u) && isMatrix(v))) { | |
throw new Error("add(): trying to add matrix and non-matrix variables"); | |
} else if (!isMatrix(u) && !isMatrix(v)) { | |
let result: number[] = []; | |
if (u.length != v.length) { | |
throw new Error("add(): vectors are not the same dimension"); | |
} | |
for (var i = 0; i < u.length; ++i) { | |
result.push(u[i] + v[i]); | |
} | |
return result as Vector; | |
} | |
throw new Error("Could not add matrices or vectors"); | |
} | |
//---------------------------------------------------------------------------- | |
export function subtract<M extends Matrix>(one: M, two: M): M; | |
export function subtract<V extends Vector>(one: V, two: V): V; | |
export function subtract(u: VectorOrMatrix, v: VectorOrMatrix): VectorOrMatrix { | |
if (isMatrix(u) && isMatrix(v)) { | |
let result: number[][] = []; | |
if (u.length != v.length) { | |
throw new Error( | |
"subtract(): trying to subtract matrices" + " of different dimensions" | |
); | |
} | |
for (var i = 0; i < u.length; ++i) { | |
if (u[i].length != v[i].length) { | |
throw new Error( | |
"subtract(): trying to subtact matrices" + " of different dimensions" | |
); | |
} | |
result.push([]); | |
for (var j = 0; j < u[i].length; ++j) { | |
result[i].push(u[i][j] - v[i][j]); | |
} | |
} | |
return result; | |
} else if ((isMatrix(u) && !isMatrix(v)) || (!isMatrix(u) && isMatrix(v))) { | |
throw new Error( | |
"subtact(): trying to subtact matrix and non-matrix variables" | |
); | |
} else if (!isMatrix(u) && !isMatrix(v)) { | |
let result: number[] = []; | |
if (u.length != v.length) { | |
throw new Error("subtract(): vectors are not the same length"); | |
} | |
for (var i = 0; i < u.length; ++i) { | |
result.push(u[i] - v[i]); | |
} | |
return result; | |
} | |
throw new Error("Could not subtract."); | |
} | |
//---------------------------------------------------------------------------- | |
export function mult(u: Matrix, v: Matrix): Matrix; | |
export function mult(u: Vector, v: Vector): Vector; | |
export function mult(u: VectorOrMatrix, v: VectorOrMatrix): VectorOrMatrix { | |
if (isMatrix(u) && isMatrix(v)) { | |
let result: number[][] = []; | |
if (u.length != v.length) { | |
throw new Error("mult(): trying to add matrices of different dimensions"); | |
} | |
for (var i = 0; i < u.length; ++i) { | |
if (u[i].length != v[i].length) { | |
throw new Error( | |
"mult(): trying to add matrices of different dimensions" | |
); | |
} | |
} | |
for (var i = 0; i < u.length; ++i) { | |
result.push([]); | |
for (var j = 0; j < v.length; ++j) { | |
var sum = 0.0; | |
for (var k = 0; k < u.length; ++k) { | |
sum += u[i][k] * v[k][j]; | |
} | |
result[i].push(sum); | |
} | |
} | |
return result; | |
} else if (!isMatrix(u) && !isMatrix(v)) { | |
let result: number[] = []; | |
if (u.length != v.length) { | |
throw "mult(): vectors are not the same dimension"; | |
} | |
for (var i = 0; i < u.length; ++i) { | |
result.push(u[i] * v[i]); | |
} | |
return result; | |
} | |
throw new Error("Could not multiply."); | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Basic Transformation Matrix Generators | |
// | |
export function translate(x: Vec3): Mat4; | |
export function translate(x: number, y: number, z: number): Mat4; | |
export function translate(x: number | Vec3, y?: number, z?: number): Mat4 { | |
let newPoint: [number, number, number] = [0.0, 0.0, 0.0]; | |
if (Array.isArray(x)) { | |
newPoint[0] = x[0]; | |
newPoint[1] = x[1]; | |
newPoint[2] = x[2]; | |
} else { | |
newPoint[0] = x; | |
newPoint[1] = y as number; | |
newPoint[2] = z as number; | |
} | |
var result = mat4(); | |
result[0][3] = newPoint[0]; | |
result[1][3] = newPoint[1]; | |
result[2][3] = newPoint[2]; | |
return result; | |
} | |
//---------------------------------------------------------------------------- | |
export function rotate(angle: number, axis: Vec3): Mat4 { | |
if (!Array.isArray(axis)) { | |
axis = [arguments[1], arguments[2], arguments[3]]; | |
} | |
var v = normalize(axis); | |
var x = v[0]; | |
var y = v[1]; | |
var z = v[2]; | |
var c = Math.cos(radians(angle)); | |
var omc = 1.0 - c; | |
var s = Math.sin(radians(angle)); | |
var result = mat4( | |
vec4(x * x * omc + c, x * y * omc - z * s, x * z * omc + y * s, 0.0), | |
vec4(x * y * omc + z * s, y * y * omc + c, y * z * omc - x * s, 0.0), | |
vec4(x * z * omc - y * s, y * z * omc + x * s, z * z * omc + c, 0.0), | |
vec4() | |
); | |
return result; | |
} | |
//---------------------------------------------------------------------------- | |
export function scalem(x: Vec3): Mat4; | |
export function scalem(x: number, y: number, z: number): Mat4; | |
export function scalem(x: Vec3 | number, y?: number, z?: number): Mat4 { | |
let points: Vec3 = [0.0, 0.0, 0.0]; | |
if (Array.isArray(x)) { | |
points = [...x]; | |
} else { | |
points = [x, y as number, z as number]; | |
} | |
var result = mat4(); | |
result[0][0] = points[0]; | |
result[1][1] = points[1]; | |
result[2][2] = points[2]; | |
return result; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// ModelView Matrix Generators | |
// | |
export function lookAt(eye: Vec3, at: Vec3, up: Vec3): Mat4 { | |
if (equal(eye, at)) { | |
return mat4(); | |
} | |
var v = normalize(subtract(at, eye)); // view direction vector | |
var n = normalize(cross(v, up)); // perpendicular vector | |
var u = normalize(cross(n, v)); // "new" up vector | |
v = negate(v); | |
var result = mat4( | |
vec4(...n, -dot(n, eye)), | |
vec4(...u, -dot(u, eye)), | |
vec4(...v, -dot(v, eye)), | |
vec4() | |
); | |
return result; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Projection Matrix Generators | |
// | |
export function ortho( | |
left: number, | |
right: number, | |
bottom: number, | |
top: number, | |
near: number, | |
far: number | |
): Mat4 { | |
if (left == right) { | |
throw new Error("ortho(): left and right are equal"); | |
} | |
if (bottom == top) { | |
throw new Error("ortho(): bottom and top are equal"); | |
} | |
if (near == far) { | |
throw new Error("ortho(): near and far are equal"); | |
} | |
var w = right - left; | |
var h = top - bottom; | |
var d = far - near; | |
var result = mat4(); | |
result[0][0] = 2.0 / w; | |
result[1][1] = 2.0 / h; | |
result[2][2] = -2.0 / d; | |
result[0][3] = -(left + right) / w; | |
result[1][3] = -(top + bottom) / h; | |
result[2][3] = -(near + far) / d; | |
return result; | |
} | |
//---------------------------------------------------------------------------- | |
export function perspective( | |
fovy: number, | |
aspect: number, | |
near: number, | |
far: number | |
): Mat4 { | |
var f = 1.0 / Math.tan(radians(fovy) / 2); | |
var d = far - near; | |
var result = mat4(); | |
result[0][0] = f / aspect; | |
result[1][1] = f; | |
result[2][2] = -(near + far) / d; | |
result[2][3] = (-2 * near * far) / d; | |
result[3][2] = -1; | |
result[3][3] = 0.0; | |
return result; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Matrix Functions | |
// | |
function transpose<M extends Matrix>(m: M): M { | |
var result: Matrix = []; | |
for (var i = 0; i < m.length; ++i) { | |
result.push([]); | |
for (var j = 0; j < m[i].length; ++j) { | |
result[i].push(m[j][i]); | |
} | |
} | |
return result as M; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Vector Functions | |
// | |
function dot<V extends Vector>(u: V, v: V): number { | |
if (u.length != v.length) { | |
throw "dot(): vectors are not the same dimension"; | |
} | |
var sum = 0.0; | |
for (var i = 0; i < u.length; ++i) { | |
sum += u[i] * v[i]; | |
} | |
return sum; | |
} | |
//---------------------------------------------------------------------------- | |
function negate<V extends Vector>(u: V): V { | |
var result = []; | |
for (var i = 0; i < u.length; ++i) { | |
result.push(-u[i]); | |
} | |
return result as V; | |
} | |
//---------------------------------------------------------------------------- | |
function cross<V extends Vector>(uVec: V, vVec: V): V { | |
if (!Array.isArray(uVec) || uVec.length < 3) { | |
throw "cross(): first argument is not a vector of at least 3"; | |
} | |
if (!Array.isArray(vVec) || vVec.length < 3) { | |
throw "cross(): second argument is not a vector of at least 3"; | |
} | |
let u = uVec as any; | |
let v = vVec as any; | |
var result = [ | |
u[1] * v[2] - u[2] * v[1], | |
u[2] * v[0] - u[0] * v[2], | |
u[0] * v[1] - u[1] * v[0], | |
]; | |
return result as V; | |
} | |
//---------------------------------------------------------------------------- | |
function length(u: Vector): number { | |
return Math.sqrt(dot(u, u)); | |
} | |
//---------------------------------------------------------------------------- | |
function normalize<V extends Vector>(u: V, excludeLastComponent?: boolean): V { | |
let last: null | number = null; | |
if (excludeLastComponent) { | |
last = u.pop() || null; | |
} | |
var len = length(u); | |
if (!isFinite(len)) { | |
throw "normalize: vector " + u + " has zero length"; | |
} | |
for (var i = 0; i < u.length; ++i) { | |
u[i] /= len; | |
} | |
if (excludeLastComponent && last !== null) { | |
u.push(last); | |
} | |
return u; | |
} | |
//---------------------------------------------------------------------------- | |
export function mix<V extends Vector>(u: V, v: V, s: number): V { | |
if (typeof s !== "number") { | |
throw "mix: the last paramter " + s + " must be a number"; | |
} | |
if (u.length != v.length) { | |
throw "vector dimension mismatch"; | |
} | |
var result: number[] = []; | |
for (var i = 0; i < u.length; ++i) { | |
result.push((1.0 - s) * u[i] + s * v[i]); | |
} | |
return result as V; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// Vector and Matrix functions | |
// | |
export function scale<V extends Vector>(s: number, u: V): V { | |
if (!Array.isArray(u)) { | |
throw "scale: second parameter " + u + " is not a vector"; | |
} | |
var result: number[] = []; | |
for (var i = 0; i < u.length; ++i) { | |
result.push(s * u[i]); | |
} | |
return result as V; | |
} | |
//---------------------------------------------------------------------------- | |
// | |
// | |
// | |
function flatten(v: VectorOrMatrix): Float32Array { | |
if (isMatrix(v)) { | |
v = transpose(v); | |
} | |
let n = v.length; | |
let elemsAreArrays = false; | |
if (Array.isArray(v[0])) { | |
elemsAreArrays = true; | |
n *= v[0].length; | |
} | |
const floats = new Float32Array(n); | |
if (isMatrix(v)) { | |
var idx = 0; | |
for (var i = 0; i < v.length; ++i) { | |
for (var j = 0; j < v[i].length; ++j) { | |
floats[idx++] = v[i][j]; | |
} | |
} | |
} else { | |
for (var i = 0; i < v.length; ++i) { | |
floats[i] = v[i]; | |
} | |
} | |
return floats; | |
} | |
//---------------------------------------------------------------------------- | |
export const sizeof = { | |
vec2: new Float32Array(flatten(vec2())).byteLength, | |
vec3: new Float32Array(flatten(vec3())).byteLength, | |
vec4: new Float32Array(flatten(vec4())).byteLength, | |
mat2: new Float32Array(flatten(mat2())).byteLength, | |
mat3: new Float32Array(flatten(mat3())).byteLength, | |
mat4: new Float32Array(flatten(mat4())).byteLength, | |
}; | |
// new functions 5/2/2015 | |
// printing | |
export function printm(m: Matrix) { | |
if (m.length == 2) | |
for (var i = 0; i < m.length; i++) console.log(m[i][0], m[i][1]); | |
else if (m.length == 3) | |
for (var i = 0; i < m.length; i++) console.log(m[i][0], m[i][1], m[i][2]); | |
else if (m.length == 4) | |
for (var i = 0; i < m.length; i++) | |
console.log(m[i][0], m[i][1], m[i][2], m[i][3]); | |
} | |
// determinants | |
export function det2(m: Mat2): number { | |
return m[0][0] * m[1][1] - m[0][1] * m[1][0]; | |
} | |
export function det3(m: Mat3): number { | |
var d = | |
m[0][0] * m[1][1] * m[2][2] + | |
m[0][1] * m[1][2] * m[2][0] + | |
m[0][2] * m[2][1] * m[1][0] - | |
m[2][0] * m[1][1] * m[0][2] - | |
m[1][0] * m[0][1] * m[2][2] - | |
m[0][0] * m[1][2] * m[2][1]; | |
return d; | |
} | |
export function det4(m: Mat4): number { | |
var m0: Mat3 = [ | |
vec3(m[1][1], m[1][2], m[1][3]), | |
vec3(m[2][1], m[2][2], m[2][3]), | |
vec3(m[3][1], m[3][2], m[3][3]), | |
]; | |
var m1: Mat3 = [ | |
vec3(m[1][0], m[1][2], m[1][3]), | |
vec3(m[2][0], m[2][2], m[2][3]), | |
vec3(m[3][0], m[3][2], m[3][3]), | |
]; | |
var m2: Mat3 = [ | |
vec3(m[1][0], m[1][1], m[1][3]), | |
vec3(m[2][0], m[2][1], m[2][3]), | |
vec3(m[3][0], m[3][1], m[3][3]), | |
]; | |
var m3: Mat3 = [ | |
vec3(m[1][0], m[1][1], m[1][2]), | |
vec3(m[2][0], m[2][1], m[2][2]), | |
vec3(m[3][0], m[3][1], m[3][2]), | |
]; | |
return ( | |
m[0][0] * det3(m0) - | |
m[0][1] * det3(m1) + | |
m[0][2] * det3(m2) - | |
m[0][3] * det3(m3) | |
); | |
} | |
export function det(m: Matrix): number { | |
if (!isMatrix(m)) throw new Error("Argument is not matrix."); | |
if (m.length == 2) return det2(m as Mat2); | |
if (m.length == 3) return det3(m as Mat3); | |
if (m.length == 4) return det4(m as Mat4); | |
throw new Error("Could not get determinant."); | |
} | |
//--------------------------------------------------------- | |
// inverses | |
export function inverse2(m: Mat2): Mat2 { | |
var a = mat2(); | |
var d = det2(m); | |
a[0][0] = m[1][1] / d; | |
a[0][1] = -m[0][1] / d; | |
a[1][0] = -m[1][0] / d; | |
a[1][1] = m[0][0] / d; | |
return a; | |
} | |
function inverse3(m: Mat3): Mat3 { | |
var a = mat3(); | |
var d = det3(m); | |
var a00: Mat2 = [vec2(m[1][1], m[1][2]), vec2(m[2][1], m[2][2])]; | |
var a01: Mat2 = [vec2(m[1][0], m[1][2]), vec2(m[2][0], m[2][2])]; | |
var a02: Mat2 = [vec2(m[1][0], m[1][1]), vec2(m[2][0], m[2][1])]; | |
var a10: Mat2 = [vec2(m[0][1], m[0][2]), vec2(m[2][1], m[2][2])]; | |
var a11: Mat2 = [vec2(m[0][0], m[0][2]), vec2(m[2][0], m[2][2])]; | |
var a12: Mat2 = [vec2(m[0][0], m[0][1]), vec2(m[2][0], m[2][1])]; | |
var a20: Mat2 = [vec2(m[0][1], m[0][2]), vec2(m[1][1], m[1][2])]; | |
var a21: Mat2 = [vec2(m[0][0], m[0][2]), vec2(m[1][0], m[1][2])]; | |
var a22: Mat2 = [vec2(m[0][0], m[0][1]), vec2(m[1][0], m[1][1])]; | |
a[0][0] = det2(a00) / d; | |
a[0][1] = -det2(a10) / d; | |
a[0][2] = det2(a20) / d; | |
a[1][0] = -det2(a01) / d; | |
a[1][1] = det2(a11) / d; | |
a[1][2] = -det2(a21) / d; | |
a[2][0] = det2(a02) / d; | |
a[2][1] = -det2(a12) / d; | |
a[2][2] = det2(a22) / d; | |
return a; | |
} | |
function inverse4(m: Mat4): Mat4 { | |
var a = mat4(); | |
var d = det4(m); | |
var a00 = mat3( | |
vec3(m[1][1], m[1][2], m[1][3]), | |
vec3(m[2][1], m[2][2], m[2][3]), | |
vec3(m[3][1], m[3][2], m[3][3]) | |
); | |
var a01 = mat3( | |
vec3(m[1][0], m[1][2], m[1][3]), | |
vec3(m[2][0], m[2][2], m[2][3]), | |
vec3(m[3][0], m[3][2], m[3][3]) | |
); | |
var a02 = mat3( | |
vec3(m[1][0], m[1][1], m[1][3]), | |
vec3(m[2][0], m[2][1], m[2][3]), | |
vec3(m[3][0], m[3][1], m[3][3]) | |
); | |
var a03 = mat3( | |
vec3(m[1][0], m[1][1], m[1][2]), | |
vec3(m[2][0], m[2][1], m[2][2]), | |
vec3(m[3][0], m[3][1], m[3][2]) | |
); | |
var a10 = mat3( | |
vec3(m[0][1], m[0][2], m[0][3]), | |
vec3(m[2][1], m[2][2], m[2][3]), | |
vec3(m[3][1], m[3][2], m[3][3]) | |
); | |
var a11 = mat3( | |
vec3(m[0][0], m[0][2], m[0][3]), | |
vec3(m[2][0], m[2][2], m[2][3]), | |
vec3(m[3][0], m[3][2], m[3][3]) | |
); | |
var a12 = mat3( | |
vec3(m[0][0], m[0][1], m[0][3]), | |
vec3(m[2][0], m[2][1], m[2][3]), | |
vec3(m[3][0], m[3][1], m[3][3]) | |
); | |
var a13 = mat3( | |
vec3(m[0][0], m[0][1], m[0][2]), | |
vec3(m[2][0], m[2][1], m[2][2]), | |
vec3(m[3][0], m[3][1], m[3][2]) | |
); | |
var a20 = mat3( | |
vec3(m[0][1], m[0][2], m[0][3]), | |
vec3(m[1][1], m[1][2], m[1][3]), | |
vec3(m[3][1], m[3][2], m[3][3]) | |
); | |
var a21 = mat3( | |
vec3(m[0][0], m[0][2], m[0][3]), | |
vec3(m[1][0], m[1][2], m[1][3]), | |
vec3(m[3][0], m[3][2], m[3][3]) | |
); | |
var a22 = mat3( | |
vec3(m[0][0], m[0][1], m[0][3]), | |
vec3(m[1][0], m[1][1], m[1][3]), | |
vec3(m[3][0], m[3][1], m[3][3]) | |
); | |
var a23 = mat3( | |
vec3(m[0][0], m[0][1], m[0][2]), | |
vec3(m[1][0], m[1][1], m[1][2]), | |
vec3(m[3][0], m[3][1], m[3][2]) | |
); | |
var a30 = mat3( | |
vec3(m[0][1], m[0][2], m[0][3]), | |
vec3(m[1][1], m[1][2], m[1][3]), | |
vec3(m[2][1], m[2][2], m[2][3]) | |
); | |
var a31 = mat3( | |
vec3(m[0][0], m[0][2], m[0][3]), | |
vec3(m[1][0], m[1][2], m[1][3]), | |
vec3(m[2][0], m[2][2], m[2][3]) | |
); | |
var a32 = mat3( | |
vec3(m[0][0], m[0][1], m[0][3]), | |
vec3(m[1][0], m[1][1], m[1][3]), | |
vec3(m[2][0], m[2][1], m[2][3]) | |
); | |
var a33 = mat3( | |
vec3(m[0][0], m[0][1], m[0][2]), | |
vec3(m[1][0], m[1][1], m[1][2]), | |
vec3(m[2][0], m[2][1], m[2][2]) | |
); | |
a[0][0] = det3(a00) / d; | |
a[0][1] = -det3(a10) / d; | |
a[0][2] = det3(a20) / d; | |
a[0][3] = -det3(a30) / d; | |
a[1][0] = -det3(a01) / d; | |
a[1][1] = det3(a11) / d; | |
a[1][2] = -det3(a21) / d; | |
a[1][3] = det3(a31) / d; | |
a[2][0] = det3(a02) / d; | |
a[2][1] = -det3(a12) / d; | |
a[2][2] = det3(a22) / d; | |
a[2][3] = -det3(a32) / d; | |
a[3][0] = -det3(a03) / d; | |
a[3][1] = det3(a13) / d; | |
a[3][2] = -det3(a23) / d; | |
a[3][3] = det3(a33) / d; | |
return a; | |
} | |
function inverse<M extends Matrix>(m: M): M { | |
if (!isMatrix(m)) throw new Error("Not a matrix."); | |
if (m.length == 2) return inverse2(m as Mat2) as M; | |
if (m.length == 3) return inverse3(m as Mat3) as M; | |
if (m.length == 4) return inverse4(m as Mat4) as M; | |
throw new Error("Could not find the inverse of the matrix."); | |
} | |
export function normalMatrix<M extends Matrix>(m: M, flag: boolean): M { | |
var a = inverse(transpose(m)); | |
if (!flag) return a; | |
else { | |
var b = mat3(); | |
for (var i = 0; i < 3; i++) for (var j = 0; j < 3; j++) b[i][j] = a[i][j]; | |
return b as M; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment