var identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
/**
* 四维矩阵
* @module lego/Matrix4
* @namespace lego.Matrix4
* @requires lego/Vector3
*/
var Matrix4 = {
/**
* @memberOf lego.Matrix4
*/
create: function() {
return identityMatrix.concat();
},
/**
*@memberOf lego.Matrix4
*/
clone: function(mat) {
return mat.concat();
},
/**
*@memberOf lego.Matrix4
*/
setIdentity: function(mat) {
this.set(mat, identityMatrix);
},
/**
*@memberOf lego.Matrix4
*/
set: function(mat0, mat1) {
for (var i = 0; i < 16; i++) {
mat0[i] = mat1[i];
}
},
/**
*@memberOf lego.Matrix4
*/
concat: function(mat0, mat1) {
var i, e, a, b, ai0, ai1, ai2, ai3;
e = mat0;
a = mat0;
b = mat1;
if (e === b) {
b = this.clone(e);
}
for (i = 0; i < 4; i++) {
ai0 = a[i];
ai1 = a[i + 4];
ai2 = a[i + 8];
ai3 = a[i + 12];
e[i] = ai0 * b[0] + ai1 * b[1] + ai2 * b[2] + ai3 * b[3];
e[i + 4] = ai0 * b[4] + ai1 * b[5] + ai2 * b[6] + ai3 * b[7];
e[i + 8] = ai0 * b[8] + ai1 * b[9] + ai2 * b[10] + ai3 * b[11];
e[i + 12] = ai0 * b[12] + ai1 * b[13] + ai2 * b[14] + ai3 * b[15];
}
},
/**
*@memberOf lego.Matrix4
*/
multiplyVector3: function(mat, vec) {
var result = Vector3.create();
result[0] = vec[0] * mat[0] + vec[1] * mat[4] + vec[2] * mat[8] + mat[12];
result[1] = vec[0] * mat[1] + vec[1] * mat[5] + vec[2] * mat[9] + mat[13];
result[2] = vec[0] * mat[2] + vec[1] * mat[6] + vec[2] * mat[10] + mat[14];
return result;
},
/**
*@memberOf lego.Matrix4
*/
transpose: function(mat) {
var t;
t = mat[1];
mat[1] = mat[4];
mat[4] = t;
t = mat[2];
mat[2] = mat[8];
mat[8] = t;
t = mat[3];
mat[3] = mat[12];
mat[12] = t;
t = mat[6];
mat[6] = mat[9];
mat[9] = t;
t = mat[7];
mat[7] = mat[13];
mat[13] = t;
t = mat[11];
mat[11] = mat[14];
mat[14] = t;
},
/**
*@memberOf lego.Matrix4
*/
setScale:function(mat, x, y, z) {
mat[0] = x;
mat[4] = 0;
mat[8] = 0;
mat[12] = 0;
mat[1] = 0;
mat[5] = y;
mat[9] = 0;
mat[13] = 0;
mat[2] = 0;
mat[6] = 0;
mat[10] = z;
mat[14] = 0;
mat[3] = 0;
mat[7] = 0;
mat[11] = 0;
mat[15] = 1;
},
/**
*@memberOf lego.Matrix4
*/
scale:function(mat, x, y, z) {
mat[0] *= x;
mat[4] *= y;
mat[8] *= z;
mat[1] *= x;
mat[5] *= y;
mat[9] *= z;
mat[2] *= x;
mat[6] *= y;
mat[10] *= z;
mat[3] *= x;
mat[7] *= y;
mat[11] *= z;
},
/**
*@memberOf lego.Matrix4
*/
setTranslate: function(mat, x, y, z) {
mat[0] = 1;
mat[4] = 0;
mat[8] = 0;
mat[12] = x;
mat[1] = 0;
mat[5] = 1;
mat[9] = 0;
mat[13] = y;
mat[2] = 0;
mat[6] = 0;
mat[10] = 1;
mat[14] = z;
mat[3] = 0;
mat[7] = 0;
mat[11] = 0;
mat[15] = 1;
},
/**
*@memberOf lego.Matrix4
*/
translate: function(mat, x, y, z) {
mat[12] += mat[0] * x + mat[4] * y + mat[8] * z;
mat[13] += mat[1] * x + mat[5] * y + mat[9] * z;
mat[14] += mat[2] * x + mat[6] * y + mat[10] * z;
mat[15] += mat[3] * x + mat[7] * y + mat[11] * z;
},
/**
*@memberOf lego.Matrix4
*/
setRotate: function(mat, angle, x, y, z) {
var e, s, c, len, rlen, nc, xy, yz, zx, xs, ys, zs;
angle = Math.PI * angle / 180;
s = Math.sin(angle);
c = Math.cos(angle);
if (0 !== x && 0 === y && 0 === z){
// Rotation around X axis
if (x < 0) {
s = -s;
}
mat[0] = 1;
mat[4] = 0;
mat[8] = 0;
mat[12] = 0;
mat[1] = 0;
mat[5] = c;
mat[9] = -s;
mat[13] = 0;
mat[2] = 0;
mat[6] = s;
mat[10] = c;
mat[14] = 0;
mat[3] = 0;
mat[7] = 0;
mat[11] = 0;
mat[15] = 1;
}
else if (0 === x && 0 !== y && 0 === z){
// Rotation around Y axis
if (y < 0) {
s = -s;
}
mat[0] = c;
mat[4] = 0;
mat[8] = s;
mat[12] = 0;
mat[1] = 0;
mat[5] = 1;
mat[9] = 0;
mat[13] = 0;
mat[2] = -s;
mat[6] = 0;
mat[10] = c;
mat[14] = 0;
mat[3] = 0;
mat[7] = 0;
mat[11] = 0;
mat[15] = 1;
}
else if (0 === x && 0 === y && 0 !== z){
// Rotation around Z axis
if (z < 0){
s = -s;
}
mat[0] = c;
mat[4] = -s;
mat[8] = 0;
mat[12] = 0;
mat[1] = s;
mat[5] = c;
mat[9] = 0;
mat[13] = 0;
mat[2] = 0;
mat[6] = 0;
mat[10] = 1;
mat[14] = 0;
mat[3] = 0;
mat[7] = 0;
mat[11] = 0;
mat[15] = 1;
}
else {
// Rotation around another axis
len = Math.sqrt(x * x + y * y + z * z);
if (len !== 1) {
rlen = 1 / len;
x *= rlen;
y *= rlen;
z *= rlen;
}
nc = 1 - c;
xy = x * y;
yz = y * z;
zx = z * x;
xs = x * s;
ys = y * s;
zs = z * s;
mat[0] = x * x * nc + c;
mat[1] = xy * nc + zs;
mat[2] = zx * nc - ys;
mat[3] = 0;
mat[4] = xy * nc - zs;
mat[5] = y * y * nc + c;
mat[6] = yz * nc + xs;
mat[7] = 0;
mat[8] = zx * nc + ys;
mat[9] = yz * nc - xs;
mat[10] = z * z * nc + c;
mat[11] = 0;
mat[12] = 0;
mat[13] = 0;
mat[14] = 0;
mat[15] = 1;
}
},
/**
*@memberOf lego.Matrix4
*/
rotate: function(mat, angle, x, y, z) {
var m = this.create();
this.setRotate(m, angle, x, y, z);
this.concat(mat, m);
}
};