summaryrefslogtreecommitdiffstats
path: root/o3d/samples/o3d-webgl/transform.js
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/samples/o3d-webgl/transform.js')
-rw-r--r--o3d/samples/o3d-webgl/transform.js1309
1 files changed, 802 insertions, 507 deletions
diff --git a/o3d/samples/o3d-webgl/transform.js b/o3d/samples/o3d-webgl/transform.js
index 677e36b..9d1a8f9 100644
--- a/o3d/samples/o3d-webgl/transform.js
+++ b/o3d/samples/o3d-webgl/transform.js
@@ -58,13 +58,13 @@ o3d.Transform =
* Default = Identity.
*/
this.localMatrix = opt_localMatrix ||
- [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ o3d.Transform.makeIdentityMatrix4_();
/**
* World (model) matrix as it was last computed.
*/
this.worldMatrix = opt_worldMatrix ||
- [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ o3d.Transform.makeIdentityMatrix4_();
/**
* Sets the parent of the transform by re-parenting the transform under
@@ -230,11 +230,11 @@ o3d.Transform.prototype.getUpdatedWorldMatrix =
var parentWorldMatrix;
if (!this.parent) {
parentWorldMatrix =
- [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ o3d.Transform.makeIdentityMatrix4_();
} else {
parentWorldMatrix = this.parent.getUpdatedWorldMatrix();
}
- o3d.Transform.compose(parentWorldMatrix, this.localMatrix, this.worldMatrix);
+ o3d.Transform.compose_(parentWorldMatrix, this.localMatrix, this.worldMatrix);
return this.worldMatrix;
};
@@ -295,238 +295,12 @@ o3d.Transform.prototype.identity = function() {
var m = this.localMatrix;
for (var i = 0; i < 4; ++i) {
for (var j = 0; j < 4; ++j) {
- m[i][j] = i==j ? 1 : 0;
+ m[i * 4 + j] = i == j ? 1 : 0;
}
}
};
-/*
- * Utility function to copose a matrix with another matrix.
- * Precomposes b with a, changing a, or if the target matrix if
- * one is provided.
- *
- * @param {!Array.<!Array.<number>>} a
- * @param {!Array.<!Array.<number>>} b
- * @param {!Array.<!Array.<number>>} opt_target
- */
-o3d.Transform.compose = function(a, b, opt_target) {
- var t = opt_target || a;
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var a3 = a[3];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var b3 = b[3];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a03 = a0[3];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a13 = a1[3];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var a23 = a2[3];
- var a30 = a3[0];
- var a31 = a3[1];
- var a32 = a3[2];
- var a33 = a3[3];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b03 = b0[3];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b13 = b1[3];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- var b23 = b2[3];
- var b30 = b3[0];
- var b31 = b3[1];
- var b32 = b3[2];
- var b33 = b3[3];
- t[0].splice(0, 4, a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03,
- a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03,
- a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03,
- a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03);
- t[1].splice(0, 4, a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13,
- a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13,
- a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13,
- a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13);
- t[2].splice(0, 4, a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23,
- a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23,
- a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23,
- a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23);
- t[3].splice(0, 4, a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33,
- a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33,
- a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33,
- a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
-};
-
-
-/**
- * Tests whether two matrices are either equal in the sense that they
- * refer to the same memory, or equal in the sense that they have equal
- * entries.
- *
- * @param {!Array.<!Array.<number>>} a A matrix.
- * @param {!Array.<!Array.<number>>} b Another matrix.
- * @return {boolean} Whether they are equal.
- */
-o3d.Transform.matricesEqual = function(a, b) {
- if (a==b) {
- return true;
- }
- for (var i = 0; i < 4; ++i) {
- for (var j = 0; j < 4; ++j) {
- if (a[i][j] != b[i][j]) {
- return false;
- }
- }
- }
- return true;
-};
-
-
-/**
- * Computes the transpose of the matrix a in place if no target is provided.
- * Or if a target is provided, turns the target into the transpose of a.
- *
- * @param {!Array.<!Array.<number>>} m A matrix.
- * @param {Array.<!Array.<number>>} opt_target
- * The matrix to become the transpose of m.
- */
-o3d.Transform.transpose = function(m, opt_target) {
- var t = opt_target || m;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
- t[0].splice(0, 4, m00, m10, m20, m30);
- t[1].splice(0, 4, m01, m11, m21, m31);
- t[2].splice(0, 4, m02, m12, m22, m32);
- t[3].splice(0, 4, m03, m13, m23, m33);
-};
-
-
-/**
- * Computes the inverse of the matrix a in place if no target is provided.
- * Or if a target is provided, turns the target into the transpose of a.
- *
- * @param {!Array.<!Array.<number>>} m A matrix.
- * @param {Array.<!Array.<number>>} opt_target The matrix to become the
- * inverse of a.
- */
-o3d.Transform.inverse = function(m, opt_target) {
- var t = opt_target || m;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- var tmp_0 = m22 * m33;
- var tmp_1 = m32 * m23;
- var tmp_2 = m12 * m33;
- var tmp_3 = m32 * m13;
- var tmp_4 = m12 * m23;
- var tmp_5 = m22 * m13;
- var tmp_6 = m02 * m33;
- var tmp_7 = m32 * m03;
- var tmp_8 = m02 * m23;
- var tmp_9 = m22 * m03;
- var tmp_10 = m02 * m13;
- var tmp_11 = m12 * m03;
- var tmp_12 = m20 * m31;
- var tmp_13 = m30 * m21;
- var tmp_14 = m10 * m31;
- var tmp_15 = m30 * m11;
- var tmp_16 = m10 * m21;
- var tmp_17 = m20 * m11;
- var tmp_18 = m00 * m31;
- var tmp_19 = m30 * m01;
- var tmp_20 = m00 * m21;
- var tmp_21 = m20 * m01;
- var tmp_22 = m00 * m11;
- var tmp_23 = m10 * m01;
-
- var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) -
- (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);
- var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) -
- (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);
- var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) -
- (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);
- var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) -
- (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);
-
- var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
-
- t[0].splice(0, 4, d * t0, d * t1, d * t2, d * t3);
- t[1].splice(0, 4, d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) -
- (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)),
- d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) -
- (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)),
- d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) -
- (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)),
- d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) -
- (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)));
- t[2].splice(0, 4, d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) -
- (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)),
- d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) -
- (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)),
- d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) -
- (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)),
- d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) -
- (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)));
- t[3].splice(0, 4, d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) -
- (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)),
- d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) -
- (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)),
- d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) -
- (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)),
- d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) -
- (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)));
-};
-
-
/**
* Pre-composes the local matrix of this Transform with a translation. For
* example, if the local matrix is a rotation then new local matrix will
@@ -545,31 +319,28 @@ o3d.Transform.prototype.translate =
var v0 = v[0];
var v1 = v[1];
var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- m3.splice(0, 4, m00 * v0 + m10 * v1 + m20 * v2 + m30,
- m01 * v0 + m11 * v1 + m21 * v2 + m31,
- m02 * v0 + m12 * v1 + m22 * v2 + m32,
- m03 * v0 + m13 * v1 + m23 * v2 + m33);
+
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
+ var m30 = m[12];
+ var m31 = m[13];
+ var m32 = m[14];
+ var m33 = m[15];
+
+ m[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30,
+ m[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31,
+ m[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32,
+ m[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33;
};
@@ -584,100 +355,26 @@ o3d.Transform.prototype.rotateX =
function(angle) {
var m = this.localMatrix;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
+
var c = Math.cos(angle);
var s = Math.sin(angle);
- m1.splice(0, 4, c * m10 + s * m20,
- c * m11 + s * m21,
- c * m12 + s * m22,
- c * m13 + s * m23);
- m2.splice(0, 4, c * m20 - s * m10,
- c * m21 - s * m11,
- c * m22 - s * m12,
- c * m23 - s * m13);
-};
-
-
-/**
- * Takes a 4-by-4 matrix and a vector with 3 entries,
- * interprets the vector as a point, transforms that point by the matrix, and
- * returns the result as a vector with 3 entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The point.
- * @return {!o3djs.math.Vector3} The transformed point.
- */
-o3d.Transform.transformPoint = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- var d = v0 * m0[3] + v1 * m1[3] + v2 * m2[3] + m3[3];
- return [(v0 * m0[0] + v1 * m1[0] + v2 * m2[0] + m3[0]) / d,
- (v0 * m0[1] + v1 * m1[1] + v2 * m2[1] + m3[1]) / d,
- (v0 * m0[2] + v1 * m1[2] + v2 * m2[2] + m3[2]) / d];
-};
-
-
-/**
- * Takes a 4-by-4 matrix and a vector with 4 entries,
- * interprets the vector as a point, transforms that point by the matrix, and
- * returns the result as a vector with 4 entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector4} v The vector.
- * @return {!o3djs.math.Vector4} The transformed vector.
- */
-o3d.Transform.multiplyVector = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var v3 = v[3];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- return [(v0 * m0[0] + v1 * m1[0] + v2 * m2[0] + v3 * m3[0]),
- (v0 * m0[1] + v1 * m1[1] + v2 * m2[1] + v3 * m3[1]),
- (v0 * m0[2] + v1 * m1[2] + v2 * m2[2] + v3 * m3[2]),
- (v0 * m0[3] + v1 * m1[3] + v2 * m2[3] + v3 * m3[3])];
-};
-
-
-/**
- * Takes a 4-by-4 matrix and a vector with 3 entries,
- * interprets the vector as a point, transforms that point by the matrix,
- * returning the z-component of the result only.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The point.
- * @return {number} The z coordinate of the transformed point.
- */
-o3d.Transform.transformPointZOnly = function(m, v) {
- var v0 = v[0];
- var v1 = v[1];
- var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- return (v0 * m0[2] + v1 * m1[2] + v2 * m2[2] + m3[2]) /
- (v0 * m0[3] + v1 * m1[3] + v2 * m2[3] + m3[3]);
+ m[4] = c * m10 + s * m20;
+ m[5] = c * m11 + s * m21;
+ m[6] = c * m12 + s * m22;
+ m[7] = c * m13 + s * m23;
+ m[8] = c * m20 - s * m10;
+ m[9] = c * m21 - s * m11;
+ m[10] = c * m22 - s * m12;
+ m[11] = c * m23 - s * m13;
};
@@ -692,29 +389,25 @@ o3d.Transform.prototype.rotateY =
function(angle) {
var m = this.localMatrix;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
var c = Math.cos(angle);
var s = Math.sin(angle);
- m0.splice(0, 4, c * m00 - s * m20,
- c * m01 - s * m21,
- c * m02 - s * m22,
- c * m03 - s * m23);
- m2.splice(0, 4, c * m20 + s * m00,
- c * m21 + s * m01,
- c * m22 + s * m02,
- c * m23 + s * m03);
+ m[0] = c * m00 - s * m20;
+ m[1] = c * m01 - s * m21;
+ m[2] = c * m02 - s * m22;
+ m[3] = c * m03 - s * m23;
+ m[8] = c * m20 + s * m00;
+ m[9] = c * m21 + s * m01;
+ m[10] = c * m22 + s * m02;
+ m[11] = c * m23 + s * m03;
};
@@ -729,29 +422,25 @@ o3d.Transform.prototype.rotateZ =
function(angle) {
var m = this.localMatrix;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
var c = Math.cos(angle);
var s = Math.sin(angle);
- m0.splice(0, 4, c * m00 + s * m10,
- c * m01 + s * m11,
- c * m02 + s * m12,
- c * m03 + s * m13);
- m1.splice(0, 4, c * m10 - s * m00,
- c * m11 - s * m01,
- c * m12 - s * m02,
- c * m13 - s * m03);
+ m[0] = c * m00 + s * m10;
+ m[1] = c * m01 + s * m11;
+ m[2] = c * m02 + s * m12;
+ m[3] = c * m03 + s * m13;
+ m[4] = c * m10 - s * m00;
+ m[5] = c * m11 - s * m01;
+ m[6] = c * m12 - s * m02;
+ m[7] = c * m13 - s * m03;
};
@@ -788,45 +477,37 @@ o3d.Transform.prototype.rotateZYX =
var r21 = sinZSinY * cosX - cosZ * sinX;
var r22 = cosY * cosX;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- m0.splice(0, 4,
- r00 * m00 + r01 * m10 + r02 * m20,
- r00 * m01 + r01 * m11 + r02 * m21,
- r00 * m02 + r01 * m12 + r02 * m22,
- r00 * m03 + r01 * m13 + r02 * m23);
-
- m1.splice(0, 4,
- r10 * m00 + r11 * m10 + r12 * m20,
- r10 * m01 + r11 * m11 + r12 * m21,
- r10 * m02 + r11 * m12 + r12 * m22,
- r10 * m03 + r11 * m13 + r12 * m23);
-
- m2.splice(0, 4,
- r20 * m00 + r21 * m10 + r22 * m20,
- r20 * m01 + r21 * m11 + r22 * m21,
- r20 * m02 + r21 * m12 + r22 * m22,
- r20 * m03 + r21 * m13 + r22 * m23);
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
+ var m30 = m[12];
+ var m31 = m[13];
+ var m32 = m[14];
+ var m33 = m[15];
+
+ m[0] = r00 * m00 + r01 * m10 + r02 * m20;
+ m[1] = r00 * m01 + r01 * m11 + r02 * m21;
+ m[2] = r00 * m02 + r01 * m12 + r02 * m22;
+ m[3] = r00 * m03 + r01 * m13 + r02 * m23;
+
+ m[4] = r10 * m00 + r11 * m10 + r12 * m20;
+ m[5] = r10 * m01 + r11 * m11 + r12 * m21;
+ m[6] = r10 * m02 + r11 * m12 + r12 * m22;
+ m[7] = r10 * m03 + r11 * m13 + r12 * m23;
+
+ m[8] = r20 * m00 + r21 * m10 + r22 * m20;
+ m[9] = r20 * m01 + r21 * m11 + r22 * m21;
+ m[10] = r20 * m02 + r21 * m12 + r22 * m22;
+ m[11] = r20 * m03 + r21 * m13 + r22 * m23;
};
@@ -871,47 +552,36 @@ o3d.Transform.axisRotateMatrix =
var r21 = y * z * oneMinusCosine - x * s;
var r22 = zz + (1 - zz) * c;
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- var m00 = m0[0];
- var m01 = m0[1];
- var m02 = m0[2];
- var m03 = m0[3];
- var m10 = m1[0];
- var m11 = m1[1];
- var m12 = m1[2];
- var m13 = m1[3];
- var m20 = m2[0];
- var m21 = m2[1];
- var m22 = m2[2];
- var m23 = m2[3];
- var m30 = m3[0];
- var m31 = m3[1];
- var m32 = m3[2];
- var m33 = m3[3];
-
- opt_target[0].splice(0, 4,
- r00 * m00 + r01 * m10 + r02 * m20,
- r00 * m01 + r01 * m11 + r02 * m21,
- r00 * m02 + r01 * m12 + r02 * m22,
- r00 * m03 + r01 * m13 + r02 * m23);
-
- opt_target[1].splice(0, 4,
- r10 * m00 + r11 * m10 + r12 * m20,
- r10 * m01 + r11 * m11 + r12 * m21,
- r10 * m02 + r11 * m12 + r12 * m22,
- r10 * m03 + r11 * m13 + r12 * m23);
-
- opt_target[2].splice(0, 4,
- r20 * m00 + r21 * m10 + r22 * m20,
- r20 * m01 + r21 * m11 + r22 * m21,
- r20 * m02 + r21 * m12 + r22 * m22,
- r20 * m03 + r21 * m13 + r22 * m23);
-
- opt_target[3].splice(0, 4, m30, m31, m32, m33);
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
+ var m30 = m[12];
+ var m31 = m[13];
+ var m32 = m[14];
+ var m33 = m[15];
+
+ m[0] = r00 * m00 + r01 * m10 + r02 * m20;
+ m[1] = r00 * m01 + r01 * m11 + r02 * m21;
+ m[2] = r00 * m02 + r01 * m12 + r02 * m22;
+ m[3] = r00 * m03 + r01 * m13 + r02 * m23;
+ m[4] = r10 * m00 + r11 * m10 + r12 * m20;
+ m[5] = r10 * m01 + r11 * m11 + r12 * m21;
+ m[6] = r10 * m02 + r11 * m12 + r12 * m22;
+ m[7] = r10 * m03 + r11 * m13 + r12 * m23;
+
+ m[8] = r20 * m00 + r21 * m10 + r22 * m20;
+ m[9] = r20 * m01 + r21 * m11 + r22 * m21;
+ m[10] = r20 * m02 + r21 * m12 + r22 * m22;
+ m[11] = r20 * m03 + r21 * m13 + r22 * m23;
};
@@ -950,17 +620,17 @@ o3d.Transform.prototype.quaternionRotate =
var d = qWqW + qXqX + qYqY + qZqZ;
- o3d.Transform.compose(this.localMatrix, [
- [(qWqW + qXqX - qYqY - qZqZ) / d,
+ o3d.Transform.compose_(this.localMatrix, o3d.Transform.makeMatrix4_(
+ (qWqW + qXqX - qYqY - qZqZ) / d,
2 * (qWqZ + qXqY) / d,
- 2 * (qXqZ - qWqY) / d, 0],
- [2 * (qXqY - qWqZ) / d,
+ 2 * (qXqZ - qWqY) / d, 0,
+ 2 * (qXqY - qWqZ) / d,
(qWqW - qXqX + qYqY - qZqZ) / d,
- 2 * (qWqX + qYqZ) / d, 0],
- [2 * (qWqY + qXqZ) / d,
+ 2 * (qWqX + qYqZ) / d, 0,
+ 2 * (qWqY + qXqZ) / d,
2 * (qYqZ - qWqX) / d,
- (qWqW - qXqX - qYqY + qZqZ) / d, 0],
- [0, 0, 0, 1]]);
+ (qWqW - qXqX - qYqY + qZqZ) / d, 0,
+ 0, 0, 0, 1));
};
@@ -984,32 +654,18 @@ o3d.Transform.prototype.scale =
var v1 = v[1];
var v2 = v[2];
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
-
- m0.splice(0, 4, v0 * m0[0], v0 * m0[1], v0 * m0[2], v0 * m0[3]);
- m1.splice(0, 4, v1 * m1[0], v1 * m1[1], v1 * m1[2], v1 * m1[3]);
- m2.splice(0, 4, v2 * m2[0], v2 * m2[1], v2 * m2[2], v2 * m2[3]);
-};
-
-
-/**
- * Utility function to flatten an o3djs-style matrix
- * (which is an array of arrays) into one array of entries.
- * @param {Array.<Array.<number> >} m The o3djs-style matrix.
- * @return {Array.<number>} The flattened matrix.
- */
-o3d.Transform.flattenMatrix4 = function(m) {
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
- var m3 = m[3];
- return [m0[0], m0[1], m0[2], m0[3],
- m1[0], m1[1], m1[2], m1[3],
- m2[0], m2[1], m2[2], m2[3],
- m3[0], m3[1], m3[2], m3[3]];
+ m[0] = v0 * m[0];
+ m[1] = v0 * m[1];
+ m[2] = v0 * m[2];
+ m[3] = v0 * m[3];
+ m[4] = v1 * m[4];
+ m[5] = v1 * m[5];
+ m[6] = v1 * m[6];
+ m[7] = v1 * m[7];
+ m[8] = v2 * m[8];
+ m[9] = v2 * m[9];
+ m[10] = v2 * m[10];
+ m[11] = v2 * m[11];
};
@@ -1027,10 +683,9 @@ o3d.Transform.prototype.traverse =
return;
}
opt_parentWorldMatrix =
- opt_parentWorldMatrix ||
- [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
+ opt_parentWorldMatrix || o3d.Transform.makeIdentityMatrix4_();
- o3d.Transform.compose(
+ o3d.Transform.compose_(
opt_parentWorldMatrix, this.localMatrix, this.worldMatrix);
var remainingDrawListInfos = [];
@@ -1040,10 +695,10 @@ o3d.Transform.prototype.traverse =
for (var i = 0; i < drawListInfos.length; ++i) {
var drawListInfo = drawListInfos[i];
- var worldViewProjection = [[], [], [], []];
- o3d.Transform.compose(drawListInfo.context.view,
+ var worldViewProjection = o3d.Transform.makeNullMatrix4_();
+ o3d.Transform.compose_(drawListInfo.context.view,
this.worldMatrix, worldViewProjection);
- o3d.Transform.compose(drawListInfo.context.projection,
+ o3d.Transform.compose_(drawListInfo.context.projection,
worldViewProjection, worldViewProjection);
if (this.boundingBox.inFrustum(worldViewProjection)) {
@@ -1073,3 +728,643 @@ o3d.Transform.prototype.traverse =
};
+/**
+ * Tells the o3d-webgl subsection if it should use native javascript
+ * arrays or if it should switch to the newer Float32Array, which help the
+ * interpreter, once created, but can require a lot of gc work to allocate
+ * and deallocate.
+ * @type {boolean}
+ */
+o3d.Transform.useFloat32Array_ = false;
+
+
+/**
+ * This defines the type of any given Matrix4
+ * @type {!Array.<number>|!Float32Array}
+ */
+o3d.Transform.Matrix4 = goog.typedef;
+
+
+/**
+ * This returns an identity 4x4 matrix with
+ * the diagonal as 1's and everything else 0
+ * @return {!o3d.Transform.Matrix4}
+ * @private
+ */
+o3d.Transform.makeIdentityMatrix4_ = null;
+
+
+/**
+ * This returns a 4x4 matrix with all values set to zero
+ * @return {!o3d.Transform.Matrix4} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.makeNullMatrix4_ = null;
+
+
+/**
+ * This returns a length 2 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @return {!Float32Array} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.makeVector2_ = null;
+
+
+/**
+ * This returns a length 3 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @param {number} c the z element in the vector
+ * @return {!Float32Array} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.makeVector3_ = null;
+
+
+/**
+ * This returns a length 4 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @param {number} c the z element in the vector
+ * @param {number} d the w element in the vector
+ * @return {!Float32Array} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.makeVector4_ = null;
+
+
+/**
+ * This returns a 4x4 matrix in row major order
+ * with values set to the passed in arguments
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [0][3] element
+ * @param {number} e [1][0] element
+ * @param {number} f [1][1] element
+ * @param {number} g [1][2] element
+ * @param {number} h [1][3] element
+ * @param {number} i [2][0] element
+ * @param {number} j [2][1] element
+ * @param {number} k [2][2] element
+ * @param {number} l [2][3] element
+ * @param {number} m [3][0] element
+ * @param {number} n [3][1] element
+ * @param {number} o [3][2] element
+ * @param {number} p [3][3] element
+ * @return {!o3d.Transform.Matrix4}
+ */
+o3d.Transform.makeMatrix4_ = null;
+
+
+// If Float32Array isn't defined we might as well not bother including the
+// Float32Array functions.
+if (window.Float32Array != undefined) {
+ /**
+ * A namespace to hold Float32Array-specialized functions.
+ * @namespace
+ * @private
+ */
+ o3d.Transform.Float32Array_ = {};
+
+
+ /**
+ * This defines the type of any given Matrix4 in the Float32Array namespace
+ * @type {function}
+ * @private
+ */
+ o3d.Transform.Float32Array_.Matrix4 = Float32Array;
+
+
+ /**
+ * This returns an identity 4x4 matrix with
+ * the diagonal as 1's and everything else 0
+ * @return {!o3d.Transform.Matrix4}
+ * @private
+ */
+ o3d.Transform.Float32Array_.makeIdentityMatrix4_ = function() {
+ var r = new Float32Array(16);
+ r[0] = 1;
+ r[5] = 1;
+ r[10] = 1;
+ r[15] = 1;
+ return r;
+ };
+
+
+ /**
+ * This returns a 4x4 matrix with all values set to zero
+ * @return {!o3d.Transform.Matrix4} the vector made up of the elements
+ * @private
+ */
+ o3d.Transform.Float32Array_.makeNullMatrix4_ = function() {
+ return new Float32Array(16);
+ };
+
+
+ /**
+ * This returns a length 2 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @return {!Float32Array} the vector made up of the elements
+ * @private
+ */
+ o3d.Transform.Float32Array_.makeVector2_ = function(a, b) {
+ var f=new Float32Array(2);
+ f[0] = a;
+ f[1] = b;
+ return f;
+ };
+
+
+ /**
+ * This returns a length 3 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @param {number} c the z element in the vector
+ * @return {!Float32Array} the vector made up of the elements
+ * @private
+ */
+ o3d.Transform.Float32Array_.makeVector3_ = function(a, b, c) {
+ var f=new Float32Array(3);
+ f[0] = a;
+ f[1] = b;
+ f[2] = c;
+ return f;
+ };
+
+
+ /**
+ * This returns a length 4 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @param {number} c the z element in the vector
+ * @param {number} d the w element in the vector
+ * @return {!Float32Array} the vector made up of the elements
+ * @private
+ */
+ o3d.Transform.Float32Array_.makeVector4_ = function(a, b, c, d) {
+ var f = new Float32Array(4);
+ f[0] = a;
+ f[1] = b;
+ f[2] = c;
+ f[3] = d;
+ return f;
+ };
+
+
+ /**
+ * This returns a 4x4 matrix in row major order
+ * with values set to the passed in arguments
+ * @param {number} a [0][0] element
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [0][3] element
+ * @param {number} e [1][0] element
+ * @param {number} f [1][1] element
+ * @param {number} g [1][2] element
+ * @param {number} h [1][3] element
+ * @param {number} i [2][0] element
+ * @param {number} j [2][1] element
+ * @param {number} k [2][2] element
+ * @param {number} l [2][3] element
+ * @param {number} m [3][0] element
+ * @param {number} n [3][1] element
+ * @param {number} o [3][2] element
+ * @param {number} p [3][3] element
+ * @return {!o3d.Transform.Matrix4}
+ */
+ o3d.Transform.Float32Array_.makeMatrix4_ =
+ function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+ var m = new Float32Array(16);
+ m[0] = a;
+ m[1] = b;
+ m[2] = c;
+ m[3] = d;
+ m[4] = e;
+ m[5] = f;
+ m[6] = g;
+ m[7] = h;
+ m[8] = i;
+ m[9] = j;
+ m[10] = k;
+ m[11] = l;
+ m[12] = m;
+ m[13] = n;
+ m[14] = o;
+ m[15] = p;
+ return m;
+ };
+} else {
+ // If Float32Array doesn't exist, we cannot use that library.
+ o3d.Transform.useFloat32Array_ = false;
+}
+
+
+/**
+ * A namespace for Array specialized Transform functions that depend
+ * on what the matrix type of choice is
+ * @namespace
+ * @private
+ */
+o3d.Transform.Array_ = {};
+
+/**
+ * This returns a length 3 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @return {!Array} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.Array_.makeVector2_ = function(a, b) {
+ return [a,b];
+};
+
+/**
+ * This returns a length 3 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @param {number} c the z element in the vector
+ * @return {!Array} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.Array_.makeVector3_ = function(a, b, c) {
+ return [a, b, c];
+};
+
+/**
+ * This returns a length 4 vector with values set to the passed in arguments
+ * @param {number} a the x element in the vector
+ * @param {number} b the y element in the vector
+ * @param {number} c the z element in the vector
+ * @param {number} d the w element in the vector
+ * @return {!Array} the vector made up of the elements
+ * @private
+ */
+o3d.Transform.Array_.makeVector4_ = function(a, b, c, d) {
+ return [a, b, c, d];
+};
+
+/**
+ * This returns a 4x4 matrix in row major order
+ * with values set to the passed in arguments
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [0][3] element
+ * @param {number} e [1][0] element
+ * @param {number} f [1][1] element
+ * @param {number} g [1][2] element
+ * @param {number} h [1][3] element
+ * @param {number} i [2][0] element
+ * @param {number} j [2][1] element
+ * @param {number} k [2][2] element
+ * @param {number} l [2][3] element
+ * @param {number} m [3][0] element
+ * @param {number} n [3][1] element
+ * @param {number} o [3][2] element
+ * @param {number} p [3][3] element
+ * @return {!o3d.Transform.Matrix4}
+ * @private
+ */
+o3d.Transform.Array_.makeMatrix4_ =
+ function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+ return [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p];
+};
+
+o3d.Transform.Array_.Matrix4_ = Array;
+
+/**
+ * This returns an identity 4x4 matrix with
+ * the diagonal as 1's and everything else 0
+ * @return {!o3d.Transform.Matrix4}
+ */
+o3d.Transform.Array_.makeIdentityMatrix4_ = function() {
+ return [1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1];
+};
+
+
+/**
+ * This returns an identity 4x4 matrix with all values as 0
+ * @return {!o3d.Transform.Matrix4}
+ */
+o3d.Transform.Array_.makeNullMatrix4_ = function() {
+ return [0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0];
+};
+
+
+if (o3d.Transform.useFloat32Array_) {
+ for (var i in o3d.Transform.Float32Array_) {
+ o3d.Transform[i] = o3d.Transform.Float32Array_[i];
+ }
+} else {
+ for (var i in o3d.Transform.Array_) {
+ o3d.Transform[i] = o3d.Transform.Array_[i];
+ }
+}
+
+
+/*
+ * Utility function to copose a matrix with another matrix.
+ * Precomposes b with a, changing a, or if the target matrix if
+ * one is provided.
+ *
+ * @param {!Array.<!Array.<number>>} a
+ * @param {!Array.<!Array.<number>>} b
+ * @param {!Array.<!Array.<number>>} opt_target
+ * @private
+ */
+o3d.Transform.compose_ = function(a, b, opt_target) {
+ var t = opt_target || a;
+
+ var a00 = a[0];
+ var a01 = a[1];
+ var a02 = a[2];
+ var a03 = a[3];
+ var a10 = a[4];
+ var a11 = a[5];
+ var a12 = a[6];
+ var a13 = a[7];
+ var a20 = a[8];
+ var a21 = a[9];
+ var a22 = a[10];
+ var a23 = a[11];
+ var a30 = a[12];
+ var a31 = a[13];
+ var a32 = a[14];
+ var a33 = a[15];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b02 = b[2];
+ var b03 = b[3];
+ var b10 = b[4];
+ var b11 = b[5];
+ var b12 = b[6];
+ var b13 = b[7];
+ var b20 = b[8];
+ var b21 = b[9];
+ var b22 = b[10];
+ var b23 = b[11];
+ var b30 = b[12];
+ var b31 = b[13];
+ var b32 = b[14];
+ var b33 = b[15];
+ t[0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;
+ t[1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;
+ t[2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;
+ t[3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;
+ t[4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;
+ t[5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;
+ t[6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;
+ t[7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;
+ t[8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;
+ t[9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;
+ t[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;
+ t[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;
+ t[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;
+ t[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;
+ t[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;
+ t[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;
+};
+
+
+/**
+ * Tests whether two matrices are either equal in the sense that they
+ * refer to the same memory, or equal in the sense that they have equal
+ * entries.
+ *
+ * @param {!Array.<!Array.<number>>} a A matrix.
+ * @param {!Array.<!Array.<number>>} b Another matrix.
+ * @return {boolean} Whether they are equal.
+ * @private
+ */
+o3d.Transform.matricesEqual_ = function(a, b) {
+ if (a==b) {
+ return true;
+ }
+ for (var i = 0; i < 16; ++i) {
+ if (a[i] != b[i]) {
+ return false;
+ }
+ }
+
+ return true;
+};
+
+
+/**
+ * Computes the transpose of the matrix a in place if no target is provided.
+ * Or if a target is provided, turns the target into the transpose of a.
+ *
+ * @param {!Array.<!Array.<number>>} m A matrix.
+ * @param {Array.<!Array.<number>>} opt_target
+ * The matrix to become the transpose of m.
+ * @private
+ */
+o3d.Transform.transpose_ = function(m, opt_target) {
+ var t = opt_target || m;
+
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
+ var m30 = m[12];
+ var m31 = m[13];
+ var m32 = m[14];
+ var m33 = m[15];
+ t[0] = m00;
+ t[1] = m10;
+ t[2] = m20;
+ t[3] = m30;
+
+ t[4] = m01;
+ t[5] = m11;
+ t[6] = m21;
+ t[7] = m31;
+
+ t[8] = m02;
+ t[9] = m12;
+ t[10] = m22;
+ t[11] = m32;
+
+ t[12] = m03;
+ t[13] = m13;
+ t[14] = m23;
+ t[15] = m33;
+};
+
+
+/**
+ * Computes the inverse of the matrix a in place if no target is provided.
+ * Or if a target is provided, turns the target into the transpose of a.
+ *
+ * @param {!Array.<!Array.<number>>} m A matrix.
+ * @param {Array.<!Array.<number>>} opt_target The matrix to become the
+ * inverse of a.
+ */
+o3d.Transform.inverse_ = function(m, opt_target) {
+ var t = opt_target || m;
+
+ var m00 = m[0];
+ var m01 = m[1];
+ var m02 = m[2];
+ var m03 = m[3];
+ var m10 = m[4];
+ var m11 = m[5];
+ var m12 = m[6];
+ var m13 = m[7];
+ var m20 = m[8];
+ var m21 = m[9];
+ var m22 = m[10];
+ var m23 = m[11];
+ var m30 = m[12];
+ var m31 = m[13];
+ var m32 = m[14];
+ var m33 = m[15];
+
+ var tmp_0 = m22 * m33;
+ var tmp_1 = m32 * m23;
+ var tmp_2 = m12 * m33;
+ var tmp_3 = m32 * m13;
+ var tmp_4 = m12 * m23;
+ var tmp_5 = m22 * m13;
+ var tmp_6 = m02 * m33;
+ var tmp_7 = m32 * m03;
+ var tmp_8 = m02 * m23;
+ var tmp_9 = m22 * m03;
+ var tmp_10 = m02 * m13;
+ var tmp_11 = m12 * m03;
+ var tmp_12 = m20 * m31;
+ var tmp_13 = m30 * m21;
+ var tmp_14 = m10 * m31;
+ var tmp_15 = m30 * m11;
+ var tmp_16 = m10 * m21;
+ var tmp_17 = m20 * m11;
+ var tmp_18 = m00 * m31;
+ var tmp_19 = m30 * m01;
+ var tmp_20 = m00 * m21;
+ var tmp_21 = m20 * m01;
+ var tmp_22 = m00 * m11;
+ var tmp_23 = m10 * m01;
+
+ var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) -
+ (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);
+ var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) -
+ (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);
+ var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) -
+ (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);
+ var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) -
+ (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);
+
+ var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
+
+ t[0] = d * t0;
+ t[1] = d * t1;
+ t[2] = d * t2;
+ t[3] = d * t3;
+ t[4] = d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) -
+ (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30));
+ t[5] = d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) -
+ (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30));
+ t[6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) -
+ (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30));
+ t[7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) -
+ (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20));
+ t[8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) -
+ (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33));
+ t[9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) -
+ (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33));
+ t[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) -
+ (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33));
+ t[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) -
+ (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23));
+ t[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) -
+ (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22));
+ t[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) -
+ (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02));
+ t[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) -
+ (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12));
+ t[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) -
+ (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02));
+};
+
+
+/**
+ * Takes a 4-by-4 matrix and a vector with 3 entries,
+ * interprets the vector as a point, transforms that point by the matrix, and
+ * returns the result as a vector with 3 entries.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector3} v The point.
+ * @return {!o3djs.math.Vector3} The transformed point.
+ * @private
+ */
+o3d.Transform.transformPoint_ = function(m, v) {
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+
+ var d = v0 * m[3] + v1 * m[7] + v2 * m[11] + m[15];
+ return o3d.Transform.makeVector3_(
+ (v0 * m[0] + v1 * m[4] + v2 * m[8] + m[12]) / d,
+ (v0 * m[1] + v1 * m[5] + v2 * m[9] + m[13]) / d,
+ (v0 * m[2] + v1 * m[6] + v2 * m[10] + m[14]) / d);
+};
+
+
+/**
+ * Takes a 4-by-4 matrix and a vector with 4 entries,
+ * interprets the vector as a point, transforms that point by the matrix, and
+ * returns the result as a vector with 4 entries.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector4} v The vector.
+ * @return {!o3djs.math.Vector4} The transformed vector.
+ * @private
+ */
+o3d.Transform.multiplyVector_ = function(m, v) {
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+ var v3 = v[3];
+
+ return o3d.Transform.makeVector4_(
+ (v0 * m[0] + v1 * m[4] + v2 * m[8] + v3 * m[12]),
+ (v0 * m[1] + v1 * m[5] + v2 * m[9] + v3 * m[13]),
+ (v0 * m[2] + v1 * m[6] + v2 * m[10] + v3 * m[14]),
+ (v0 * m[3] + v1 * m[7] + v2 * m[11] + v3 * m[15]));
+};
+
+
+/**
+ * Takes a 4-by-4 matrix and a vector with 3 entries,
+ * interprets the vector as a point, transforms that point by the matrix,
+ * returning the z-component of the result only.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector3} v The point.
+ * @return {number} The z coordinate of the transformed point.
+ * @private
+ */
+o3d.Transform.transformPointZOnly_ = function(m, v) {
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+
+ return (v0 * m[2] + v1 * m[6] + v2 * m[10] + m[14]) /
+ (v0 * m[3] + v1 * m[7] + v2 * m[11] + m[15]);
+};