JavaScript
var mat4 = {
create: function () {
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
},
translate: function(v) {
return [1, 0, 0, v[0] || 0, 0, 1, 0, v[1] || 0, 0, 0, 1, v[2] || 0, 0, 0, 0, 1];
},
scale: function(v) {
return [v[0] || 1, 0, 0, 0, 0, v[1] || 1, 0, 0, 0, 0, v[2] || 1, 0, 0, 0, 0, 1];
},
rotate: function(r, v) {
var s = Math.sin(r), c = Math.cos(r), C = 1 - c;
return [
C * v[0] * v[0] + c, C * v[0] * v[1] - s * v[2], C * v[0] * v[2] + s * v[1], 0,
C * v[1] * v[0] + s * v[2], C * v[1] * v[1] + c, C * v[1] * v[2] - s * v[0], 0,
C * v[2] * v[0] - s * v[1], C * v[2] * v[1] + s * v[0], C * v[2] * v[2] + c, 0,
0, 0, 0, 1
];
},
perspective: function(fov, aspect, near, far) {
fov = Math.tan(fov * Math.PI / 360);
return [
1 / (aspect * fov), 0, 0, 0,
0, 1 / fov, 0, 0,
0, 0, -(near + far) / (near - far), 2 * far * near / (near - far),
0, 0, 1, 0
];
},
xM: function (a, b) {
return [
a[ 0] * b[0] + a[ 1] * b[4] + a[ 2] * b[ 8] + a[ 3] * b[12],
a[ 0] * b[1] + a[ 1] * b[5] + a[ 2] * b[ 9] + a[ 3] * b[13],
a[ 0] * b[2] + a[ 1] * b[6] + a[ 2] * b[10] + a[ 3] * b[14],
a[ 0] * b[3] + a[ 1] * b[7] + a[ 2] * b[11] + a[ 3] * b[15],
a[ 4] * b[0] + a[ 5] * b[4] + a[ 6] * b[ 8] + a[ 7] * b[12],
a[ 4] * b[1] + a[ 5] * b[5] + a[ 6] * b[ 9] + a[ 7] * b[13],
a[ 4] * b[2] + a[ 5] * b[6] + a[ 6] * b[10] + a[ 7] * b[14],
a[ 4] * b[3] + a[ 5] * b[7] + a[ 6] * b[11] + a[ 7] * b[15],
a[ 8] * b[0] + a[ 9] * b[4] + a[10] * b[ 8] + a[11] * b[12],
a[ 8] * b[1] + a[ 9] * b[5] + a[10] * b[ 9] + a[11] * b[13],
a[ 8] * b[2] + a[ 9] * b[6] + a[10] * b[10] + a[11] * b[14],
a[ 8] * b[3] + a[ 9] * b[7] + a[10] * b[11] + a[11] * b[15],
a[12] * b[0] + a[13] * b[4] + a[14] * b[ 8] + a[15] * b[12],
a[12] * b[1] + a[13] * b[5] + a[14] * b[ 9] + a[15] * b[13],
a[12] * b[2] + a[13] * b[6] + a[14] *...