§ Единичная матрица

Единичная матрица выглядит так.
1identity() {
2
3	return [
4		[1, 0, 0, 0],
5		[0, 1, 0, 0],
6		[0, 0, 1, 0],
7		[0, 0, 0, 1],
8	];
9}
При умножении матрицу на единичную матрицу, любая другая матрица равна самой себе.

§ Умножение матриц

Теперь же приведу код для умножения матриц 4x4.
1mult(m1, m2) {
2
3	let mat = [];
4	for (let a = 0; a < 4; a++) {
5
6		let row = [];
7		for (let b = 0; b < 4; b++) {
8
9			let s = 0;
10			for (let c = 0; c < 4; c++) s += m1[a][c]*m2[c][b];
11			row.push(s);
12		}
13
14		mat.push(row);
15	}
16
17	return mat;
18}
Пришло время сделать методы для поворотов по X,Y,Z, а также матрицы перемещения (трансляции). На вход подается матрица m, и угол поворота в радианах. Для матрицы трансляции требуется вектор p типа vec3.
Поворот по оси X
1rotateX(m, angle) {
2
3	let [s,c] = [Math.sin(angle), Math.cos(angle)];
4
5	return this.mult(m, [
6		[1, 0,  0, 0],
7		[0, c, -s, 0],
8		[0, s,  c, 0],
9		[0, 0,  0, 1]
10	]);
11}
Поворот по оси Y
1rotateY(m, angle) {
2
3	let [s,c] = [Math.sin(angle), Math.cos(angle)];
4
5	return this.mult(m, [
6		[ c, 0, s, 0],
7		[ 0, 1, 0, 0],
8		[-s, 0, c, 0],
9		[ 0, 0, 0, 1]
10	]);
11}
Поворот по оси Z
1rotateZ(m, angle) {
2
3	let [s,c] = [Math.sin(angle), Math.cos(angle)];
4
5	return this.mult(m, [
6		[c, -s, 0, 0],
7		[s,  c, 0, 0],
8		[0,  0, 1, 0],
9		[0,  0, 0, 1]
10	]);
11}
Трансляция матрицы
1translate(m, p) {
2
3	return this.mult(m, [
4		[1, 0, 0, 0],
5		[0, 1, 0, 0],
6		[0, 0, 1, 0],
7		[p.x, p.y, p.z, 1]
8	]);
9}

§ Умножение вектора на матрицу

На вход метода поступает m - матрица, и vtx — массив вершин, которые будут преобразованы в новые вершины типа vec3:
1matrix_apply(vtx, m) {
2
3	let out = [];
4	for (let i = 0; i < vtx.length; i++) {
5
6		let t = [vtx[i].x, vtx[i].y, vtx[i].z, 1];
7		let n = [0, 0, 0];
8		for (let a = 0; a < 3; a++) {
9
10			let s = 0;
11			for (let b = 0; b < 4; b++) s += t[b] * m[b][a];
12			n[a] = s;
13		}
14
15		out.push( { x:n[0], y:n[1], z:n[2] } );
16	}
17
18	return out;
19}