diff options
author | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-13 20:00:18 +0000 |
---|---|---|
committer | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-13 20:00:18 +0000 |
commit | ee9372cbbc0bbeb8c8f06473409f3749eb443dd2 (patch) | |
tree | 755b8a5792facb882afbf3c13d733613c09c9742 /o3d/samples/o3d-webgl | |
parent | a0835ac1850ccabc846ebfcee537b0b0592b8519 (diff) | |
download | chromium_src-ee9372cbbc0bbeb8c8f06473409f3749eb443dd2.zip chromium_src-ee9372cbbc0bbeb8c8f06473409f3749eb443dd2.tar.gz chromium_src-ee9372cbbc0bbeb8c8f06473409f3749eb443dd2.tar.bz2 |
Replaces matrix math functions in o3d-webgl with a new library that uses 1-dimensional arrays to represent matrices instead of 2-dimensional arrays.
This is a duplicate of Daniel Horn's change http://codereview.chromium.org/3072008 for committal.
Review URL: http://codereview.chromium.org/3273004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples/o3d-webgl')
-rw-r--r-- | o3d/samples/o3d-webgl/base.js | 2 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/bounding_box.js | 4 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/draw_context.js | 6 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/draw_list.js | 4 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/param.js | 104 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/param_operation.js | 57 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/shape.js | 8 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/skin.js | 77 | ||||
-rw-r--r-- | o3d/samples/o3d-webgl/transform.js | 1309 |
9 files changed, 921 insertions, 650 deletions
diff --git a/o3d/samples/o3d-webgl/base.js b/o3d/samples/o3d-webgl/base.js index b484e484..3572a25 100644 --- a/o3d/samples/o3d-webgl/base.js +++ b/o3d/samples/o3d-webgl/base.js @@ -246,6 +246,7 @@ o3d.include('named_object_base'); o3d.include('named_object'); o3d.include('param_object'); o3d.include('param_array'); +o3d.include('transform'); o3d.include('param'); o3d.include('event'); o3d.include('raw_data'); @@ -266,7 +267,6 @@ o3d.include('state'); o3d.include('draw_context'); o3d.include('ray_intersection_info'); o3d.include('sampler'); -o3d.include('transform'); o3d.include('pack'); o3d.include('bounding_box'); o3d.include('draw_element'); diff --git a/o3d/samples/o3d-webgl/bounding_box.js b/o3d/samples/o3d-webgl/bounding_box.js index a3da9aa..8a88d78 100644 --- a/o3d/samples/o3d-webgl/bounding_box.js +++ b/o3d/samples/o3d-webgl/bounding_box.js @@ -129,7 +129,7 @@ o3d.BoundingBox.prototype.mul = var new_corners = []; for (var i = 0; i < corners.length; ++i) { - new_corners.push(o3d.Transform.transformPoint(matrix, corners[i])); + new_corners.push(o3d.Transform.transformPoint_(matrix, corners[i])); } return o3d.BoundingBox.fitBoxToPoints_(new_corners); @@ -283,7 +283,7 @@ o3d.BoundingBox.prototype.inFrustum = var bb_test = 0x3f; for (var i = 0; i < corners.length; ++i) { var corner = corners[i]; - var p = o3d.Transform.transformPoint(matrix, corner); + var p = o3d.Transform.transformPoint_(matrix, corner); bb_test &= (((p[0] > 1.0) << 0) | ((p[0] < -1.0) << 1) | ((p[1] > 1.0) << 2) | diff --git a/o3d/samples/o3d-webgl/draw_context.js b/o3d/samples/o3d-webgl/draw_context.js index 0b4967c..dde73e8 100644 --- a/o3d/samples/o3d-webgl/draw_context.js +++ b/o3d/samples/o3d-webgl/draw_context.js @@ -49,8 +49,7 @@ o3d.DrawContext = function(opt_view, opt_projection) { * take vertices from world space to view space. * @type {o3d.Matrix4} */ - this.view = opt_view || - [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.view = opt_view || o3d.Transform.makeIdentityMatrix4_(); /** * The projection matrix represents the projection transformation, @@ -58,8 +57,7 @@ o3d.DrawContext = function(opt_view, opt_projection) { * matrix is usually an orthographic or perspective transformation. * @type {o3d.Matrix4} */ - this.projection = opt_projection || - [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.projection = opt_projection || o3d.Transform.makeIdentityMatrix4_(); }; o3d.inherit('DrawContext', 'ParamObject'); diff --git a/o3d/samples/o3d-webgl/draw_list.js b/o3d/samples/o3d-webgl/draw_list.js index 68f635d..33cc7fd 100644 --- a/o3d/samples/o3d-webgl/draw_list.js +++ b/o3d/samples/o3d-webgl/draw_list.js @@ -83,10 +83,10 @@ o3d.DrawList.comparePriority_ = function(drawElementInfoA, drawElementInfoB) { * @param {!o3d.DrawElement} drawElementInfoB */ o3d.DrawList.compareZ_ = function(drawElementInfoA, drawElementInfoB) { - return o3d.Transform.transformPointZOnly( + return o3d.Transform.transformPointZOnly_( drawElementInfoB.worldViewProjection, drawElementInfoB.drawElement.owner.zSortPoint) - - o3d.Transform.transformPointZOnly( + o3d.Transform.transformPointZOnly_( drawElementInfoA.worldViewProjection, drawElementInfoA.drawElement.owner.zSortPoint); }; diff --git a/o3d/samples/o3d-webgl/param.js b/o3d/samples/o3d-webgl/param.js index 9ea8bd0..66fca29 100644 --- a/o3d/samples/o3d-webgl/param.js +++ b/o3d/samples/o3d-webgl/param.js @@ -39,50 +39,50 @@ * @constructor */ o3d.Param = function(param_type_name) { - o3d.Param.prototype.output_connections = []; + /** + * If true, this param will make sure its input param is up to date when + * using it as a source. Default = true. + * + * This is for helping with Param cycles. + * + * If paramA gets its value from paramB and paramB gets its value from + * paramA: + * If you go paramA.value, paramB will evaluate then copy to paramA. + * If you go paramB.value, paramA will evaluate then copy to paramB. + * If you set paramB.updateInput = false, then: + * If you go paramA.value, paramB will evaluate then copy to paramA. + * If you go paramB.value, paramB just copy paramA. paramA will NOT evaluate + * when paramB asks for its value. + */ + this.updateInput = true; + + /** + * @type {o3d.Param} + */ + this.inputConnection = null; + + /** + * @type {Array.<!o3d.Param>} + */ this.outputConnections = []; + + /** + * The ParamObject that has this param as a param. + * @type {o3d.ParamObject} + * @private + */ + o3d.Param.prototype.owner_ = null; + + /** + * Private variable to store the value of the param. + * @type {*} + * @private + */ + this.value_ = null; } o3d.inherit('Param', 'NamedObject'); -/** - * If true, this param will make sure its input param is up to date when - * using it as a source. Default = true. - * - * This is for helping with Param cycles. - * - * If paramA gets its value from paramB and paramB gets its value from - * paramA: - * If you go paramA.value, paramB will evaluate then copy to paramA. - * If you go paramB.value, paramA will evaluate then copy to paramB. - * If you set paramB.updateInput = false, then: - * If you go paramA.value, paramB will evaluate then copy to paramA. - * If you go paramB.value, paramB just copy paramA. paramA will NOT evaluate - * when paramB asks for its value. - */ -o3d.Param.prototype.update_input = true; - -/** - * @type {o3d.Param} - */ -o3d.Param.prototype.inputConnection = null; - -/** - * @type {Array.<!o3d.Param>} - */ -o3d.Param.prototype.outputConnections = []; - - -/** - * @type {o3d.ParamObject} - */ -o3d.Param.prototype.owner_ = null; - -/** - * @type {Object} The value of the parameter. - */ -o3d.Param.prototype.value_ = null; - o3d.Param.prototype.__defineSetter__('value', function(v) { if (this.inputConnection) { @@ -267,7 +267,7 @@ o3d.inherit('ParamFloat', 'Param'); */ o3d.ParamFloat2 = function() { o3d.Param.call(this); - this.value = [0.0, 0.0]; + this.value = o3d.Transform.makeVector2_(0.0, 0.0); }; o3d.inherit('ParamFloat2', 'Param'); @@ -277,7 +277,7 @@ o3d.inherit('ParamFloat2', 'Param'); */ o3d.ParamFloat3 = function() { o3d.Param.call(this); - this.value = [0.0, 0.0, 0.0]; + this.value = o3d.Transform.makeVector3_(0.0, 0.0, 0.0); }; o3d.inherit('ParamFloat3', 'Param'); @@ -287,7 +287,7 @@ o3d.inherit('ParamFloat3', 'Param'); */ o3d.ParamFloat4 = function() { o3d.Param.call(this); - this.value = [0.0, 0.0, 0.0, 0.0]; + this.value = o3d.Transform.makeVector4_(0.0, 0.0, 0.0, 0.0); }; o3d.inherit('ParamFloat4', 'Param'); @@ -327,17 +327,18 @@ o3d.inherit('ParamMaterial', 'Param'); */ o3d.ParamMatrix4 = function() { o3d.Param.call(this); - this.value = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.value = o3d.Transform.makeMatrix4_(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); }; o3d.inherit('ParamMatrix4', 'Param'); - /** * @constructor */ o3d.ParamParamArray = function() { o3d.Param.call(this); - this.value = null; }; o3d.inherit('ParamParamArray', 'Param'); @@ -483,8 +484,10 @@ o3d.CompositionParamMatrix4 = function() { o3d.ParamMatrix4.call(this); this.matrix_names_ = []; }; + o3d.inherit('CompositionParamMatrix4', 'ParamMatrix4'); + /** * The array of names of matrix params for the matrices that are to be * composed to get the value. @@ -508,15 +511,15 @@ o3d.CompositionParamMatrix4.prototype.transpose_ = false; o3d.CompositionParamMatrix4.prototype.__defineGetter__('value', // TODO(petersont): Cache the result if it hasn't changed. function() { - var product = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + var product = o3d.Transform.makeIdentityMatrix4_(); for (var i = 0; i < this.matrix_names_.length; ++i) { - o3d.Transform.compose(product, o3d.Param.SAS[this.matrix_names_[i]]); + o3d.Transform.compose_(product, o3d.Param.SAS[this.matrix_names_[i]]); } if (this.inverse_) { - o3d.Transform.inverse(product); + o3d.Transform.inverse_(product); } if (this.transpose_) { - o3d.Transform.transpose(product); + o3d.Transform.transpose_(product); } return product; } @@ -786,7 +789,6 @@ o3d.WorldViewProjectionTransposeParamMatrix4 = function() { o3d.inherit('WorldViewProjectionTransposeParamMatrix4', 'CompositionParamMatrix4'); - /** * @constructor */ @@ -862,7 +864,7 @@ o3d.ParamFloat4.prototype.applyToLocation = function(gl, location) { o3d.ParamMatrix4.prototype.applyToLocation = function(gl, location) { gl.uniformMatrix4fv(location, false, - o3d.Transform.flattenMatrix4(this.value)); + this.value); }; /** diff --git a/o3d/samples/o3d-webgl/param_operation.js b/o3d/samples/o3d-webgl/param_operation.js index 69ecea7..172f537 100644 --- a/o3d/samples/o3d-webgl/param_operation.js +++ b/o3d/samples/o3d-webgl/param_operation.js @@ -147,7 +147,7 @@ o3d.inherit('ParamOp2FloatsToFloat2', 'ParamObject'); /** * Called by o3d.Param*Output whenever its value gets read. - * @return {!Array.<number>} 2-element array equal to [input0,input1] + * @return {!Array.<number>} 2-element array equal to [input0, input1] */ o3d.ParamOp2FloatsToFloat2.prototype.updateOutputs = function() { this.last_output_value_[0] = this.getParam("input0").value; @@ -226,8 +226,7 @@ o3d.ParamOp4FloatsToFloat4.prototype.updateOutputs = function() { */ o3d.ParamOp16FloatsToMatrix4 = function() { o3d.ParamObject.call(this); - this.last_output_value_ = - [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.last_output_value_ = o3d.Transform.makeIdentityMatrix4_(); }; o3d.inherit('ParamOp16FloatsToMatrix4', 'ParamObject'); @@ -242,12 +241,12 @@ o3d.inherit('ParamOp16FloatsToMatrix4', 'ParamObject'); /** * Called by o3d.Param*Output whenever its value gets read. - * @return {!Array.<!Array.<number>>} 4x4 array equal to - * [[i0,i1,i2,i3],[i4,i5,i6,i7],[i8,i9,i10,i11],[i12,i13,i14,i15]] + * @return {!Array<!Array<number>>} 4x4 array equal to + * [i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15] */ o3d.ParamOp16FloatsToMatrix4.prototype.updateOutputs = function() { for (var i = 0; i < 16; i++) { - this.last_output_value_[Math.floor(i/4)][i%4] = + this.last_output_value_[i] = this.getParam("input"+i).value; } return this.last_output_value_; @@ -282,8 +281,7 @@ o3d.TRSToMatrix4 = function() { this.scaleY = 1; this.scaleZ = 1; - this.last_output_value_ = - [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.last_output_value_ = o3d.Transform.makeIdentityMatrix4_(); }; o3d.inherit('TRSToMatrix4', 'ParamObject'); @@ -320,22 +318,22 @@ o3d.TRSToMatrix4.prototype.updateOutputs = function () { var cosZSinY = cosZ * sinY; var sinZSinY = sinZ * sinY; - ret[0].splice(0, 4, cosZ * cosY * sX, - sinZ * cosY * sX, - -sinY * sX, - 0); - ret[1].splice(0, 4, (cosZSinY * sinX - sinZ * cosX) * sY, - (sinZSinY * sinX + cosZ * cosX) * sY, - cosY * sinX * sY, - 0); - ret[2].splice(0, 4, (cosZSinY * cosX + sinZ * sinX) * sZ, - (sinZSinY * cosX - cosZ * sinX) * sZ, - cosY * cosX * sZ, - 0); - ret[3].splice(0, 4, this.translateX, - this.translateY, - this.translateZ, - 1); + ret[0] = cosZ * cosY * sX; + ret[1] = sinZ * cosY * sX; + ret[2] = -sinY * sX; + ret[3] = 0; + ret[4] = (cosZSinY * sinX - sinZ * cosX) * sY; + ret[5] = (sinZSinY * sinX + cosZ * cosX) * sY; + ret[6] = cosY * sinX * sY, + ret[7] = 0; + ret[8] = (cosZSinY * cosX + sinZ * sinX) * sZ; + ret[9] = (sinZSinY * cosX - cosZ * sinX) * sZ; + ret[10] = cosY * cosX * sZ; + ret[11] = 0; + ret[12] = this.translateX; + ret[13] = this.translateY; + ret[14] = this.translateZ; + ret[15] = 1; return ret; }; @@ -347,8 +345,7 @@ o3d.TRSToMatrix4.prototype.updateOutputs = function () { */ o3d.Matrix4Composition = function() { o3d.ParamObject.call(this); - this.last_output_value_ = - [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.last_output_value_ = o3d.Transform.makeIdentityMatrix4_(); }; o3d.inherit('Matrix4Composition', 'ParamObject'); @@ -363,13 +360,13 @@ o3d.ParamObject.setUpO3DParam_( /** * Called by o3d.Param*Output whenever its value gets read. - * @return {!Array.<!Array.<number>>} 4x4 array equal to - * inputMatrix * localMatrix + * @return {!Array<!Array<number>>} 4x4 array equal to + * inputMatrix * localMatrix. */ o3d.Matrix4Composition.prototype.updateOutputs = function() { var input = this.getParam("inputMatrix").value; var local = this.getParam("localMatrix").value; - o3d.Transform.compose(input, local, this.last_output_value_); + o3d.Transform.compose_(input, local, this.last_output_value_); return this.last_output_value_; }; @@ -408,7 +405,7 @@ o3d.Matrix4AxisRotation.prototype.updateOutputs = function() { var input = this.getParam("inputMatrix").value; var axis = this.getParam("axis").value; var angle = this.getParam("angle").value; - o3d.Transform.axisRotateMatrix(input, axis, angle, this.last_output_value_); + o3d.Transform.axisRotateMatrix_(input, axis, angle, this.last_output_value_); return this.last_output_value_; }; diff --git a/o3d/samples/o3d-webgl/shape.js b/o3d/samples/o3d-webgl/shape.js index a0ad16e..8823f83 100644 --- a/o3d/samples/o3d-webgl/shape.js +++ b/o3d/samples/o3d-webgl/shape.js @@ -155,10 +155,10 @@ o3d.Shape.prototype.writeToDrawLists = var view = context.view; var projection = context.projection; - var worldViewProjection = [[], [], [], []]; - var viewProjection = [[], [], [], []]; - o3d.Transform.compose(projection, view, viewProjection); - o3d.Transform.compose(viewProjection, world, worldViewProjection); + var worldViewProjection = o3d.Transform.makeIdentityMatrix4_(); + var viewProjection = o3d.Transform.makeIdentityMatrix4_(); + o3d.Transform.compose_(projection, view, viewProjection); + o3d.Transform.compose_(viewProjection, world, worldViewProjection); if (element.cull && element.boundingBox) { if (!element.boundingBox.inFrustum(worldViewProjection)) { diff --git a/o3d/samples/o3d-webgl/skin.js b/o3d/samples/o3d-webgl/skin.js index cbec71f..1e9455c 100644 --- a/o3d/samples/o3d-webgl/skin.js +++ b/o3d/samples/o3d-webgl/skin.js @@ -307,14 +307,14 @@ o3d.SkinEval = function() { * The base matrix to subtract from the matrices before skinning. * @type {!Array<!Array<number>>} */ - this.base = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.base = o3d.Transform.makeIdentityMatrix4_(); /** * Temporary storage for matrix ops. * @type {!Array<!Array<number>>} * @private */ - this.temp_matrix_ = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + this.temp_matrix_ = o3d.Transform.makeIdentityMatrix4_(); /** * Array of matrices representing each bone. @@ -325,7 +325,7 @@ o3d.SkinEval = function() { /** * Float32 array containing all matrices in 3x4 format. - * @type {Float32Array} + * @type {o3d.ParamArray} * @private */ this.bone_array_ = null; @@ -463,30 +463,9 @@ o3d.SkinEval.prototype.streamWasBound_ = function( * @private */ o3d.SkinEval.prototype.multiplyAdd_ = function(input, weight, output) { - var a0 = input[0]; - var a1 = input[1]; - var a2 = input[2]; - var a3 = input[3]; - var b0 = output[0]; - var b1 = output[1]; - var b2 = output[2]; - var b3 = output[3]; - b0[0] += a0[0] * weight; - b0[1] += a0[1] * weight; - b0[2] += a0[2] * weight; - b0[3] += a0[3] * weight; - b1[0] += a1[0] * weight; - b1[1] += a1[1] * weight; - b1[2] += a1[2] * weight; - b1[3] += a1[3] * weight; - b2[0] += a2[0] * weight; - b2[1] += a2[1] * weight; - b2[2] += a2[2] * weight; - b2[3] += a2[3] * weight; - b3[0] += a3[0] * weight; - b3[1] += a3[1] * weight; - b3[2] += a3[2] * weight; - b3[3] += a3[3] * weight; + for (var i = 0; i < 16; ++i) { + output[i] += input[i] * weight; + } }; /** @@ -637,11 +616,11 @@ o3d.SkinEval.prototype.doSkinning_ = function() { // combine the matrixes for this vertex. var accumulated_matrix = - [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]; + o3d.Transform.makeNullMatrix4_(); this.multiplyAdd_(this.bones_[this_matrix_index], this_weight, accumulated_matrix); var num_influences = influences.length; - for (jj = 2; jj < num_influences; jj+=2) { + for (jj = 2; jj < num_influences; jj += 2) { var influence_matrix_index = influences[jj]; var influence_weight = influences[jj + 1]; this.multiplyAdd_(this.bones_[influence_matrix_index], @@ -707,7 +686,7 @@ o3d.SkinEval.prototype.updateBones_ = function() { // Get the inverse of our base to remove from the bones. var inverse_base = this.temp_matrix_; - o3d.Transform.inverse(this.base, inverse_base); + o3d.Transform.inverse_(this.base, inverse_base); for (var ii = 0; ii < param_array.length; ++ii) { var param = param_array.getParam(ii); // ParamMatrix4 @@ -718,10 +697,10 @@ o3d.SkinEval.prototype.updateBones_ = function() { + " is not a ParamMatrix4"); return; } - this.bones_[ii] = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; - o3d.Transform.compose(param.value, inverse_bind_pose_array[ii], + this.bones_[ii] = o3d.Transform.makeIdentityMatrix4_(); + o3d.Transform.compose_(param.value, inverse_bind_pose_array[ii], this.bones_[ii]); - o3d.Transform.compose(inverse_base, this.bones_[ii], this.bones_[ii]); + o3d.Transform.compose_(inverse_base, this.bones_[ii], this.bones_[ii]); } }; @@ -777,20 +756,20 @@ o3d.SkinEval.prototype.updateOutputs = function(param) { for (ii = 0; ii < this.bones_.length; ++ii) { var bone = this.bones_[ii]; row = boneArray.getParam(ii*3); - row.value[0] = bone[0][0]; - row.value[1] = bone[1][0]; - row.value[2] = bone[2][0]; - row.value[3] = bone[3][0]; + row.value[0] = bone[0]; + row.value[1] = bone[4]; + row.value[2] = bone[8]; + row.value[3] = bone[12]; row = boneArray.getParam(ii*3 + 1); - row.value[0] = bone[0][1]; - row.value[1] = bone[1][1]; - row.value[2] = bone[2][1]; - row.value[3] = bone[3][1]; + row.value[0] = bone[1]; + row.value[1] = bone[5]; + row.value[2] = bone[9]; + row.value[3] = bone[13]; row = boneArray.getParam(ii*3 + 2); - row.value[0] = bone[0][2]; - row.value[1] = bone[1][2]; - row.value[2] = bone[2][2]; - row.value[3] = bone[3][2]; + row.value[0] = bone[2]; + row.value[1] = bone[6]; + row.value[2] = bone[10]; + row.value[3] = bone[14]; } } return boneArray; @@ -884,7 +863,7 @@ o3d.SkinEval.StreamInfo.prototype.uninit = function() { o3d.SkinEval.StreamInfo.prototype.computeFloat3AsVector3 = function(matrix) { var ii = this.index_; var vec = [this.values_[ii], this.values_[ii + 1], this.values_[ii + 2], 0]; - this.result_ = o3d.Transform.multiplyVector(matrix, vec); + this.result_ = o3d.Transform.multiplyVector_(matrix, vec); this.index_ = ii + this.stride_; }; @@ -898,10 +877,10 @@ o3d.SkinEval.StreamInfo.prototype.computeFloat3AsVector3 = function(matrix) { o3d.SkinEval.StreamInfo.prototype.computeFloat3AsPoint3 = function(matrix) { var ii = this.index_; // TODO: The C++ code just dropped element 3 of the return Vector4, while - // o3d.Transform.transformPoint divides by the last value to make it 1. + // o3d.Transform.transformPoint_ divides by the last value to make it 1. // Which is the right one to use? var point = [this.values_[ii], this.values_[ii + 1], this.values_[ii + 2], 1]; - this.result_ = o3d.Transform.multiplyVector(matrix, point); + this.result_ = o3d.Transform.multiplyVector_(matrix, point); this.index_ = ii + this.stride_; }; @@ -916,7 +895,7 @@ o3d.SkinEval.StreamInfo.prototype.computeFloat4AsVector4 = function(matrix) { var ii = this.index_; var vec = [this.values_[ii], this.values_[ii + 1], this.values_[ii + 2], this.values_[ii + 3]]; - this.result_ = o3d.Transform.multiplyVector(matrix, vec); + this.result_ = o3d.Transform.multiplyVector_(matrix, vec); this.index_ = ii + this.stride_; }; 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]); +}; |