summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/rectangles/models/mat4.js
blob: b0611992d8f33cb1fb03222c15cd7e21949af483 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
function mat4(e){
	this.elements = [ 1, 0, 0, 0,
	                  0, 1, 0, 0,
	                  0, 0, 1, 0,
	                  0, 0, 0, 1 ]
	return this
}
mat4.prototype.set = function (a) {
	var els = this.elements
	a.forEach(function(n,i){ els[i] = n })
	return this
}
mat4.prototype.clone = function(){
	return (new mat4).set(this.els)
}
mat4.prototype.identity = function () {
	this.set([
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		0, 0, 0, 1
	]);
	return this;
}
mat4.prototype.getInverse = function (m, throwOnInvertible) {

	// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
	var te = this.elements;
	var me = m.elements;

	var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
	var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
	var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
	var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];

	te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
	te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
	te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
	te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
	te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
	te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
	te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
	te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
	te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
	te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
	te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
	te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
	te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
	te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
	te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
	te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;

	var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ];

	if ( det == 0 ) {
		var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0";

		if ( throwOnInvertible || false ) {
			throw new Error( msg )
		}
		else {
			console.warn( msg )
		}
		this.identity();
		return this
	}
	this.multiplyScalar( 1 / det );
	return this
}
mat4.prototype.multiplyScalar = function (n) {
	var els = this.elements
	els[0] *= n; els[4] *= n; els[8]  *= n; els[12] *= n
	els[1] *= n; els[5] *= n; els[9]  *= n; els[13] *= n
	els[2] *= n; els[6] *= n; els[10] *= n; els[14] *= n
	els[3] *= n; els[7] *= n; els[11] *= n; els[15] *= n
	return this
}