summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-13 20:00:18 +0000
committerpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-13 20:00:18 +0000
commitee9372cbbc0bbeb8c8f06473409f3749eb443dd2 (patch)
tree755b8a5792facb882afbf3c13d733613c09c9742 /o3d
parenta0835ac1850ccabc846ebfcee537b0b0592b8519 (diff)
downloadchromium_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')
-rw-r--r--o3d/samples/o3d-webgl-samples/2d.html8
-rw-r--r--o3d/samples/o3d-webgl-samples/box2d-3d/demos/manager.js24
-rw-r--r--o3d/samples/o3d-webgl-samples/hellocube.html4
-rw-r--r--o3d/samples/o3d-webgl-samples/hud-2d-overlay.html16
-rw-r--r--o3d/samples/o3d-webgl-samples/pool.html45
-rw-r--r--o3d/samples/o3d-webgl-samples/shadow-map.html17
-rw-r--r--o3d/samples/o3d-webgl-samples/skinning.html9
-rw-r--r--o3d/samples/o3d-webgl/base.js2
-rw-r--r--o3d/samples/o3d-webgl/bounding_box.js4
-rw-r--r--o3d/samples/o3d-webgl/draw_context.js6
-rw-r--r--o3d/samples/o3d-webgl/draw_list.js4
-rw-r--r--o3d/samples/o3d-webgl/param.js104
-rw-r--r--o3d/samples/o3d-webgl/param_operation.js57
-rw-r--r--o3d/samples/o3d-webgl/shape.js8
-rw-r--r--o3d/samples/o3d-webgl/skin.js77
-rw-r--r--o3d/samples/o3d-webgl/transform.js1309
-rw-r--r--o3d/samples/o3djs/canvas.js16
-rw-r--r--o3d/samples/o3djs/debug.js30
-rw-r--r--o3d/samples/o3djs/fps.js8
-rw-r--r--o3d/samples/o3djs/manipulators.js6
-rw-r--r--o3d/samples/o3djs/math.js3100
-rw-r--r--o3d/samples/o3djs/plugin_math.js2621
-rw-r--r--o3d/samples/o3djs/primitives.js11
-rw-r--r--o3d/samples/o3djs/quaternions.js30
-rw-r--r--o3d/samples/o3djs/serialization.js50
25 files changed, 5513 insertions, 2053 deletions
diff --git a/o3d/samples/o3d-webgl-samples/2d.html b/o3d/samples/o3d-webgl-samples/2d.html
index 416c76c..2e7bd23 100644
--- a/o3d/samples/o3d-webgl-samples/2d.html
+++ b/o3d/samples/o3d-webgl-samples/2d.html
@@ -296,10 +296,10 @@ function initStep2(clientElements) {
1,
1,
1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0,-1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0,-1, 0, 0,
+ 0, 0, 0, 1));
// Load all the textures.
var loader = o3djs.loader.createLoader(initStep3);
diff --git a/o3d/samples/o3d-webgl-samples/box2d-3d/demos/manager.js b/o3d/samples/o3d-webgl-samples/box2d-3d/demos/manager.js
index b780460..c8bb604 100644
--- a/o3d/samples/o3d-webgl-samples/box2d-3d/demos/manager.js
+++ b/o3d/samples/o3d-webgl-samples/box2d-3d/demos/manager.js
@@ -24,10 +24,10 @@ O3DManager.prototype.createCylinder = function(radius) {
shape = o3djs.primitives.createCylinder(g.pack,
g.materials[0],
radius, 40, 20, 1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0, -1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0, 0,
+ 0, 0, 0, 1));
this.shapes[id] = shape;
}
return new O3DShape({shape: shape});
@@ -53,16 +53,16 @@ O3DManager.prototype.createCompoundCylinder = function(radius1,
if (!shape) {
shape = o3djs.primitives.createCylinder(
g.pack, g.materials[0], radius1, 40, 20, 1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0, -1, 0, 0],
- [offset1, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0, 0,
+ offset1, 0, 0, 1));
shape2 = o3djs.primitives.createCylinder(
g.pack, g.materials[0], radius2, 40, 20, 1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0, -1, 0, 0],
- [offset2, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0, 0,
+ offset2, 0, 0, 1));
shape2.elements[0].owner = shape;
g.pack.removeObject(shape2);
this.shapes[id] = shape;
diff --git a/o3d/samples/o3d-webgl-samples/hellocube.html b/o3d/samples/o3d-webgl-samples/hellocube.html
index 148183b..8655b62 100644
--- a/o3d/samples/o3d-webgl-samples/hellocube.html
+++ b/o3d/samples/o3d-webgl-samples/hellocube.html
@@ -207,8 +207,8 @@ function initStep2(clientElements) {
// Set up our view transformation to look towards the world origin where the
// cube is located.
viewInfo.drawContext.view = g_math.matrix4.lookAt([0, 1, 5], // eye
- [0, 0, 0], // target
- [0, 1, 0]); // up
+ [0, 0, 0], // target
+ [0, 1, 0]); // up
// Create an Effect object and initialize it using the shaders from the
// text area.
diff --git a/o3d/samples/o3d-webgl-samples/hud-2d-overlay.html b/o3d/samples/o3d-webgl-samples/hud-2d-overlay.html
index 0464b30..9d7b967 100644
--- a/o3d/samples/o3d-webgl-samples/hud-2d-overlay.html
+++ b/o3d/samples/o3d-webgl-samples/hud-2d-overlay.html
@@ -216,10 +216,10 @@ function initStep2(clientElements) {
1,
1,
1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0,-1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0,-1, 0, 0,
+ 0, 0, 0, 1));
// Create a ground plane
g_groundShape = o3djs.primitives.createPlane(
@@ -235,10 +235,10 @@ function initStep2(clientElements) {
g_pack,
g_materials[1],
1,
- [[0.9, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 0.9, 0],
- [0, 0.5, 0, 1]]);
+ o3djs.math.makeMatrix4(0.9, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 0.9, 0,
+ 0, 0.5, 0, 1));
// Load all the textures.
var loader = o3djs.loader.createLoader(initStep3);
diff --git a/o3d/samples/o3d-webgl-samples/pool.html b/o3d/samples/o3d-webgl-samples/pool.html
index 14eca54..f9e983f0 100644
--- a/o3d/samples/o3d-webgl-samples/pool.html
+++ b/o3d/samples/o3d-webgl-samples/pool.html
@@ -396,7 +396,7 @@ pool.Physics = function() {
[0, w / 2 - r, 0]];
var angles = [0, Math.PI/2, Math.PI, Math.PI, 3 * Math.PI / 2, 0];
- var translations = this.math.mulMatrixMatrix(
+ var translations = this.math.generalizedMulMatrixMatrix(
[[-1, -1, 0], [0, -2, 0], [1, -1, 0], [1, 1, 0], [0, 2, 0], [-1, 1, 0]],
[[w / 2, 0, 0], [0, w / 2, 0], [0, 0, 1]]);
@@ -624,9 +624,10 @@ pool.Physics = function() {
var b = r[1];
var c = r[2];
- return [[1 / m + (b * b + c * c) / I, (-a * b) / I, (-a * c) / I],
- [(-a * b) / I, 1 / m + (a * a + c * c) / I, (-b * c) / I],
- [(-a * c) / I, (-b * c) / I, 1 / m + (a * a + b * b) / I]];
+ return o3djs.math
+ .makeMatrix3(1 / m + (b * b + c * c) / I, (-a * b) / I, (-a * c) / I,
+ (-a * b) / I, 1 / m + (a * a + c * c) / I, (-b * c) / I,
+ (-a * c) / I, (-b * c) / I, 1 / m + (a * a + b * b) / I);
};
this.applyImpulse = function(i, impulse, r) {
@@ -1269,11 +1270,11 @@ function initTable() {
Math.PI,
15)).concat([[-scaledWoodBreadth - 1, 0]]);
- var m = g_math.mulScalarMatrix(g_tableWidth / 2, g_math.identity(2));
- felt_polygon_A = g_math.mulMatrixMatrix(felt_polygon_A, m);
- felt_polygon_B = g_math.mulMatrixMatrix(felt_polygon_B, m);
- felt_polygon_C = g_math.mulMatrixMatrix(felt_polygon_C, m);
- wood_polygon = g_math.mulMatrixMatrix(wood_polygon, m);
+ var m = [[g_tableWidth / 2, 0],[0,g_tableWidth / 2]];
+ felt_polygon_A = g_math.generalizedMulMatrixMatrix(felt_polygon_A, m);
+ felt_polygon_B = g_math.generalizedMulMatrixMatrix(felt_polygon_B, m);
+ felt_polygon_C = g_math.generalizedMulMatrixMatrix(felt_polygon_C, m);
+ wood_polygon = g_math.generalizedMulMatrixMatrix(wood_polygon, m);
var felt_polygons = [];
var wood_polygons = [];
@@ -1316,11 +1317,13 @@ function initTable() {
var cushionSwoop = g_pocketRadius;
var angles = [0, Math.PI/2, Math.PI, Math.PI, 3 * Math.PI / 2, 0];
- var translations = g_math.mulMatrixMatrix(
+ var translations = g_math.generalizedMulMatrixMatrix(
[[-1, -1, 0], [0, -2, 0], [1, -1, 0], [1, 1, 0], [0, 2, 0], [-1, 1, 0]],
[[g_tableWidth / 2, 0, 0], [0, g_tableWidth / 2, 0], [0, 0, 1]]);
- var shortenings = g_math.mulScalarMatrix(g_pocketRadius,
- [[1, root2], [root2, root2], [root2, 1]])
+ var shortenings =
+ [[g_pocketRadius, g_pocketRadius*root2],
+ [g_pocketRadius*root2, g_pocketRadius*root2],
+ [g_pocketRadius*root2, g_pocketRadius]];
var billiardThickness = 0.1;
var billiardBreadth = 1;
@@ -1415,17 +1418,19 @@ function initHud() {
var plane = o3djs.primitives.createPlane(
g_pack, g_solidMaterial, 1, 1, 1, 1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0,-1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(
+ 1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0,-1, 0, 0,
+ 0, 0, 0, 1));
var backPlane = o3djs.primitives.createPlane(
g_pack, g_solidMaterial, 1, 1, 1, 1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0,-1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(
+ 1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0,-1, 0, 0,
+ 0, 0, 0, 1));
barT2.addShape(plane);
//backT2.addShape(backPlane);
diff --git a/o3d/samples/o3d-webgl-samples/shadow-map.html b/o3d/samples/o3d-webgl-samples/shadow-map.html
index 97defe2..77fca20 100644
--- a/o3d/samples/o3d-webgl-samples/shadow-map.html
+++ b/o3d/samples/o3d-webgl-samples/shadow-map.html
@@ -301,11 +301,6 @@ function updateLightMatrix() {
4, // Near plane.
20); // Far plane.
- var adjustedProjection =
- [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 2, 0], [0, 0, -1, 1]];
- o3d.Transform.compose(
- adjustedProjection, lightProjection, adjustedProjection);
-
// Make the light point toward the origin
var lightView = g_math.matrix4.lookAt(
g_lightWorldPos, // light
@@ -384,17 +379,9 @@ function createShapes() {
function createLightShape() {
var inverseMatrix = g_math.matrix4.inverse(g_lightViewProjection);
- // Scale and translate a cube of side length 2 to get a box
- // that extends from [-1, -1, 0] to [1, 1, 1].
var shape = o3djs.lineprimitives.createLineCube(
- g_pack,
- o3djs.material.createConstantMaterial(g_pack,
- g_colorViewInfo,
- [1, 0, 0, 1]),
- 2,
- g_math.matrix4.compose(
- g_math.matrix4.translation([0, 0, 0.5]),
- g_math.matrix4.scaling([1, 1, 0.5])));
+ g_pack, o3djs.material.createConstantMaterial(g_pack, g_colorViewInfo,
+ [1, 0, 0, 1]), 2);
g_lightFrustumTransform = g_pack.createObject('Transform');
g_lightFrustumTransform.localMatrix = inverseMatrix;
diff --git a/o3d/samples/o3d-webgl-samples/skinning.html b/o3d/samples/o3d-webgl-samples/skinning.html
index f8450be..0b4e91e 100644
--- a/o3d/samples/o3d-webgl-samples/skinning.html
+++ b/o3d/samples/o3d-webgl-samples/skinning.html
@@ -122,10 +122,11 @@ function initStep2(clientElements) {
// Create a cylinder.
var vertexInfo = o3djs.primitives.createCylinderVertices(
40, 200, 120, 200,
- [[1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0],
- [0, 100, 0, 1]]);
+ o3djs.math.makeMatrix4(
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 100, 0, 1));
var shape = vertexInfo.createShape(g_pack, material);
// Create an ParamArray to hold matrices for skinning.
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]);
+};
diff --git a/o3d/samples/o3djs/canvas.js b/o3d/samples/o3djs/canvas.js
index 2d83718..fce83b4 100644
--- a/o3d/samples/o3djs/canvas.js
+++ b/o3d/samples/o3djs/canvas.js
@@ -241,10 +241,10 @@ o3djs.canvas.CanvasInfo = function(pack, root, viewInfo) {
1,
1,
1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0, -1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0 ,0,
+ 0, 0, 0, 1));
/**
* A shape for opaque quads.
@@ -257,10 +257,10 @@ o3djs.canvas.CanvasInfo = function(pack, root, viewInfo) {
1,
1,
1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0, -1, 0, 0],
- [0, 0, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0 ,0,
+ 0, 0, 0, 1));
};
/**
* The CanvasQuad object encapsulates a Transform, a rectangle Shape,
diff --git a/o3d/samples/o3djs/debug.js b/o3d/samples/o3djs/debug.js
index b1730ab..f646d90 100644
--- a/o3d/samples/o3djs/debug.js
+++ b/o3d/samples/o3djs/debug.js
@@ -258,10 +258,10 @@ o3djs.debug.DebugLine.prototype.update_ = function() {
perp2 = math.cross(perp1, direction);
}
this.transform_.localMatrix =
- [perp2.concat(0),
- direction.concat(0),
- perp1.concat(0),
- this.start_.concat(1)];
+ o3djs.math.makeMatrix4(perp2[0], perp2[1], perp2[2], 0,
+ direction[0], direction[1], direction[2], 0,
+ perp1[0], perp1[1], perp1[2], 0,
+ this.start_[0], this.start_[1], this.start_[2], 1);
this.transform_.scale(1, math.length(vector), 1);
};
@@ -517,16 +517,18 @@ o3djs.debug.DebugHelper = function(pack, viewInfo) {
// Create the axis shape.
for (var ii = 0; ii < O3D_DEBUG_AXIS_INFO_.length; ++ii) {
var info = O3D_DEBUG_AXIS_INFO_[ii];
- var cubeShape = o3djs.primitives.createCube(pack,
- material,
- 1,
- [[1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0],
- [info.offset[0] * 0.5,
- info.offset[1] * 0.5,
- info.offset[2] * 0.5,
- 1]]);
+ var cubeShape = o3djs.primitives.createCube(
+ pack,
+ material,
+ 1,
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ info.offset[0] * 0.5,
+ info.offset[1] * 0.5,
+ info.offset[2] * 0.5,
+ 1));
+
var cube = cubeShape.elements[0];
cube.owner = this.axisShape_;
pack.removeObject(cubeShape);
diff --git a/o3d/samples/o3djs/fps.js b/o3d/samples/o3djs/fps.js
index c8e7888..51c233d 100644
--- a/o3d/samples/o3djs/fps.js
+++ b/o3d/samples/o3djs/fps.js
@@ -251,10 +251,10 @@ o3djs.fps.FPSManager = function(pack, clientWidth, clientHeight, opt_parent) {
1,
1,
1,
- [[1, 0, 0, 0],
- [0, 0, 1, 0],
- [0, -1, 0, 0],
- [0.5, 0.5, 0, 1]]);
+ o3djs.math.makeMatrix4(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0, 0,
+ 0.5, 0.5, 0, 1));
var barXOffset = 10;
var barYOffset = 2;
diff --git a/o3d/samples/o3djs/manipulators.js b/o3d/samples/o3djs/manipulators.js
index 8dc7278..4aa300f 100644
--- a/o3d/samples/o3djs/manipulators.js
+++ b/o3d/samples/o3djs/manipulators.js
@@ -244,8 +244,10 @@ o3djs.manipulators.Line_.prototype.closestPointToRay = function(startPoint,
// value of u' is less than zero.
var rayDirection = o3djs.math.subVector(endPoint, startPoint);
var ddrd = o3djs.math.dot(this.direction_, rayDirection);
- var A = [[-o3djs.math.lengthSquared(this.direction_), ddrd],
- [ddrd, -o3djs.math.lengthSquared(rayDirection)]];
+ var A = o3djs.math.makeMatrix2(-o3djs.math.lengthSquared(this.direction_),
+ ddrd,
+ ddrd,
+ -o3djs.math.lengthSquared(rayDirection));
var det = o3djs.math.det2(A);
if (Math.abs(det) < o3djs.manipulators.EPSILON) {
return null;
diff --git a/o3d/samples/o3djs/math.js b/o3d/samples/o3djs/math.js
index e840f23..c37ccb2 100644
--- a/o3d/samples/o3djs/math.js
+++ b/o3d/samples/o3djs/math.js
@@ -35,21 +35,20 @@
* It adds them to the "math" module on the o3djs object.
*
* o3djs.math supports a row-major and a column-major mode. In both
- * modes, vectors are stored as arrays of numbers, and matrices are stored as
- * arrays of arrays of numbers.
+ * modes, vectors are stored as arrays of numbers, and matrices are also.
*
* In row-major mode:
*
- * - Rows of a matrix are sub-arrays.
- * - Individual entries of a matrix M get accessed in M[row][column] fashion.
- * - Tuples of coordinates are interpreted as row-vectors.
+ * - Rows of a matrix are neighboring <dimension> elements in the array.
+ * - Entries of a matrix M get accessed in M[row*dimension+column] fashion.
+ * - Tuples of coordinates adjacent are interpreted as row-vectors.
* - A vector v gets transformed by a matrix M by multiplying in the order v*M.
*
* In column-major mode:
*
- * - Columns of a matrix are sub-arrays.
- * - Individual entries of a matrix M get accessed in M[column][row] fashion.
- * - Tuples of coordinates are interpreted as column-vectors.
+ * - Columns of a matrix are neighboring <dimension> elements in the array.
+ * - Entries of a matrix M get accessed in M[column*dimension+row] fashion.
+ * - Tuples of coordinates adjacent are interpreted as column-vectors.
* - A matrix M transforms a vector v by multiplying in the order M*v.
*
* When a function in o3djs.math requires separate row-major and
@@ -96,123 +95,483 @@
* mean all sample code will work even if a line is added which switches major
* modes, but it does mean that calls to o3djs still do what they are supposed
* to.
- *
*/
-o3djs.provide('o3djs.math');
+
+var use_plugin_math = false;
+
+if ((typeof o3d != 'undefined') && o3d && o3d.Transform &&
+ o3d.Transform.makeIdentityMatrix4_) {
+ o3djs.provide('o3djs.math');
+} else {
+ use_plugin_math = true;
+ o3djs.require('o3djs.plugin_math');
+}
+
+o3djs.provide("o3djs.flat_math");
/**
- * A module for math for o3djs.math.
+ * A module for math functions where a matrix is represented as a flat
+ * (1-dimensional) array.
* @namespace
*/
-o3djs.math = o3djs.math || {};
+o3djs.flat_math = o3djs.flat_math || {};
/**
* A random seed for the pseudoRandom function.
* @private
* @type {number}
*/
-o3djs.math.randomSeed_ = 0;
+o3djs.flat_math.randomSeed_ = 0;
/**
* A constant for the pseudoRandom function
* @private
* @type {number}
*/
-o3djs.math.RANDOM_RANGE_ = Math.pow(2, 32);
+o3djs.flat_math.RANDOM_RANGE_ = Math.pow(2, 32);
/**
* Functions which deal with 4-by-4 transformation matrices are kept in their
* own namespsace.
* @namespace
*/
-o3djs.math.matrix4 = o3djs.math.matrix4 || {};
+o3djs.flat_math.matrix4 = o3djs.flat_math.matrix4 || {};
/**
* Functions that are specifically row major are kept in their own namespace.
* @namespace
*/
-o3djs.math.rowMajor = o3djs.math.rowMajor || {};
+o3djs.flat_math.rowMajor = o3djs.flat_math.rowMajor || {};
/**
* Functions that are specifically column major are kept in their own namespace.
* @namespace
*/
-o3djs.math.columnMajor = o3djs.math.columnMajor || {};
+o3djs.flat_math.columnMajor = o3djs.flat_math.columnMajor || {};
/**
* Functions that do error checking are stored in their own namespace.
* @namespace
*/
-o3djs.math.errorCheck = o3djs.math.errorCheck || {};
+o3djs.flat_math.errorCheck = o3djs.flat_math.errorCheck || {};
/**
* Functions that do no error checking and have a separate version that does in
- * o3djs.math.errorCheck are stored in their own namespace.
+ * o3djs.flat_math.errorCheck are stored in their own namespace.
* @namespace
*/
-o3djs.math.errorCheckFree = o3djs.math.errorCheckFree || {};
+o3djs.flat_math.errorCheckFree = o3djs.flat_math.errorCheckFree || {};
/**
- * An Array of 2 floats
- * @type {(!Array.<number>|!o3d.Float2)}
+ * An Float32Array of 2 floats
+ * @type {(!Float32Array.<number>|!o3d.Float2)}
*/
-o3djs.math.Vector2 = goog.typedef;
+o3djs.flat_math.Vector2 = goog.typedef;
/**
- * An Array of 3 floats
- * @type {(!Array.<number>|!o3d.Float3)}
+ * An Float32Array of 3 floats
+ * @type {(!Float32Array.<number>|!o3d.Float3)}
*/
-o3djs.math.Vector3 = goog.typedef;
+o3djs.flat_math.Vector3 = goog.typedef;
/**
- * An Array of 4 floats
- * @type {(!Array.<number>|!o3d.Float4)}
+ * An Float32Array of 4 floats
+ * @type {(!Float32Array.<number>|!o3d.Float4)}
*/
-o3djs.math.Vector4 = goog.typedef;
+o3djs.flat_math.Vector4 = goog.typedef;
-/**
- * An Array of floats.
- * @type {!Array.<number>}
- */
-o3djs.math.Vector = goog.typedef;
/**
* A 1x1 Matrix of floats
- * @type {!Array.<!Array.<number>>}
+ * @type {!Array.<number>}
*/
-o3djs.math.Matrix1 = goog.typedef;
+o3djs.flat_math.Matrix1 = goog.typedef;
/**
* A 2x2 Matrix of floats
- * @type {!Array.<!Array.<number>>}
+ * @type {!Array.<number>}
*/
-o3djs.math.Matrix2 = goog.typedef;
+o3djs.flat_math.Matrix2 = goog.typedef;
/**
* A 3x3 Matrix of floats
- * @type {!Array.<!Array.<number>>}
+ * @type {!Array.<number>}
*/
-o3djs.math.Matrix3 = goog.typedef;
+o3djs.flat_math.Matrix3 = goog.typedef;
/**
* A 4x4 Matrix of floats
- * @type {(!Array.<!Array.<number>>|!o3d.Matrix4)}
+ * @type {(!Array.<number>|!o3d.Matrix4)}
+ */
+o3djs.flat_math.Matrix4 = goog.typedef;
+
+o3djs.flat_math.useFloat32Array_ = false;
+
+/**
+ * A arbitrary size Matrix of floats
+ * @type {(!Array.<number>|!o3d.Matrix4)}
*/
-o3djs.math.Matrix4 = goog.typedef;
+o3djs.flat_math.Matrix = goog.typedef;
+
+/**
+ * A arbitrary size Matrix of floats
+ * @type {(!Array.<number>)}
+ */
+o3djs.flat_math.Vector = goog.typedef;
+
+
+/**
+ * Namespace for Float32Array specific math functions
+ */
+o3djs.flat_math.Float32Array = {};
+
+/**
+ * A arbitrary size Matrix of floats
+ * @type {(!Array.<number>|!o3d.Matrix4)}
+ */
+o3djs.flat_math.Float32Array.Matrix =
+ (use_plugin_math ? goog.typedef : Float32Array);
+/**
+ * An Float32Array of floats.
+ * @type {!Array.<number>}
+ */
+o3djs.flat_math.Float32Array.Vector =
+ (use_plugin_math ? goog.typedef : Float32Array);
+
+/**
+ * If 16 arguments, this returns a 4x4 matrix
+ * 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
+ *
+ * If 9 arguments returns a 3x3 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [1][0] element
+ * @param {number} e [1][1] element
+ * @param {number} f [1][2] element
+ * @param {number} g [2][0] element
+ * @param {number} h [2][1] element
+ * @param {number} i [2][2] element
+
+ * If 4 arguments returns a 2x2 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [1][0] element
+ * @param {number} d [1][1] element
+ * @returns {!o3djs.flat_math.Matrix}
+ */
+o3djs.flat_math.Float32Array.makeMatrix = function(
+ a, b, c, d,
+ e, f, g, h,
+ i, j, k, l,
+ m, n, o, p) {
+ if (p === undefined) {
+ if (i === undefined) {
+ var retval = new Float32Array(4);
+ retval[0] = a;
+ retval[1] = b;
+ retval[2] = c;
+ retval[3] = d;
+ return retval;
+ }
+ var retval = new Float32Array(9);
+ retval[0] = a;
+ retval[1] = b;
+ retval[2] = c;
+ retval[3] = d;
+ retval[4] = e;
+ retval[5] = f;
+ retval[6] = g;
+ retval[7] = h;
+ retval[8] = i;
+ return retval;
+ }
+ var retval = new Float32Array(16);
+ retval[0] = a;
+ retval[1] = b;
+ retval[2] = c;
+ retval[3] = d;
+ retval[4] = e;
+ retval[5] = f;
+ retval[6] = g;
+ retval[7] = h;
+ retval[8] = i;
+ retval[9] = j;
+ retval[10] = k;
+ retval[11] = l;
+ retval[12] = m;
+ retval[13] = n;
+ retval[14] = o;
+ retval[15] = p;
+ return retval;
+};
+
+/**
+ * returns a 2x2 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [1][0] element
+ * @param {number} d [1][1] element
+ * @returns {!o3djs.flat_math.Matrix}
+ */
+o3djs.flat_math.Float32Array.makeMatrix2 = function(a,b,
+ c,d) {
+ var retval = new Float32Array(4);
+ retval[0] = a;
+ retval[1] = b;
+ retval[2] = c;
+ retval[3] = d;
+ return retval;
+};
+
+/**
+ * If returns a 3x3 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [1][0] element
+ * @param {number} e [1][1] element
+ * @param {number} f [1][2] element
+ * @param {number} g [2][0] element
+ * @param {number} h [2][1] element
+ * @param {number} i [2][2] element
+ * @return {!o3djs.flat_math.Matrix} the matrix of the above elements
+ */
+o3djs.flat_math.Float32Array.makeMatrix3 = function(
+ a, b, c,
+ d, e, f,
+ g, h, i) {
+ var retval = new Float32Array(9);
+ retval[0] = a;
+ retval[1] = b;
+ retval[2] = c;
+ retval[3] = d;
+ retval[4] = e;
+ retval[5] = f;
+ retval[6] = g;
+ retval[7] = h;
+ retval[8] = i;
+ return retval;
+};
+
+/**
+ * returns a 4x4 matrix
+ * 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
+ * @returns {o3djs.flat_math.Matrix} comprised of the above elements
+ */
+o3djs.flat_math.Float32Array.makeMatrix4 = function(
+ a, b, c, d,
+ e, f, g, h,
+ i, j, k, l,
+ m, n, o, p) {
+ var retval = new Float32Array(16);
+ retval[0] = a;
+ retval[1] = b;
+ retval[2] = c;
+ retval[3] = d;
+ retval[4] = e;
+ retval[5] = f;
+ retval[6] = g;
+ retval[7] = h;
+ retval[8] = i;
+ retval[9] = j;
+ retval[10] = k;
+ retval[11] = l;
+ retval[12] = m;
+ retval[13] = n;
+ retval[14] = o;
+ retval[15] = p;
+ return retval;
+};
+
+/**
+ * Namespace for Array specific math functions
+ */
+o3djs.flat_math.Array={};
/**
* A arbitrary size Matrix of floats
* @type {(!Array.<!Array.<number>>|!o3d.Matrix4)}
*/
-o3djs.math.Matrix = goog.typedef;
+o3djs.flat_math.Array.Matrix = (use_plugin_math ? goog.typedef: Array);
+
+/**
+ * An Float32Array of floats.
+ * @type {!Float32Array.<number>}
+ */
+o3djs.flat_math.Array.Vector = (use_plugin_math ? goog.typedef: Array);
+
+/**
+ * If 16 arguments, this returns a 4x4 matrix
+ * 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
+ *
+ * If 9 arguments returns a 3x3 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [1][0] element
+ * @param {number} e [1][1] element
+ * @param {number} f [1][2] element
+ * @param {number} g [2][0] element
+ * @param {number} h [2][1] element
+ * @param {number} i [2][2] element
+
+ * If 4 arguments returns a 2x2 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [1][0] element
+ * @param {number} d [1][1] element
+ * @returns {!o3djs.flat_math.Matrix}
+ */
+o3djs.flat_math.Array.makeMatrix = function(
+ a, b, c, d,
+ e, f, g, h,
+ i, j, k, l,
+ m, n, o, p) {
+ if (p === undefined) {
+ if (i === undefined) {
+ return [a,b,c,d];
+ }
+ return [a, b, c, d, e, f, g, h, i];
+ }
+ return [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p];
+};
+
+/**
+ * returns a 2x2 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [1][0] element
+ * @param {number} d [1][1] element
+ * @returns {!o3djs.flat_math.Matrix}
+ */
+o3djs.flat_math.Array.makeMatrix2 = function(a, b, c, d) {
+ return [a, b, c, d];
+};
+
+/**
+ * If returns a 3x3 matrix
+ * @param {number} a [0][0] element
+ * @param {number} b [0][1] element
+ * @param {number} c [0][2] element
+ * @param {number} d [1][0] element
+ * @param {number} e [1][1] element
+ * @param {number} f [1][2] element
+ * @param {number} g [2][0] element
+ * @param {number} h [2][1] element
+ * @param {number} i [2][2] element
+ * @return {!o3djs.flat_math.Matrix} the matrix of the above elements
+ */
+o3djs.flat_math.Array.makeMatrix3 = function(
+ a, b, c,
+ d, e, f,
+ g, h, i) {
+ return [a, b, c, d, e, f, g, h, i];
+};
+
+/**
+ * returns a 4x4 matrix
+ * 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
+ * @returns {o3djs.flat_math.Matrix} comprised of the above elements
+ */
+o3djs.flat_math.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];
+};
+
+if (o3djs.flat_math.useFloat32Array_) {
+ o3djs.flat_math.Matrix = o3djs.flat_math.Float32Array.Matrix;
+ o3djs.flat_math.Vector = o3djs.flat_math.Float32Array.Vector;
+ for (var i in o3djs.flat_math.Float32Array) {
+ if (o3djs.flat_math.Float32Array[i].call)
+ o3djs.flat_math[i]=o3djs.flat_math.Float32Array[i];
+ }
+} else {
+ o3djs.flat_math.Matrix = o3djs.flat_math.Array.Matrix;
+ o3djs.flat_math.Vector = o3djs.flat_math.Array.Vector;
+ for (var i in o3djs.flat_math.Array) {
+ if (o3djs.flat_math.Array[i].call)
+ o3djs.flat_math[i]=o3djs.flat_math.Array[i];
+ }
+}
+
+
+
/**
* Returns a deterministic pseudorandom number between 0 and 1
* @return {number} a random number between 0 and 1
*/
-o3djs.math.pseudoRandom = function() {
- var math = o3djs.math;
+o3djs.flat_math.pseudoRandom = function() {
+ var math = o3djs.flat_math;
return (math.randomSeed_ =
(134775813 * math.randomSeed_ + 1) %
math.RANDOM_RANGE_) / math.RANDOM_RANGE_;
@@ -221,8 +580,8 @@ o3djs.math.pseudoRandom = function() {
/**
* Resets the pseudoRandom function sequence.
*/
-o3djs.math.resetPseudoRandom = function() {
- o3djs.math.randomSeed_ = 0;
+o3djs.flat_math.resetPseudoRandom = function() {
+ o3djs.flat_math.randomSeed_ = 0;
};
/**
@@ -230,7 +589,7 @@ o3djs.math.resetPseudoRandom = function() {
* @param {number} degrees A value in degrees.
* @return {number} the value in radians.
*/
-o3djs.math.degToRad = function(degrees) {
+o3djs.flat_math.degToRad = function(degrees) {
return degrees * Math.PI / 180;
};
@@ -239,7 +598,7 @@ o3djs.math.degToRad = function(degrees) {
* @param {number} radians A value in radians.
* @return {number} the value in degrees.
*/
-o3djs.math.radToDeg = function(radians) {
+o3djs.flat_math.radToDeg = function(radians) {
return radians * 180 / Math.PI;
};
@@ -252,19 +611,19 @@ o3djs.math.radToDeg = function(radians) {
* @param {number} t Interpolation coefficient.
* @return {number} The weighted sum of a and b.
*/
-o3djs.math.lerpScalar = function(a, b, t) {
+o3djs.flat_math.lerpScalar = function(a, b, t) {
return (1 - t) * a + t * b;
};
/**
* Adds two vectors; assumes a and b have the same dimension.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The sum of a and b.
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
+ * @return {!o3djs.flat_math.Vector} The sum of a and b.
*/
-o3djs.math.addVector = function(a, b) {
- var r = [];
+o3djs.flat_math.addVector = function(a, b) {
var aLength = a.length;
+ var r = new o3djs.flat_math.Vector(aLength);
for (var i = 0; i < aLength; ++i)
r[i] = a[i] + b[i];
return r;
@@ -272,30 +631,43 @@ o3djs.math.addVector = function(a, b) {
/**
* Subtracts two vectors.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The difference of a and b.
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
+ * @return {!o3djs.flat_math.Vector} The difference of a and b.
*/
-o3djs.math.subVector = function(a, b) {
- var r = [];
+o3djs.flat_math.subVector = function(a, b) {
var aLength = a.length;
+ var r = new o3djs.flat_math.Vector(aLength);
for (var i = 0; i < aLength; ++i)
r[i] = a[i] - b[i];
return r;
};
/**
+ * Subtracts two 3d vectors.
+ * @param {!o3djs.flat_math.Vector3} a Operand vector.
+ * @param {!o3djs.flat_math.Vector3} b Operand vector.
+ * @return {!o3djs.flat_math.Vector3} The difference of a and b.
+ */
+o3djs.flat_math.subVector3 = function(a, b) {
+ var r = new o3djs.flat_math.Vector(3);
+ for (var i = 0; i < 3; ++i)
+ r[i] = a[i] - b[i];
+ return r;
+};
+
+/**
* Performs linear interpolation on two vectors.
* Given vectors a and b and interpolation coefficient t, returns
* (1 - t) * a + t * b.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
* @param {number} t Interpolation coefficient.
- * @return {!o3djs.math.Vector} The weighted sum of a and b.
+ * @return {!o3djs.flat_math.Vector} The weighted sum of a and b.
*/
-o3djs.math.lerpVector = function(a, b, t) {
- var r = [];
+o3djs.flat_math.lerpVector = function(a, b, t) {
var aLength = a.length;
+ var r = new o3djs.flat_math.Vector(aLength);
for (var i = 0; i < aLength; ++i)
r[i] = (1 - t) * a[i] + t * b[i];
return r;
@@ -308,7 +680,7 @@ o3djs.math.lerpVector = function(a, b, t) {
* @param {number} opt_rangeStart start of range. Default = 0.
* @return {number} Clamp modded value.
*/
-o3djs.math.modClamp = function(v, range, opt_rangeStart) {
+o3djs.flat_math.modClamp = function(v, range, opt_rangeStart) {
var start = opt_rangeStart || 0;
if (range < 0.00001) {
return start;
@@ -332,9 +704,9 @@ o3djs.math.modClamp = function(v, range, opt_rangeStart) {
* @param {number} range Range of circle.
* @return {number} lerped result.
*/
-o3djs.math.lerpCircular = function(a, b, t, range) {
- a = o3djs.math.modClamp(a, range);
- b = o3djs.math.modClamp(b, range);
+o3djs.flat_math.lerpCircular = function(a, b, t, range) {
+ a = o3djs.flat_math.modClamp(a, range);
+ b = o3djs.flat_math.modClamp(b, range);
var delta = b - a;
if (Math.abs(delta) > range * 0.5) {
if (delta > 0) {
@@ -343,7 +715,7 @@ o3djs.math.lerpCircular = function(a, b, t, range) {
b += range;
}
}
- return o3djs.math.modClamp(o3djs.math.lerpScalar(a, b, t), range);
+ return o3djs.flat_math.modClamp(o3djs.flat_math.lerpScalar(a, b, t), range);
};
/**
@@ -353,17 +725,17 @@ o3djs.math.lerpCircular = function(a, b, t, range) {
* @param {number} t Amount to lerp (0 to 1).
* @return {number} lerped result.
*/
-o3djs.math.lerpRadian = function(a, b, t) {
- return o3djs.math.lerpCircular(a, b, t, Math.PI * 2);
+o3djs.flat_math.lerpRadian = function(a, b, t) {
+ return o3djs.flat_math.lerpCircular(a, b, t, Math.PI * 2);
};
/**
* Divides a vector by a scalar.
- * @param {!o3djs.math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Vector} v The vector.
* @param {number} k The scalar.
- * @return {!o3djs.math.Vector} v The vector v divided by k.
+ * @return {!o3djs.flat_math.Vector} v The vector v divided by k.
*/
-o3djs.math.divVectorScalar = function(v, k) {
+o3djs.flat_math.divVectorScalar = function(v, k) {
var r = [];
var vLength = v.length;
for (var i = 0; i < vLength; ++i)
@@ -374,11 +746,11 @@ o3djs.math.divVectorScalar = function(v, k) {
/**
* Computes the dot product of two vectors; assumes that a and b have
* the same dimension.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
* @return {number} The dot product of a and b.
*/
-o3djs.math.dot = function(a, b) {
+o3djs.flat_math.dot = function(a, b) {
var r = 0.0;
var aLength = a.length;
for (var i = 0; i < aLength; ++i)
@@ -389,23 +761,25 @@ o3djs.math.dot = function(a, b) {
/**
* Computes the cross product of two vectors; assumes both vectors have
* three entries.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The vector a cross b.
- */
-o3djs.math.cross = function(a, b) {
- return [a[1] * b[2] - a[2] * b[1],
- a[2] * b[0] - a[0] * b[2],
- a[0] * b[1] - a[1] * b[0]];
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
+ * @return {!o3djs.flat_math.Vector} The vector a cross b.
+ */
+o3djs.flat_math.cross = function(a, b) {
+ var r = new o3djs.flat_math.Vector(3);
+ r[0] = a[1] * b[2] - a[2] * b[1];
+ r[1] = a[2] * b[0] - a[0] * b[2];
+ r[2] = a[0] * b[1] - a[1] * b[0];
+ return r;
};
/**
* Computes the Euclidean length of a vector, i.e. the square root of the
* sum of the squares of the entries.
- * @param {!o3djs.math.Vector} a The vector.
+ * @param {!o3djs.flat_math.Vector} a The vector.
* @return {number} The length of a.
*/
-o3djs.math.length = function(a) {
+o3djs.flat_math.length = function(a) {
var r = 0.0;
var aLength = a.length;
for (var i = 0; i < aLength; ++i)
@@ -416,10 +790,10 @@ o3djs.math.length = function(a) {
/**
* Computes the square of the Euclidean length of a vector, i.e. the sum
* of the squares of the entries.
- * @param {!o3djs.math.Vector} a The vector.
+ * @param {!o3djs.flat_math.Vector} a The vector.
* @return {number} The square of the length of a.
*/
-o3djs.math.lengthSquared = function(a) {
+o3djs.flat_math.lengthSquared = function(a) {
var r = 0.0;
var aLength = a.length;
for (var i = 0; i < aLength; ++i)
@@ -429,11 +803,11 @@ o3djs.math.lengthSquared = function(a) {
/**
* Computes the Euclidean distance between two vectors.
- * @param {!o3djs.math.Vector} a A vector.
- * @param {!o3djs.math.Vector} b A vector.
+ * @param {!o3djs.flat_math.Vector} a A vector.
+ * @param {!o3djs.flat_math.Vector} b A vector.
* @return {number} The distance between a and b.
*/
-o3djs.math.distance = function(a, b) {
+o3djs.flat_math.distance = function(a, b) {
var r = 0.0;
var aLength = a.length;
for (var i = 0; i < aLength; ++i) {
@@ -445,11 +819,11 @@ o3djs.math.distance = function(a, b) {
/**
* Computes the square of the Euclidean distance between two vectors.
- * @param {!o3djs.math.Vector} a A vector.
- * @param {!o3djs.math.Vector} b A vector.
+ * @param {!o3djs.flat_math.Vector} a A vector.
+ * @param {!o3djs.flat_math.Vector} b A vector.
* @return {number} The distance between a and b.
*/
-o3djs.math.distanceSquared = function(a, b) {
+o3djs.flat_math.distanceSquared = function(a, b) {
var r = 0.0;
var aLength = a.length;
for (var i = 0; i < aLength; ++i) {
@@ -461,59 +835,48 @@ o3djs.math.distanceSquared = function(a, b) {
/**
* Divides a vector by its Euclidean length and returns the quotient.
- * @param {!o3djs.math.Vector} a The vector.
- * @return {!o3djs.math.Vector} The normalized vector.
+ * @param {!o3djs.flat_math.Vector} a The vector.
+ * @return {!o3djs.flat_math.Vector} The normalized vector.
*/
-o3djs.math.normalize = function(a) {
- var r = [];
- var n = 0.0;
+o3djs.flat_math.normalize = function(a) {
var aLength = a.length;
- for (var i = 0; i < aLength; ++i)
+ var r = new o3djs.flat_math.Vector(aLength);
+ var n = 0.0;
+ var i;
+ for (i = 0; i < aLength; ++i)
n += a[i] * a[i];
n = Math.sqrt(n);
- for (var i = 0; i < aLength; ++i)
+ for (i = 0; i < aLength; ++i)
r[i] = a[i] / n;
return r;
};
/**
* Adds two matrices; assumes a and b are the same size.
- * @param {!o3djs.math.Matrix} a Operand matrix.
- * @param {!o3djs.math.Matrix} b Operand matrix.
- * @return {!o3djs.math.Matrix} The sum of a and b.
+ * @param {!o3djs.flat_math.Matrix} a Operand matrix.
+ * @param {!o3djs.flat_math.Matrix} b Operand matrix.
+ * @return {!o3djs.flat_math.Matrix} The sum of a and b.
*/
-o3djs.math.addMatrix = function(a, b) {
- var r = [];
+o3djs.flat_math.addMatrix = function(a, b) {
var aLength = a.length;
- var a0Length = a[0].length;
+ var r = new o3djs.flat_math.Matrix(aLength);
for (var i = 0; i < aLength; ++i) {
- var row = [];
- var ai = a[i];
- var bi = b[i];
- for (var j = 0; j < a0Length; ++j)
- row[j] = ai[j] + bi[j];
- r[i] = row;
+ r[i] = a[i] + b[i];
}
return r;
};
/**
* Subtracts two matrices; assumes a and b are the same size.
- * @param {!o3djs.math.Matrix} a Operand matrix.
- * @param {!o3djs.math.Matrix} b Operand matrix.
- * @return {!o3djs.math.Matrix} The sum of a and b.
+ * @param {!o3djs.flat_math.Matrix} a Operand matrix.
+ * @param {!o3djs.flat_math.Matrix} b Operand matrix.
+ * @return {!o3djs.flat_math.Matrix} The sum of a and b.
*/
-o3djs.math.subMatrix = function(a, b) {
- var r = [];
+o3djs.flat_math.subMatrix = function(a, b) {
var aLength = a.length;
- var a0Length = a[0].length;
+ var r = new o3djs.flat_math.Matrix(aLength);
for (var i = 0; i < aLength; ++i) {
- var row = [];
- var ai = a[i];
- var bi = b[i];
- for (var j = 0; j < a0Length; ++j)
- row[j] = ai[j] - bi[j];
- r[i] = row;
+ r[i] = a[i] - b[i];
}
return r;
};
@@ -522,40 +885,31 @@ o3djs.math.subMatrix = function(a, b) {
* Performs linear interpolation on two matrices.
* Given matrices a and b and interpolation coefficient t, returns
* (1 - t) * a + t * b.
- * @param {!o3djs.math.Matrix} a Operand matrix.
- * @param {!o3djs.math.Matrix} b Operand matrix.
+ * @param {!o3djs.flat_math.Matrix} a Operand matrix.
+ * @param {!o3djs.flat_math.Matrix} b Operand matrix.
* @param {number} t Interpolation coefficient.
- * @return {!o3djs.math.Matrix} The weighted of a and b.
+ * @return {!o3djs.flat_math.Matrix} Interpolated a and b.
*/
-o3djs.math.lerpMatrix = function(a, b, t) {
- var r = [];
+o3djs.flat_math.lerpMatrix = function(a, b, t) {
var aLength = a.length;
- var a0Length = a[0].length;
+ var r = new o3djs.flat_math.Matrix(aLength);
for (var i = 0; i < aLength; ++i) {
- var row = [];
- var ai = a[i];
- var bi = b[i];
- for (var j = 0; j < a0Length; ++j)
- row[j] = (1 - t) * ai[j] + t * bi[j];
- r[i] = row;
+ r[i] = (1 - t) * a[i] + t * b[i];
}
return r;
};
/**
- * Divides a matrix by a scalar.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {number} k The scalar.
- * @return {!o3djs.math.Matrix} The matrix m divided by k.
+ * Divides a matrix by a scalar; assumes a and b are the same size.
+ * @param {!o3djs.flat_math.Matrix} a Operand matrix.
+ * @param {number} b scalar
+ * @return {!o3djs.flat_math.Matrix} The division of a by b.
*/
-o3djs.math.divMatrixScalar = function(m, k) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m0Length; ++j)
- r[i][j] = m[i][j] / k;
+o3djs.flat_math.divMatrixScalar = function(a, b) {
+ var aLength = a.length;
+ var r = new o3djs.flat_math.Matrix(aLength);
+ for (var i = 0; i < aLength; ++i) {
+ r[i] = a[i] / b;
}
return r;
};
@@ -565,18 +919,18 @@ o3djs.math.divMatrixScalar = function(m, k) {
* @param {number} a The scalar.
* @return {number} -a.
*/
-o3djs.math.negativeScalar = function(a) {
+o3djs.flat_math.negativeScalar = function(a) {
return -a;
};
/**
* Negates a vector.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} -v.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} -v.
*/
-o3djs.math.negativeVector = function(v) {
- var r = [];
+o3djs.flat_math.negativeVector = function(v) {
var vLength = v.length;
+ var r = new o3djs.flat_math.Vector(vLength);
for (var i = 0; i < vLength; ++i) {
r[i] = -v[i];
}
@@ -585,17 +939,14 @@ o3djs.math.negativeVector = function(v) {
/**
* Negates a matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} -m.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} -m.
*/
-o3djs.math.negativeMatrix = function(m) {
- var r = [];
+o3djs.flat_math.negativeMatrix = function(m) {
var mLength = m.length;
- var m0Length = m[0].length;
+ var r = new o3djs.flat_math.Matrix(mLength);
for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m0Length; ++j)
- r[i][j] = -m[i][j];
+ r[i] = -m[i];
}
return r;
};
@@ -605,57 +956,56 @@ o3djs.math.negativeMatrix = function(m) {
* @param {number} a The scalar.
* @return {number} a.
*/
-o3djs.math.copyScalar = function(a) {
+o3djs.flat_math.copyScalar = function(a) {
return a;
};
/**
* Copies a vector.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} A copy of v.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} A copy of v.
*/
-o3djs.math.copyVector = function(v) {
- var r = [];
- for (var i = 0; i < v.length; i++)
+o3djs.flat_math.copyVector = function(v) {
+ var vLength = v.length;
+ var r = new o3djs.flat_math.Vector(vLength);
+ for (var i = 0; i < vLength; i++)
r[i] = v[i];
return r;
};
/**
- * Copies a matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} A copy of m.
+ * Copies a vector.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Vector} r Set to a copy of v.
*/
-o3djs.math.copyMatrix = function(m) {
- var r = [];
- var mLength = m.length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m[i].length; j++) {
- r[i][j] = m[i][j];
- }
- }
- return r;
+o3djs.flat_math.copyVectorTo = function(v, r) {
+ var vLength = v.length;
+ for (var i = 0; i < vLength; i++)
+ r[i] = v[i];
};
/**
- * Returns the elements of a matrix as a one-dimensional array. The
+ * Copies a matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} A copy of m.
+ */
+o3djs.flat_math.copyMatrix = o3djs.flat_math.copyVector;
+
+/**
+ * Copies a matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} A copy of m.
+ */
+o3djs.flat_math.copyMatrixTo = o3djs.flat_math.copyVectorTo;
+
+/**
+ * Returns the elements of a matrix as a copied one-dimensional array. The
* rows or columns (depending on whether the matrix is row-major or
* column-major) are concatenated.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @return {!Array.<number>} The matrix's elements as a one-dimensional array.
*/
-o3djs.math.getMatrixElements = function(m) {
- var r = [];
- var mLength = m.length;
- var k = 0;
- for (var i = 0; i < mLength; i++) {
- for (var j = 0; j < m[i].length; j++) {
- r[k++] = m[i][j];
- }
- }
- return r;
-};
+o3djs.flat_math.getMatrixElements = o3djs.flat_math.copyMatrix;
/**
* Multiplies two scalars.
@@ -663,19 +1013,19 @@ o3djs.math.getMatrixElements = function(m) {
* @param {number} b Operand scalar.
* @return {number} The product of a and b.
*/
-o3djs.math.mulScalarScalar = function(a, b) {
+o3djs.flat_math.mulScalarScalar = function(a, b) {
return a * b;
};
/**
* Multiplies a scalar by a vector.
* @param {number} k The scalar.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of k and v.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} The product of k and v.
*/
-o3djs.math.mulScalarVector = function(k, v) {
- var r = [];
+o3djs.flat_math.mulScalarVector = function(k, v) {
var vLength = v.length;
+ var r = new o3djs.flat_math.Vector(vLength);
for (var i = 0; i < vLength; ++i) {
r[i] = k * v[i];
}
@@ -684,53 +1034,41 @@ o3djs.math.mulScalarVector = function(k, v) {
/**
* Multiplies a vector by a scalar.
- * @param {!o3djs.math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Vector} v The vector.
* @param {number} k The scalar.
- * @return {!o3djs.math.Vector} The product of k and v.
+ * @return {!o3djs.flat_math.Vector} The product of k and v.
*/
-o3djs.math.mulVectorScalar = function(v, k) {
- return o3djs.math.mulScalarVector(k, v);
+o3djs.flat_math.mulVectorScalar = function(v, k) {
+ return o3djs.flat_math.mulScalarVector(k, v);
};
/**
* Multiplies a scalar by a matrix.
* @param {number} k The scalar.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} The product of m and k.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} The product of m and k.
*/
-o3djs.math.mulScalarMatrix = function(k, m) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = [];
- for (var j = 0; j < m0Length; ++j)
- r[i][j] = k * m[i][j];
- }
- return r;
-};
+o3djs.flat_math.mulScalarMatrix = o3djs.flat_math.mulScalarVector;
/**
* Multiplies a matrix by a scalar.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} k The scalar.
- * @return {!o3djs.math.Matrix} The product of m and k.
+ * @return {!o3djs.flat_math.Matrix} The product of m and k.
*/
-o3djs.math.mulMatrixScalar = function(m, k) {
- return o3djs.math.mulScalarMatrix(k, m);
-};
+o3djs.flat_math.mulMatrixScalar = o3djs.flat_math.mulVectorScalar;
/**
* Multiplies a vector by another vector (component-wise); assumes a and
* b have the same length.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The vector of products of entries of a and
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
+ * @return {!o3djs.flat_math.Vector} The vector of products of entries of a and
* b.
*/
-o3djs.math.mulVectorVector = function(a, b) {
- var r = [];
+o3djs.flat_math.mulVectorVector = function(a, b) {
var aLength = a.length;
+ var r = new o3djs.flat_math.Vector(aLength);
for (var i = 0; i < aLength; ++i)
r[i] = a[i] * b[i];
return r;
@@ -739,14 +1077,14 @@ o3djs.math.mulVectorVector = function(a, b) {
/**
* Divides a vector by another vector (component-wise); assumes a and
* b have the same length.
- * @param {!o3djs.math.Vector} a Operand vector.
- * @param {!o3djs.math.Vector} b Operand vector.
- * @return {!o3djs.math.Vector} The vector of quotients of entries of a and
+ * @param {!o3djs.flat_math.Vector} a Operand vector.
+ * @param {!o3djs.flat_math.Vector} b Operand vector.
+ * @return {!o3djs.flat_math.Vector} The vector of quotients of entries of a and
* b.
*/
-o3djs.math.divVectorVector = function(a, b) {
- var r = [];
+o3djs.flat_math.divVectorVector = function(a, b) {
var aLength = a.length;
+ var r = new o3djs.flat_math.Vector(aLength);
for (var i = 0; i < aLength; ++i)
r[i] = a[i] / b[i];
return r;
@@ -754,398 +1092,490 @@ o3djs.math.divVectorVector = function(a, b) {
/**
* Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Vector} v The vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Vector} The product of v and m as a row vector.
+ * matrix entries are accessed in [row*4+column] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
+ */
+o3djs.flat_math.rowMajor.mulVectorMatrix4 = function(v, m) {
+ var r = new o3djs.flat_math.Vector(16);
+ for (var i = 0; i < 4; ++i) {
+ r[i] = 0.0;
+ for (var j = 0; j < 4; ++j)
+ r[i] += v[j] * m[j * 4 + i];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [row*2+column] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @returns {!o3djs.flat_math.Vector} The product of v and m as a row vector.
+ */
+o3djs.flat_math.rowMajor.mulVectorMatrix2 = function(v, m) {
+ var r = new o3djs.flat_math.Vector(4);
+ for (var i = 0; i < 2; ++i) {
+ r[i] = 0.0;
+ for (var j = 0; j < 2; ++j)
+ r[i] += v[j] * m[j * 2 + i];
+ }
+ return r;
+};
+
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [row*3+column] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @returns {!o3djs.flat_math.Vector} The product of v and m as a row vector.
+ */
+o3djs.flat_math.rowMajor.mulVectorMatrix3 = function(v, m) {
+ var r = new o3djs.flat_math.Vector(9);
+ for (var i = 0; i < 3; ++i) {
+ r[i] = 0.0;
+ for (var j = 0; j < 3; ++j)
+ r[i] += v[j] * m[j * 3 + i];
+ }
+ return r;
+};
+
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [row*dimension+column] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
+ */
+o3djs.flat_math.rowMajor.mulVectorMatrix = function(v, m) {
+ switch(m.length) {
+ case 4:
+ return o3djs.flat_math.rowMajor.mulVectorMatrix2(v, m);
+ case 9:
+ return o3djs.flat_math.rowMajor.mulVectorMatrix3(v, m);
+ case 16:
+ return o3djs.flat_math.rowMajor.mulVectorMatrix4(v, m);
+ default:
+ throw "Cannot handle matrices of size other than 3x3 or 4x4";
+ }
+};
+
+
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [column*4+row] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} r The product of v and m as a row vector.
+ */
+o3djs.flat_math.rowMajor.mulMatrixVector4 = function(m, v) {
+ var r = new o3djs.flat_math.Vector(4);
+ var vLength = v.length;
+ for (var i = 0; i < 4; ++i) {
+ r[i] = 0.0;
+ for (var j = 0; j < 4; ++j)
+ r[i] += v[j] * m[i * 4 + j];
+ }
+ return r;
+};
+
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [column*3+row] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} r The product of v and m as a row vector.
*/
-o3djs.math.rowMajor.mulVectorMatrix = function(v, m) {
- var r = [];
- var m0Length = m[0].length;
+o3djs.flat_math.rowMajor.mulMatrixVector3 = function(m, v) {
+ var r = new o3djs.flat_math.Vector(3);
var vLength = v.length;
- for (var i = 0; i < m0Length; ++i) {
+ for (var i = 0; i < 3; ++i) {
r[i] = 0.0;
- for (var j = 0; j < vLength; ++j)
- r[i] += v[j] * m[j][i];
+ for (var j = 0; j < 3; ++j)
+ r[i] += v[j] * m[i * 3 + j];
}
return r;
};
/**
* Multiplies a vector by a matrix; treats the vector as a row vector; assumes
- * matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Vector} v The vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Vector} The product of v and m as a row vector.
+ * matrix entries are accessed in [column*2+row] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} r The product of v and m as a row vector.
*/
-o3djs.math.columnMajor.mulVectorMatrix = function(v, m) {
- var r = [];
- var mLength = m.length;
+o3djs.flat_math.rowMajor.mulMatrixVector2 = function(m, v) {
+ var r = new o3djs.flat_math.Vector(2);
+
var vLength = v.length;
- for (var i = 0; i < mLength; ++i) {
+ for (var i = 0; i < 2; ++i) {
r[i] = 0.0;
- var column = m[i];
- for (var j = 0; j < vLength; ++j)
- r[i] += v[j] * column[j];
+ for (var j = 0; j < 2; ++j)
+ r[i] += v[j] * m[i * 2 + j];
}
return r;
};
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [column*dimension+row] fashion.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Vector} The product of v and m as a row vector.
+ */
+o3djs.flat_math.rowMajor.mulMatrixVector = function(m, v) {
+ switch(m.length) {
+ case 4:
+ return o3djs.flat_math.rowMajor.mulMatrixVector2(m, v);
+ case 9:
+ return o3djs.flat_math.rowMajor.mulMatrixVector3(m, v);
+ case 16:
+ return o3djs.flat_math.rowMajor.mulMatrixVector4(m, v);
+ default:
+ throw "Cannot handle matrices of size other than 3x3 or 4x4";
+ }
+};
+
/**
* Multiplies a vector by a matrix; treats the vector as a row vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a row vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} The product of m and v as a row vector.
*/
-o3djs.math.mulVectorMatrix = null;
+o3djs.flat_math.mulVectorMatrix = null;
/**
* Multiplies a matrix by a vector; treats the vector as a column vector.
* assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a column vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} The product of m and v as a column vector.
*/
-o3djs.math.rowMajor.mulMatrixVector = function(m, v) {
- var r = [];
- var mLength = m.length;
- var m0Length = m[0].length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = 0.0;
- var row = m[i];
- for (var j = 0; j < m0Length; ++j)
- r[i] += row[j] * v[j];
- }
- return r;
+o3djs.flat_math.columnMajor.mulVectorMatrix = function (v, m) {
+ return o3djs.flat_math.rowMajor.mulMatrixVector(m, v);
};
/**
* Multiplies a matrix by a vector; treats the vector as a column vector;
* assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a column vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} The product of m and v as a column vector.
*/
-o3djs.math.columnMajor.mulMatrixVector = function(m, v) {
- var r = [];
- var m0Length = m[0].length;
- var vLength = v.length;
- for (var i = 0; i < m0Length; ++i) {
- r[i] = 0.0;
- for (var j = 0; j < vLength; ++j)
- r[i] += v[j] * m[j][i];
- }
- return r;
+o3djs.flat_math.columnMajor.mulMatrixVector = function(m, v) {
+ return o3djs.flat_math.rowMajor.mulVectorMatrix(v, m);
};
/**
* Multiplies a matrix by a vector; treats the vector as a column vector.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @param {!o3djs.math.Vector} v The vector.
- * @return {!o3djs.math.Vector} The product of m and v as a column vector.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Vector} v The vector.
+ * @return {!o3djs.flat_math.Vector} The product of m and v as a column vector.
*/
-o3djs.math.mulMatrixVector = null;
+o3djs.flat_math.mulMatrixVector = null;
/**
* Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
* assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix2} a The matrix on the left.
- * @param {!o3djs.math.Matrix2} b The matrix on the right.
- * @return {!o3djs.math.Matrix2} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix2} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix2} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix2} The matrix product of a and b.
*/
-o3djs.math.rowMajor.mulMatrixMatrix2 = function(a, b) {
+o3djs.flat_math.rowMajor.mulMatrixMatrix2 = function(a, b) {
var a0 = a[0];
var a1 = a[1];
var b0 = b[0];
var b1 = b[1];
- var a00 = a0[0];
- var a01 = a0[1];
- var a10 = a1[0];
- var a11 = a1[1];
- var b00 = b0[0];
- var b01 = b0[1];
- var b10 = b1[0];
- var b11 = b1[1];
- return [[a00 * b00 + a01 * b10, a00 * b01 + a01 * b11],
- [a10 * b00 + a11 * b10, a10 * b01 + a11 * b11]];
+ var a00 = a[0];
+ var a01 = a[1];
+ var a10 = a[2];
+ var a11 = a[3];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b10 = b[2];
+ var b11 = b[3];
+ return o3djs.flat_math.makeMatrix2(a00 * b00 + a01 * b10, a00 * b01 + a01 * b11,
+ a10 * b00 + a11 * b10, a10 * b01 + a11 * b11);
};
/**
* Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
* assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix2} a The matrix on the left.
- * @param {!o3djs.math.Matrix2} b The matrix on the right.
- * @return {!o3djs.math.Matrix2} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix2} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix2} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix2} The matrix product of a and b.
*/
-o3djs.math.columnMajor.mulMatrixMatrix2 = function(a, b) {
+o3djs.flat_math.columnMajor.mulMatrixMatrix2 = function(a, b) {
var a0 = a[0];
var a1 = a[1];
var b0 = b[0];
var b1 = b[1];
- var a00 = a0[0];
- var a01 = a0[1];
- var a10 = a1[0];
- var a11 = a1[1];
- var b00 = b0[0];
- var b01 = b0[1];
- var b10 = b1[0];
- var b11 = b1[1];
- return [[a00 * b00 + a10 * b01, a01 * b00 + a11 * b01],
- [a00 * b10 + a10 * b11, a01 * b10 + a11 * b11]];
+ var a00 = a[0];
+ var a01 = a[1];
+ var a10 = a[2];
+ var a11 = a[3];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b10 = b[2];
+ var b11 = b[3];
+ return o3djs.flat_math.makeMatrix2(a00 * b00 + a10 * b01, a01 * b00 + a11 * b01,
+ a00 * b10 + a10 * b11, a01 * b10 + a11 * b11);
};
/**
* Multiplies two 2-by-2 matrices.
- * @param {!o3djs.math.Matrix2} a The matrix on the left.
- * @param {!o3djs.math.Matrix2} b The matrix on the right.
- * @return {!o3djs.math.Matrix2} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix2} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix2} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix2} The matrix product of a and b.
*/
-o3djs.math.mulMatrixMatrix2 = null;
+o3djs.flat_math.mulMatrixMatrix2 = null;
/**
* Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
* assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix3} a The matrix on the left.
- * @param {!o3djs.math.Matrix3} b The matrix on the right.
- * @return {!o3djs.math.Matrix3} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix3} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix3} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix3} The matrix product of a and b.
*/
-o3djs.math.rowMajor.mulMatrixMatrix3 = function(a, b) {
+o3djs.flat_math.rowMajor.mulMatrixMatrix3 = function(a, b) {
var a0 = a[0];
var a1 = a[1];
var a2 = a[2];
var b0 = b[0];
var b1 = b[1];
var b2 = b[2];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- return [[a00 * b00 + a01 * b10 + a02 * b20,
+ var a00 = a[0];
+ var a01 = a[1];
+ var a02 = a[2];
+ var a10 = a[3];
+ var a11 = a[4];
+ var a12 = a[5];
+ var a20 = a[6];
+ var a21 = a[7];
+ var a22 = a[8];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b02 = b[2];
+ var b10 = b[3];
+ var b11 = b[4];
+ var b12 = b[5];
+ var b20 = b[6];
+ var b21 = b[7];
+ var b22 = b[8];
+ return o3djs.flat_math.makeMatrix3(a00 * b00 + a01 * b10 + a02 * b20,
a00 * b01 + a01 * b11 + a02 * b21,
- a00 * b02 + a01 * b12 + a02 * b22],
- [a10 * b00 + a11 * b10 + a12 * b20,
+ a00 * b02 + a01 * b12 + a02 * b22,
+ a10 * b00 + a11 * b10 + a12 * b20,
a10 * b01 + a11 * b11 + a12 * b21,
- a10 * b02 + a11 * b12 + a12 * b22],
- [a20 * b00 + a21 * b10 + a22 * b20,
+ a10 * b02 + a11 * b12 + a12 * b22,
+ a20 * b00 + a21 * b10 + a22 * b20,
a20 * b01 + a21 * b11 + a22 * b21,
- a20 * b02 + a21 * b12 + a22 * b22]];
+ a20 * b02 + a21 * b12 + a22 * b22);
};
/**
* Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
* assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix3} a The matrix on the left.
- * @param {!o3djs.math.Matrix3} b The matrix on the right.
- * @return {!o3djs.math.Matrix3} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix3 = function(a, b) {
- var a0 = a[0];
- var a1 = a[1];
- var a2 = a[2];
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
- var a00 = a0[0];
- var a01 = a0[1];
- var a02 = a0[2];
- var a10 = a1[0];
- var a11 = a1[1];
- var a12 = a1[2];
- var a20 = a2[0];
- var a21 = a2[1];
- var a22 = a2[2];
- var b00 = b0[0];
- var b01 = b0[1];
- var b02 = b0[2];
- var b10 = b1[0];
- var b11 = b1[1];
- var b12 = b1[2];
- var b20 = b2[0];
- var b21 = b2[1];
- var b22 = b2[2];
- return [[a00 * b00 + a10 * b01 + a20 * b02,
+ * @param {!o3djs.flat_math.Matrix3} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix3} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix3} The matrix product of a and b.
+ */
+o3djs.flat_math.columnMajor.mulMatrixMatrix3 = function(a, b) {
+
+ var a00 = a[0];
+ var a01 = a[1];
+ var a02 = a[2];
+ var a10 = a[3];
+ var a11 = a[4];
+ var a12 = a[5];
+ var a20 = a[6];
+ var a21 = a[7];
+ var a22 = a[8];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b02 = b[2];
+ var b10 = b[3];
+ var b11 = b[4];
+ var b12 = b[5];
+ var b20 = b[6];
+ var b21 = b[7];
+ var b22 = b[8];
+
+ return o3djs.flat_math.makeMatrix4(a00 * b00 + a10 * b01 + a20 * b02,
a01 * b00 + a11 * b01 + a21 * b02,
- a02 * b00 + a12 * b01 + a22 * b02],
- [a00 * b10 + a10 * b11 + a20 * b12,
+ a02 * b00 + a12 * b01 + a22 * b02,
+ a00 * b10 + a10 * b11 + a20 * b12,
a01 * b10 + a11 * b11 + a21 * b12,
- a02 * b10 + a12 * b11 + a22 * b12],
- [a00 * b20 + a10 * b21 + a20 * b22,
+ a02 * b10 + a12 * b11 + a22 * b12,
+ a00 * b20 + a10 * b21 + a20 * b22,
a01 * b20 + a11 * b21 + a21 * b22,
- a02 * b20 + a12 * b21 + a22 * b22]];
+ a02 * b20 + a12 * b21 + a22 * b22);
};
/**
* Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3.
- * @param {!o3djs.math.Matrix3} a The matrix on the left.
- * @param {!o3djs.math.Matrix3} b The matrix on the right.
- * @return {!o3djs.math.Matrix3} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix3} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix3} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix3} The matrix product of a and b.
*/
-o3djs.math.mulMatrixMatrix3 = null;
+o3djs.flat_math.mulMatrixMatrix3 = null;
/**
* Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
* assumes matrix entries are accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
- */
-o3djs.math.rowMajor.mulMatrixMatrix4 = function(a, b) {
- 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];
- return [[a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,
+ * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
+ */
+o3djs.flat_math.rowMajor.mulMatrixMatrix4 = function(a, b) {
+
+ 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];
+ return o3djs.flat_math.makeMatrix4(a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,
a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,
a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,
- a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33],
- [a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,
+ a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33,
+ a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,
a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,
a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,
- a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33],
- [a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,
+ a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33,
+ a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,
a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,
a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,
- a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33],
- [a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,
+ a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33,
+ a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,
a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,
a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,
- a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33]];
+ a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33);
};
/**
* Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
* assumes matrix entries are accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix4 = function(a, b) {
- 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];
- return [[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],
- [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],
- [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],
- [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]];
+ * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
+ */
+o3djs.flat_math.columnMajor.mulMatrixMatrix4 = function(a, b) {
+
+ 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];
+ return o3djs.flat_math.makeMatrix4(
+ 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,
+ 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,
+ 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,
+ 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);
};
/**
* Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
*/
-o3djs.math.mulMatrixMatrix4 = null;
+o3djs.flat_math.mulMatrixMatrix4 = null;
/**
* Multiplies two matrices; assumes that the sizes of the matrices are
* appropriately compatible; assumes matrix entries are accessed in
* [row][column] fashion.
- * @param {!o3djs.math.Matrix} a The matrix on the left.
- * @param {!o3djs.math.Matrix} b The matrix on the right.
- * @return {!o3djs.math.Matrix} The matrix product of a and b.
- */
-o3djs.math.rowMajor.mulMatrixMatrix = function(a, b) {
+ * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
+ */
+o3djs.flat_math.rowMajor.mulMatrixMatrix = function(a, b) {
+ switch(a.length) {
+ case 4:
+ return o3djs.flat_math.rowMajor.mulMatrixMatrix2(a,b);
+ case 9:
+ return o3djs.flat_math.rowMajor.mulMatrixMatrix3(a,b);
+ case 16:
+ return o3djs.flat_math.rowMajor.mulMatrixMatrix4(a,b);
+ default:
+ throw "Unable to handle irregular matrices or matrices of dim > 4 or < 2";
+ }
+ };
+
+o3djs.flat_math.rowMajor.generalizedMulMatrixMatrix= function(a, b) {
var r = [];
var aRows = a.length;
var bColumns = b[0].length;
@@ -1167,49 +1597,56 @@ o3djs.math.rowMajor.mulMatrixMatrix = function(a, b) {
* Multiplies two matrices; assumes that the sizes of the matrices are
* appropriately compatible; assumes matrix entries are accessed in
* [row][column] fashion.
- * @param {!o3djs.math.Matrix} a The matrix on the left.
- * @param {!o3djs.math.Matrix} b The matrix on the right.
- * @return {!o3djs.math.Matrix} The matrix product of a and b.
- */
-o3djs.math.columnMajor.mulMatrixMatrix = function(a, b) {
- var r = [];
- var bColumns = b.length;
- var aRows = a[0].length;
- var aColumns = a.length;
- for (var i = 0; i < bColumns; ++i) {
- var v = []; // v becomes a column of the answer.
- var bi = b[i]; // ith column of b.
- for (var j = 0; j < aRows; ++j) {
- v[j] = 0.0;
- for (var k = 0; k < aColumns; ++k)
- v[j] += bi[k] * a[k][j]; // kth column, jth row.
- }
- r[i] = v;
+ * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
+ */
+o3djs.flat_math.columnMajor.mulMatrixMatrix = function(a, b) {
+ switch(a.length) {
+ case 4:
+ return o3djs.flat_math.columnMajor.mulMatrixMatrix2(a,b);
+ case 9:
+ return o3djs.flat_math.columnMajor.mulMatrixMatrix3(a,b);
+ case 16:
+ return o3djs.flat_math.columnMajor.mulMatrixMatrix4(a,b);
+ default:
+ throw "Unable to handle irregular matrices or matrices of dim > 4 or < 2";
}
- return r;
};
/**
* Multiplies two matrices; assumes that the sizes of the matrices are
* appropriately compatible.
- * @param {!o3djs.math.Matrix} a The matrix on the left.
- * @param {!o3djs.math.Matrix} b The matrix on the right.
- * @return {!o3djs.math.Matrix} The matrix product of a and b.
+ * @param {!o3djs.flat_math.Matrix} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix} The matrix product of a and b.
*/
-o3djs.math.mulMatrixMatrix = null;
+o3djs.flat_math.mulMatrixMatrix = null;
/**
* Gets the jth column of the given matrix m; assumes matrix entries are
- * accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * accessed in [row*dimension+column] fashion.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} j The index of the desired column.
- * @return {!o3djs.math.Vector} The jth column of m as a vector.
+ * @return {!o3djs.flat_math.Vector} The jth column of m as a vector.
*/
-o3djs.math.rowMajor.column = function(m, j) {
- var r = [];
+o3djs.flat_math.rowMajor.column = function(m, j) {
var mLength = m.length;
- for (var i = 0; i < mLength; ++i) {
- r[i] = m[i][j];
+ var dimension;
+ switch (mLength){
+ case 4:
+ dimension = 2;
+ break;
+ case 9:
+ dimension = 3;
+ break;
+ case 16:
+ dimension = 4;
+ break;
+ }
+ var r = new o3djs.flat_math.Vector(dimension);
+ for (var i = 0; i < dimension; ++i) {
+ r[i] = m[i * dimension + j];
}
return r;
};
@@ -1217,85 +1654,110 @@ o3djs.math.rowMajor.column = function(m, j) {
/**
* Gets the jth column of the given matrix m; assumes matrix entries are
* accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} j The index of the desired column.
- * @return {!o3djs.math.Vector} The jth column of m as a vector.
+ * @return {!o3djs.flat_math.Vector} The jth column of m as a vector.
*/
-o3djs.math.columnMajor.column = function(m, j) {
- return m[j].slice();
+o3djs.flat_math.columnMajor.column = function(m, j) {
+ var dimension;
+ var mLength = m.length;
+ switch (mLength){
+ case 4:
+ dimension = 2;
+ break;
+ case 9:
+ dimension = 3;
+ break;
+ case 16:
+ dimension = 4;
+ break;
+ default:
+ dimension = Math.sqrt(dimension);
+ if (Math.round(dimension) * Math.round(dimension) != mLength) {
+ throw "Calling column on nonsquare matrix";
+ }
+ }
+ return m.slice(j * dimension, j * dimension + dimension);
};
/**
* Gets the jth column of the given matrix m.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} j The index of the desired column.
- * @return {!o3djs.math.Vector} The jth column of m as a vector.
+ * @return {!o3djs.flat_math.Vector} The jth column of m as a vector.
*/
-o3djs.math.column = null;
+o3djs.flat_math.column = null;
/**
* Gets the ith row of the given matrix m; assumes matrix entries are
* accessed in [row][column] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} i The index of the desired row.
- * @return {!o3djs.math.Vector} The ith row of m.
+ * @return {!o3djs.flat_math.Vector} The ith row of m.
*/
-o3djs.math.rowMajor.row = function(m, i) {
- return m[i].slice();
-};
+o3djs.flat_math.rowMajor.row = o3djs.flat_math.columnMajor.column;
/**
* Gets the ith row of the given matrix m; assumes matrix entries are
* accessed in [column][row] fashion.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} i The index of the desired row.
- * @return {!o3djs.math.Vector} The ith row of m.
+ * @return {!o3djs.flat_math.Vector} The ith row of m.
*/
-o3djs.math.columnMajor.row = function(m, i) {
- var r = [];
- var mLength = m.length;
- for (var j = 0; j < mLength; ++j) {
- r[j] = m[j][i];
- }
- return r;
-};
+o3djs.flat_math.columnMajor.row = o3djs.flat_math.rowMajor.column;
/**
* Gets the ith row of the given matrix m.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @param {number} i The index of the desired row.
- * @return {!o3djs.math.Vector} The ith row of m.
+ * @return {!o3djs.flat_math.Vector} The ith row of m.
*/
-o3djs.math.row = null;
+o3djs.flat_math.row = null;
/**
* Creates an n-by-n identity matrix.
* @param {number} n The dimension of the identity matrix required.
- * @return {!o3djs.math.Matrix} An n-by-n identity matrix.
+ * @return {!o3djs.flat_math.Matrix} An n-by-n identity matrix.
*/
-o3djs.math.identity = function(n) {
- var r = [];
+o3djs.flat_math.identity = function(n) {
+ var r = new o3djs.flat_math.Matrix(n*n);
+
for (var j = 0; j < n; ++j) {
- r[j] = [];
for (var i = 0; i < n; ++i)
- r[j][i] = (i == j) ? 1 : 0;
+ r[j * n + i] = (i == j) ? 1 : 0;
}
return r;
};
/**
* Takes the transpose of a matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} The transpose of m.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} The transpose of m.
*/
-o3djs.math.transpose = function(m) {
- var r = [];
- var m0Length = m[0].length;
+o3djs.flat_math.transpose = function(m) {
var mLength = m.length;
- for (var j = 0; j < m0Length; ++j) {
- r[j] = [];
- for (var i = 0; i < mLength; ++i)
- r[j][i] = m[i][j];
+ var r = new o3djs.flat_math.Matrix(mLength);
+ var dimension;
+ switch (mLength){
+ case 4:
+ dimension = 2;
+ break;
+ case 9:
+ dimension = 3;
+ break;
+ case 16:
+ dimension = 4;
+ break;
+ default:
+ dimension = Math.sqrt(dimension);
+ if (Math.round(dimension) * Math.round(dimension) != mLength) {
+ throw "Calling transpose on nonsquare matrix";
+ }
+ }
+
+ for (var j = 0; j < dimension; ++j) {
+ for (var i = 0; i < dimension; ++i)
+ r[j * dimension + i] = m[i * dimension + j];
}
return r;
};
@@ -1303,218 +1765,259 @@ o3djs.math.transpose = function(m) {
/**
* Computes the trace (sum of the diagonal entries) of a square matrix;
* assumes m is square.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @return {number} The trace of m.
*/
-o3djs.math.trace = function(m) {
+o3djs.flat_math.trace = function(m) {
var r = 0.0;
- var mLength = m.length;
+ var dimension;
+ switch (mLength){
+ case 4:
+ dimension = 2;
+ break;
+ case 9:
+ dimension = 3;
+ break;
+ case 16:
+ dimension = 4;
+ break;
+ }
+ var mLength = dimension;
for (var i = 0; i < mLength; ++i)
- r += m[i][i];
+ r += m[i * dimension + i];
return r;
};
/**
* Computes the determinant of a 1-by-1 matrix.
- * @param {!o3djs.math.Matrix1} m The matrix.
+ * @param {!o3djs.flat_math.Matrix1} m The matrix.
* @return {number} The determinant of m.
*/
-o3djs.math.det1 = function(m) {
- return m[0][0];
+o3djs.flat_math.det1 = function(m) {
+ return m[0];
};
/**
* Computes the determinant of a 2-by-2 matrix.
- * @param {!o3djs.math.Matrix2} m The matrix.
+ * @param {!o3djs.flat_math.Matrix2} m The matrix.
* @return {number} The determinant of m.
*/
-o3djs.math.det2 = function(m) {
- return m[0][0] * m[1][1] - m[0][1] * m[1][0];
+o3djs.flat_math.det2 = function(m) {
+ return m[0] * m[3] - m[1] * m[2];
};
/**
* Computes the determinant of a 3-by-3 matrix.
- * @param {!o3djs.math.Matrix3} m The matrix.
+ * @param {!o3djs.flat_math.Matrix3} m The matrix.
* @return {number} The determinant of m.
*/
-o3djs.math.det3 = function(m) {
- return m[2][2] * (m[0][0] * m[1][1] - m[0][1] * m[1][0]) -
- m[2][1] * (m[0][0] * m[1][2] - m[0][2] * m[1][0]) +
- m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]);
+o3djs.flat_math.det3 = function(m) {
+ return m[8] * (m[0 * 3] * m[4] - m[1] * m[1 * 3]) -
+ m[7] * (m[0 * 3] * m[5] - m[2] * m[1 * 3]) +
+ m[2 * 3] * (m[1] * m[5] - m[2] * m[4]);
};
/**
* Computes the determinant of a 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
* @return {number} The determinant of m.
*/
-o3djs.math.det4 = function(m) {
- var t01 = m[0][0] * m[1][1] - m[0][1] * m[1][0];
- var t02 = m[0][0] * m[1][2] - m[0][2] * m[1][0];
- var t03 = m[0][0] * m[1][3] - m[0][3] * m[1][0];
- var t12 = m[0][1] * m[1][2] - m[0][2] * m[1][1];
- var t13 = m[0][1] * m[1][3] - m[0][3] * m[1][1];
- var t23 = m[0][2] * m[1][3] - m[0][3] * m[1][2];
- return m[3][3] * (m[2][2] * t01 - m[2][1] * t02 + m[2][0] * t12) -
- m[3][2] * (m[2][3] * t01 - m[2][1] * t03 + m[2][0] * t13) +
- m[3][1] * (m[2][3] * t02 - m[2][2] * t03 + m[2][0] * t23) -
- m[3][0] * (m[2][3] * t12 - m[2][2] * t13 + m[2][1] * t23);
+o3djs.flat_math.det4 = function(m) {
+ var t01 = m[0] * m[5] - m[1] * m[4];
+ var t02 = m[0] * m[6] - m[2] * m[4];
+ var t03 = m[0] * m[7] - m[3] * m[4];
+ var t12 = m[1] * m[6] - m[2] * m[5];
+ var t13 = m[1] * m[7] - m[3] * m[5];
+ var t23 = m[2] * m[7] - m[3] * m[6];
+ return m[15] * (m[10] * t01 - m[9] * t02 + m[8] * t12) -
+ m[14] * (m[11] * t01 - m[9] * t03 + m[8] * t13) +
+ m[13] * (m[11] * t02 - m[10] * t03 + m[8] * t23) -
+ m[12] * (m[11] * t12 - m[10] * t13 + m[9] * t23);
};
/**
* Computes the inverse of a 1-by-1 matrix.
- * @param {!o3djs.math.Matrix1} m The matrix.
- * @return {!o3djs.math.Matrix1} The inverse of m.
+ * @param {!o3djs.flat_math.Matrix1} m The matrix.
+ * @return {!o3djs.flat_math.Matrix1} The inverse of m.
*/
-o3djs.math.inverse1 = function(m) {
- return [[1.0 / m[0][0]]];
+o3djs.flat_math.inverse1 = function(m) {
+ var retval = new o3djs.flat_math.Matrix(1);
+ retval[0] = 1.0 / m[0];
+ return retval;
};
/**
* Computes the inverse of a 2-by-2 matrix.
- * @param {!o3djs.math.Matrix2} m The matrix.
- * @return {!o3djs.math.Matrix2} The inverse of m.
+ * @param {!o3djs.flat_math.Matrix2} m The matrix.
+ * @return {!o3djs.flat_math.Matrix2} The inverse of m.
*/
-o3djs.math.inverse2 = function(m) {
- var d = 1.0 / (m[0][0] * m[1][1] - m[0][1] * m[1][0]);
- return [[d * m[1][1], -d * m[0][1]], [-d * m[1][0], d * m[0][0]]];
+o3djs.flat_math.inverse2 = function(m) {
+ var d = 1.0 / (m[0] * m[3] - m[1] * m[2]);
+ return o3djs.flat_math.makeMatrix2(d * m[3], -d * m[1],
+ -d * m[2], d * m[0]);
};
/**
* Computes the inverse of a 3-by-3 matrix.
- * @param {!o3djs.math.Matrix3} m The matrix.
- * @return {!o3djs.math.Matrix3} The inverse of m.
+ * @param {!o3djs.flat_math.Matrix3} m The matrix.
+ * @return {!o3djs.flat_math.Matrix3} The inverse of m.
*/
-o3djs.math.inverse3 = function(m) {
- var t00 = m[1][1] * m[2][2] - m[1][2] * m[2][1];
- var t10 = m[0][1] * m[2][2] - m[0][2] * m[2][1];
- var t20 = m[0][1] * m[1][2] - m[0][2] * m[1][1];
- var d = 1.0 / (m[0][0] * t00 - m[1][0] * t10 + m[2][0] * t20);
- return [[d * t00, -d * t10, d * t20],
- [-d * (m[1][0] * m[2][2] - m[1][2] * m[2][0]),
- d * (m[0][0] * m[2][2] - m[0][2] * m[2][0]),
- -d * (m[0][0] * m[1][2] - m[0][2] * m[1][0])],
- [d * (m[1][0] * m[2][1] - m[1][1] * m[2][0]),
- -d * (m[0][0] * m[2][1] - m[0][1] * m[2][0]),
- d * (m[0][0] * m[1][1] - m[0][1] * m[1][0])]];
+o3djs.flat_math.inverse3 = function(m) {
+ var t00 = m[4] * m[8] - m[5] * m[7];
+ var t10 = m[1] * m[8] - m[2] * m[7];
+ var t20 = m[1] * m[5] - m[2] * m[4];
+ var d = 1.0 / (m[0] * t00 - m[3] * t10 + m[6] * t20);
+ return o3djs.flat_math.makeMatrix3(d * t00, -d * t10, d * t20,
+ -d * (m[3] * m[8] - m[5] * m[6]),
+ d * (m[0] * m[8] - m[2] * m[6]),
+ -d * (m[0] * m[5] - m[2] * m[3]),
+ d * (m[3] * m[7] - m[4] * m[6]),
+ -d * (m[0] * m[7] - m[1] * m[6]),
+ d * (m[0] * m[4] - m[1] * m[3]));
};
/**
* Computes the inverse of a 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix4} The inverse of m.
- */
-o3djs.math.inverse4 = function(m) {
- var tmp_0 = m[2][2] * m[3][3];
- var tmp_1 = m[3][2] * m[2][3];
- var tmp_2 = m[1][2] * m[3][3];
- var tmp_3 = m[3][2] * m[1][3];
- var tmp_4 = m[1][2] * m[2][3];
- var tmp_5 = m[2][2] * m[1][3];
- var tmp_6 = m[0][2] * m[3][3];
- var tmp_7 = m[3][2] * m[0][3];
- var tmp_8 = m[0][2] * m[2][3];
- var tmp_9 = m[2][2] * m[0][3];
- var tmp_10 = m[0][2] * m[1][3];
- var tmp_11 = m[1][2] * m[0][3];
- var tmp_12 = m[2][0] * m[3][1];
- var tmp_13 = m[3][0] * m[2][1];
- var tmp_14 = m[1][0] * m[3][1];
- var tmp_15 = m[3][0] * m[1][1];
- var tmp_16 = m[1][0] * m[2][1];
- var tmp_17 = m[2][0] * m[1][1];
- var tmp_18 = m[0][0] * m[3][1];
- var tmp_19 = m[3][0] * m[0][1];
- var tmp_20 = m[0][0] * m[2][1];
- var tmp_21 = m[2][0] * m[0][1];
- var tmp_22 = m[0][0] * m[1][1];
- var tmp_23 = m[1][0] * m[0][1];
-
- var t0 = (tmp_0 * m[1][1] + tmp_3 * m[2][1] + tmp_4 * m[3][1]) -
- (tmp_1 * m[1][1] + tmp_2 * m[2][1] + tmp_5 * m[3][1]);
- var t1 = (tmp_1 * m[0][1] + tmp_6 * m[2][1] + tmp_9 * m[3][1]) -
- (tmp_0 * m[0][1] + tmp_7 * m[2][1] + tmp_8 * m[3][1]);
- var t2 = (tmp_2 * m[0][1] + tmp_7 * m[1][1] + tmp_10 * m[3][1]) -
- (tmp_3 * m[0][1] + tmp_6 * m[1][1] + tmp_11 * m[3][1]);
- var t3 = (tmp_5 * m[0][1] + tmp_8 * m[1][1] + tmp_11 * m[2][1]) -
- (tmp_4 * m[0][1] + tmp_9 * m[1][1] + tmp_10 * m[2][1]);
-
- var d = 1.0 / (m[0][0] * t0 + m[1][0] * t1 + m[2][0] * t2 + m[3][0] * t3);
-
- var row0 = [d * t0, d * t1, d * t2, d * t3];
- var row1 = [d * ((tmp_1 * m[1][0] + tmp_2 * m[2][0] + tmp_5 * m[3][0]) -
- (tmp_0 * m[1][0] + tmp_3 * m[2][0] + tmp_4 * m[3][0])),
- d * ((tmp_0 * m[0][0] + tmp_7 * m[2][0] + tmp_8 * m[3][0]) -
- (tmp_1 * m[0][0] + tmp_6 * m[2][0] + tmp_9 * m[3][0])),
- d * ((tmp_3 * m[0][0] + tmp_6 * m[1][0] + tmp_11 * m[3][0]) -
- (tmp_2 * m[0][0] + tmp_7 * m[1][0] + tmp_10 * m[3][0])),
- d * ((tmp_4 * m[0][0] + tmp_9 * m[1][0] + tmp_10 * m[2][0]) -
- (tmp_5 * m[0][0] + tmp_8 * m[1][0] + tmp_11 * m[2][0]))];
- var row2 =[d * ((tmp_12 * m[1][3] + tmp_15 * m[2][3] + tmp_16 * m[3][3]) -
- (tmp_13 * m[1][3] + tmp_14 * m[2][3] + tmp_17 * m[3][3])),
- d * ((tmp_13 * m[0][3] + tmp_18 * m[2][3] + tmp_21 * m[3][3]) -
- (tmp_12 * m[0][3] + tmp_19 * m[2][3] + tmp_20 * m[3][3])),
- d * ((tmp_14 * m[0][3] + tmp_19 * m[1][3] + tmp_22 * m[3][3]) -
- (tmp_15 * m[0][3] + tmp_18 * m[1][3] + tmp_23 * m[3][3])),
- d * ((tmp_17 * m[0][3] + tmp_20 * m[1][3] + tmp_23 * m[2][3]) -
- (tmp_16 * m[0][3] + tmp_21 * m[1][3] + tmp_22 * m[2][3]))];
- var row3 = [d * ((tmp_14 * m[2][2] + tmp_17 * m[3][2] + tmp_13 * m[1][2]) -
- (tmp_16 * m[3][2] + tmp_12 * m[1][2] + tmp_15 * m[2][2])),
- d * ((tmp_20 * m[3][2] + tmp_12 * m[0][2] + tmp_19 * m[2][2]) -
- (tmp_18 * m[2][2] + tmp_21 * m[3][2] + tmp_13 * m[0][2])),
- d * ((tmp_18 * m[1][2] + tmp_23 * m[3][2] + tmp_15 * m[0][2]) -
- (tmp_22 * m[3][2] + tmp_14 * m[0][2] + tmp_19 * m[1][2])),
- d * ((tmp_22 * m[2][2] + tmp_16 * m[0][2] + tmp_21 * m[1][2]) -
- (tmp_20 * m[1][2] + tmp_23 * m[2][2] + tmp_17 * m[0][2]))];
- return [row0, row1, row2, row3];
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @return {!o3djs.flat_math.Matrix4} The inverse of m.
+ */
+o3djs.flat_math.inverse4 = function(m) {
+ var tmp_0 = m[10] * m[15];
+ var tmp_1 = m[14] * m[11];
+ var tmp_2 = m[6] * m[15];
+ var tmp_3 = m[14] * m[7];
+ var tmp_4 = m[6] * m[11];
+ var tmp_5 = m[10] * m[7];
+ var tmp_6 = m[2] * m[15];
+ var tmp_7 = m[14] * m[3];
+ var tmp_8 = m[2] * m[11];
+ var tmp_9 = m[10] * m[3];
+ var tmp_10 = m[2] * m[7];
+ var tmp_11 = m[6] * m[3];
+ var tmp_12 = m[8] * m[13];
+ var tmp_13 = m[12] * m[9];
+ var tmp_14 = m[4] * m[13];
+ var tmp_15 = m[12] * m[5];
+ var tmp_16 = m[4] * m[9];
+ var tmp_17 = m[8] * m[5];
+ var tmp_18 = m[0] * m[13];
+ var tmp_19 = m[12] * m[1];
+ var tmp_20 = m[0] * m[9];
+ var tmp_21 = m[8] * m[1];
+ var tmp_22 = m[0] * m[5];
+ var tmp_23 = m[4] * m[1];
+
+ var t0 = tmp_0 * m[5] + tmp_3 * m[9] + tmp_4 * m[13] -
+ (tmp_1 * m[5] + tmp_2 * m[9] + tmp_5 * m[13]);
+ var t1 = tmp_1 * m[1] + tmp_6 * m[9] + tmp_9 * m[13] -
+ (tmp_0 * m[1] + tmp_7 * m[9] + tmp_8 * m[13]);
+ var t2 = tmp_2 * m[1] + tmp_7 * m[5] + tmp_10 * m[13] -
+ (tmp_3 * m[1] + tmp_6 * m[5] + tmp_11 * m[13]);
+ var t3 = (tmp_5 * m[1] + tmp_8 * m[5] + tmp_11 * m[9]) -
+ (tmp_4 * m[1] + tmp_9 * m[5] + tmp_10 * m[9]);
+
+ var d = 1.0 / (m[0] * t0 + m[1 * 4] * t1 + m[8] * t2 + m[12] * t3);
+
+ return o3djs.flat_math.makeMatrix4(d * t0, d * t1, d * t2, d * t3,
+ d * ((tmp_1 * m[1 * 4] + tmp_2 * m[8] + tmp_5 * m[12]) -
+ (tmp_0 * m[1 * 4] + tmp_3 * m[8] + tmp_4 * m[12])),
+ d * ((tmp_0 * m[0 * 4] + tmp_7 * m[8] + tmp_8 * m[12]) -
+ (tmp_1 * m[0 * 4] + tmp_6 * m[8] + tmp_9 * m[12])),
+ d * ((tmp_3 * m[0 * 4] + tmp_6 * m[1 * 4] + tmp_11 * m[12]) -
+ (tmp_2 * m[0 * 4] + tmp_7 * m[1 * 4] + tmp_10 * m[12])),
+ d * ((tmp_4 * m[0 * 4] + tmp_9 * m[1 * 4] + tmp_10 * m[8]) -
+ (tmp_5 * m[0 * 4] + tmp_8 * m[1 * 4] + tmp_11 * m[8])),
+ d * ((tmp_12 * m[4 + 3] + tmp_15 * m[11] + tmp_16 * m[15]) -
+ (tmp_13 * m[4 + 3] + tmp_14 * m[11] + tmp_17 * m[15])),
+ d * ((tmp_13 * m[3] + tmp_18 * m[11] + tmp_21 * m[15]) -
+ (tmp_12 * m[3] + tmp_19 * m[11] + tmp_20 * m[15])),
+ d * ((tmp_14 * m[3] + tmp_19 * m[7] + tmp_22 * m[15]) -
+ (tmp_15 * m[3] + tmp_18 * m[7] + tmp_23 * m[15])),
+ d * ((tmp_17 * m[3] + tmp_20 * m[7] + tmp_23 * m[11]) -
+ (tmp_16 * m[3] + tmp_21 * m[7] + tmp_22 * m[11])),
+ d * ((tmp_14 * m[10] + tmp_17 * m[14] + tmp_13 * m[4 + 2]) -
+ (tmp_16 * m[14] + tmp_12 * m[4 + 2] + tmp_15 * m[10])),
+ d * ((tmp_20 * m[14] + tmp_12 * m[2] + tmp_19 * m[10]) -
+ (tmp_18 * m[10] + tmp_21 * m[14] + tmp_13 * m[2])),
+ d * ((tmp_18 * m[6] + tmp_23 * m[14] + tmp_15 * m[2]) -
+ (tmp_22 * m[14] + tmp_14 * m[2] + tmp_19 * m[6])),
+ d * ((tmp_22 * m[10] + tmp_16 * m[2] + tmp_21 * m[6]) -
+ (tmp_20 * m[6] + tmp_23 * m[10] + tmp_17 * m[2])));
};
/**
* Computes the determinant of the cofactor matrix obtained by removal
* of a specified row and column. This is a helper function for the general
* determinant and matrix inversion functions.
- * @param {!o3djs.math.Matrix} a The original matrix.
+ * @param {!o3djs.flat_math.Matrix} a The original matrix.
* @param {number} x The row to be removed.
* @param {number} y The column to be removed.
* @return {number} The determinant of the matrix obtained by removing
* row x and column y from a.
*/
-o3djs.math.codet = function(a, x, y) {
- var size = a.length;
- var b = [];
+o3djs.flat_math.codet = function(a, x, y) {
+ var aLength = a.length;
+ var size;
+ switch (aLength) {
+ case 4:
+ size = 2;
+ break;
+ case 9:
+ size = 3;
+ break;
+ case 16:
+ size = 4;
+ break;
+ default:
+ size=Math.sqrt(aLength);
+ if (Math.round(size) * Math.round(size) != aLength) {
+ throw "Calling codet on nonsquare matrix";
+ }
+ }
+ var b = new o3djs.flat_math.Matrix(aLength);
var ai = 0;
for (var bi = 0; bi < size - 1; ++bi) {
if (ai == x)
ai++;
- b[bi] = [];
var aj = 0;
for (var bj = 0; bj < size - 1; ++bj) {
if (aj == y)
aj++;
- b[bi][bj] = a[ai][aj];
+ b[bi*size+bj] = a[ai*size+aj];
aj++;
}
ai++;
}
- return o3djs.math.det(b);
+ return o3djs.flat_math.det(b);
};
/**
* Computes the determinant of an arbitrary square matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
* @return {number} the determinant of m.
*/
-o3djs.math.det = function(m) {
+o3djs.flat_math.det = function(m) {
var d = m.length;
- if (d <= 4) {
- return o3djs.math['det' + d](m);
+ switch (d) {
+ case 4:
+ return o3djs.flat_math.det2(m);
+ case 9:
+ return o3djs.flat_math.det3(m);
+ case 16:
+ return o3djs.flat_math.det4(m);
+ default:
+ d = Math.sqrt(d);
+ if (Math.round(d) * Math.round(d) != m.length) {
+ throw "Calling det on nonsquare matrix";
+ }
+ break;
}
var r = 0.0;
var sign = 1;
- var row = m[0];
+ var row = m;
var mLength = m.length;
for (var y = 0; y < mLength; y++) {
- r += sign * row[y] * o3djs.math.codet(m, 0, y);
+ r += sign * m[0] * o3djs.flat_math.codet(m, 0, y);
sign *= -1;
}
return r;
@@ -1522,22 +2025,34 @@ o3djs.math.det = function(m) {
/**
* Computes the inverse of an arbitrary square matrix.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} The inverse of m.
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} The inverse of m.
*/
-o3djs.math.inverse = function(m) {
+o3djs.flat_math.inverse = function(m) {
var d = m.length;
- if (d <= 4) {
- return o3djs.math['inverse' + d](m);
+ switch (d) {
+ case 4:
+ return o3djs.flat_math.inverse2(m);
+ case 9:
+ return o3djs.flat_math.inverse3(m);
+ case 16:
+ return o3djs.flat_math.inverse4(m);
+ default:
+ d = Math.sqrt(d);
+ if (Math.round(d) * Math.round(d) != m.length) {
+ throw "Calling inverse on nonsquare matrix";
+ }
+ break;
}
- var r = [];
+ var r = new o3djs.flat_math.Matrix(m.length);
var size = m.length;
+ var det = o3djs.flat_math.det(m);
for (var j = 0; j < size; ++j) {
- r[j] = [];
for (var i = 0; i < size; ++i)
- r[j][i] = ((i + j) % 2 ? -1 : 1) * o3djs.math.codet(m, i, j);
+ r[j * d + i] =
+ ((i + j) % 2 ? -1 : 1) * o3djs.flat_math.codet(m, i, j) / det;
}
- return o3djs.math.divMatrixScalar(r, o3djs.math.det(m));
+ return r;
};
/**
@@ -1546,80 +2061,99 @@ o3djs.math.inverse = function(m) {
* multiplying many orthogonal matrices together, errors can accumulate causing
* the product to fail to be orthogonal. This function can be used to correct
* that.
- * @param {!o3djs.math.Matrix} m The matrix.
- * @return {!o3djs.math.Matrix} A matrix whose rows are obtained from the
+ * @param {!o3djs.flat_math.Matrix} m The matrix.
+ * @return {!o3djs.flat_math.Matrix} A matrix whose rows are obtained from the
* rows of m by the Graham-Schmidt process.
*/
-o3djs.math.orthonormalize = function(m) {
- var r = [];
- var mLength = m.length;
- for (var i = 0; i < mLength; ++i) {
- var v = m[i];
+o3djs.flat_math.orthonormalize = function(m) {
+ var d = m.length;
+ var r = new o3djs.flat_math.Matrix(d);
+ switch (d) {
+ case 4:
+ d = 2; break;
+ case 9:
+ d = 3; break;
+ case 16:
+ d = 4; break;
+ default:
+ d = Math.sqrt(d);
+ if (Math.round(d) * Math.round(d) != m.length) {
+ throw "Calling orthonormalize on nonsquare matrix";
+ }
+ break;
+ }
+ for (var i = 0; i < d; ++i) {
+ var v = m.slice(i*d,i*d+d);
for (var j = 0; j < i; ++j) {
- v = o3djs.math.subVector(v, o3djs.math.mulScalarVector(
- o3djs.math.dot(r[j], m[i]), r[j]));
+ v = o3djs.flat_math.subVector(v, o3djs.flat_math.mulScalarVector(
+ o3djs.flat_math.dot(r[j], v), r[j]));
+ }
+ var ri = o3djs.flat_math.normalize(v);
+ for (var k = 0; k < d; ++ k) {
+ r[i * d +k ] = ri[k];
}
- r[i] = o3djs.math.normalize(v);
}
return r;
};
/**
* Computes the inverse of a 4-by-4 matrix.
- * Note: It is faster to call this than o3djs.math.inverse.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix4} The inverse of m.
+ * Note: It is faster to call this than o3djs.flat_math.inverse.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @return {!o3djs.flat_math.Matrix4} The inverse of m.
*/
-o3djs.math.matrix4.inverse = function(m) {
- return o3djs.math.inverse4(m);
+o3djs.flat_math.matrix4.inverse = function(m) {
+ return o3djs.flat_math.inverse4(m);
};
/**
* Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
- * Note: It is faster to call this than o3djs.math.mul.
- * @param {!o3djs.math.Matrix4} a The matrix on the left.
- * @param {!o3djs.math.Matrix4} b The matrix on the right.
- * @return {!o3djs.math.Matrix4} The matrix product of a and b.
+ * Note: It is faster to call this than o3djs.flat_math.mul.
+ * @param {!o3djs.flat_math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.flat_math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.flat_math.Matrix4} The matrix product of a and b.
*/
-o3djs.math.matrix4.mul = function(a, b) {
- return o3djs.math.mulMatrixMatrix4(a, b);
+o3djs.flat_math.matrix4.mul = function(a, b) {
+ return o3djs.flat_math.mulMatrixMatrix4(a, b);
};
/**
* Computes the determinant of a 4-by-4 matrix.
- * Note: It is faster to call this than o3djs.math.det.
- * @param {!o3djs.math.Matrix4} m The matrix.
+ * Note: It is faster to call this than o3djs.flat_math.det.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
* @return {number} The determinant of m.
*/
-o3djs.math.matrix4.det = function(m) {
- return o3djs.math.det4(m);
+o3djs.flat_math.matrix4.det = function(m) {
+ return o3djs.flat_math.det4(m);
};
/**
* Copies a Matrix4.
- * Note: It is faster to call this than o3djs.math.copy.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix4} A copy of m.
+ * Note: It is faster to call this than o3djs.flat_math.copy.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @return {!o3djs.flat_math.Matrix4} A copy of m.
*/
-o3djs.math.matrix4.copy = function(m) {
- return o3djs.math.copyMatrix(m);
+o3djs.flat_math.matrix4.copy = function(m) {
+ return o3djs.flat_math.copyMatrix(m);
};
/**
* Sets the upper 3-by-3 block of matrix a to the upper 3-by-3 block of matrix
* b; assumes that a and b are big enough to contain an upper 3-by-3 block.
- * @param {!o3djs.math.Matrix4} a A matrix.
- * @param {!o3djs.math.Matrix3} b A 3-by-3 matrix.
- * @return {!o3djs.math.Matrix4} a once modified.
- */
-o3djs.math.matrix4.setUpper3x3 = function(a, b) {
- var b0 = b[0];
- var b1 = b[1];
- var b2 = b[2];
-
- a[0].splice(0, 3, b0[0], b0[1], b0[2]);
- a[1].splice(0, 3, b1[0], b1[1], b1[2]);
- a[2].splice(0, 3, b2[0], b2[1], b2[2]);
+ * @param {!o3djs.flat_math.Matrix4} a A matrix.
+ * @param {!o3djs.flat_math.Matrix3} b A 3-by-3 matrix.
+ * @return {!o3djs.flat_math.Matrix4} a once modified.
+ */
+o3djs.flat_math.matrix4.setUpper3x3 = function(a, b) {
+ a[0] = b[0];
+ a[1] = b[1];
+ a[2] = b[2];
+ a[4] = b[4];
+ a[5] = b[5];
+ a[6] = b[6];
+ a[8] = b[8];
+ a[9] = b[9];
+ a[10] = b[10];
return a;
};
@@ -1627,80 +2161,107 @@ o3djs.math.matrix4.setUpper3x3 = function(a, b) {
/**
* Returns a 3-by-3 matrix mimicking the upper 3-by-3 block of m; assumes m
* is big enough to contain an upper 3-by-3 block.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Matrix3} The upper 3-by-3 block of m.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @return {!o3djs.flat_math.Matrix3} The upper 3-by-3 block of m.
*/
-o3djs.math.matrix4.getUpper3x3 = function(m) {
- return [m[0].slice(0, 3), m[1].slice(0, 3), m[2].slice(0, 3)];
+o3djs.flat_math.matrix4.getUpper3x3 = function(m) {
+ return o3djs.flat_math.makeMatrix3(
+ m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10]);
};
/**
* Sets the translation component of a 4-by-4 matrix to the given
* vector.
- * @param {!o3djs.math.Matrix4} a The matrix.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector.
- * @return {!o3djs.math.Matrix4} a once modified.
- */
-o3djs.math.matrix4.setTranslation = function(a, v) {
- a[3].splice(0, 4, v[0], v[1], v[2], 1);
+ * @param {!o3djs.flat_math.Matrix4} a The matrix.
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} v The vector.
+ * @return {!o3djs.flat_math.Matrix4} a once modified.
+ */
+o3djs.flat_math.matrix4.setTranslation = function(a, v) {
+ a[12] = v[0];
+ a[13] = v[1];
+ a[14] = v[2];
return a;
};
/**
* Returns the translation component of a 4-by-4 matrix as a vector with 3
* entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @return {!o3djs.math.Vector3} The translation component of m.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @return {!o3djs.flat_math.Vector3} The translation component of m.
*/
-o3djs.math.matrix4.getTranslation = function(m) {
- return m[3].slice(0, 3);
+o3djs.flat_math.matrix4.getTranslation = function(m) {
+ var retval =new o3djs.flat_math.Vector(3);
+ retval[0] = m[12];
+ retval[1] = m[13];
+ retval[2] = m[14];
+ return retval;
};
/**
* 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.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Vector3} v The point.
+ * @return {!o3djs.flat_math.Vector3} The transformed point.
*/
-o3djs.math.matrix4.transformPoint = function(m, v) {
+o3djs.flat_math.matrix4.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];
+ var d = v0 * m[3] +
+ v1 * m[7] +
+ v2 * m[11] +
+ m[15];
+ var retval = new o3djs.flat_math.Vector(3);
+ retval[0] = (v0 * m[0] +
+ v1 * m[4] +
+ v2 * m[8] +
+ m[12]) / d;
+ retval[1] = (v0 * m[1] +
+ v1 * m[5] +
+ v2 * m[9] +
+ m[13]) / d;
+ retval[2] = (v0 * m[2] +
+ v1 * m[6] +
+ v2 * m[10] +
+ m[14]) / d;
+ return retval;
};
/**
* Takes a 4-by-4 matrix and a vector with 4 entries, transforms that vector 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 point in homogenous coordinates.
- * @return {!o3djs.math.Vector4} The transformed point in homogenous
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Vector4} v The point in homogenous coordinates.
+ * @return {!o3djs.flat_math.Vector4} The transformed point in homogenous
* coordinates.
*/
-o3djs.math.matrix4.transformVector4 = function(m, v) {
+o3djs.flat_math.matrix4.transformVector4 = 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]];
+ return [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]];
};
/**
@@ -1710,22 +2271,24 @@ o3djs.math.matrix4.transformVector4 = function(m, v) {
* is parallel-preserving, i.e. any combination of rotation, scaling and
* translation, but not a perspective distortion. Returns a vector with 3
* entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The direction.
- * @return {!o3djs.math.Vector3} The transformed direction.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Vector3} v The direction.
+ * @return {!o3djs.flat_math.Vector3} The transformed direction.
*/
-o3djs.math.matrix4.transformDirection = function(m, v) {
+o3djs.flat_math.matrix4.transformDirection = 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[0] + v1 * m1[0] + v2 * m2[0],
- v0 * m0[1] + v1 * m1[1] + v2 * m2[1],
- v0 * m0[2] + v1 * m1[2] + v2 * m2[2]];
+ return [v0 * m[0] +
+ v1 * m[4] +
+ v2 * m[8],
+ v0 * m[1] +
+ v1 * m[5] +
+ v2 * m[9],
+ v0 * m[2] +
+ v1 * m[6] +
+ v2 * m[10]];
};
/**
@@ -1737,50 +2300,49 @@ o3djs.math.matrix4.transformDirection = function(m, v) {
* matrix is parallel-preserving, i.e. any combination of rotation, scaling and
* translation, but not a perspective distortion. Returns a vector with 3
* entries.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v The normal.
- * @return {!o3djs.math.Vector3} The transformed normal.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Vector3} v The normal.
+ * @return {!o3djs.flat_math.Vector3} The transformed normal.
*/
-o3djs.math.matrix4.transformNormal = function(m, v) {
- var mInverse = o3djs.math.inverse4(m);
+o3djs.flat_math.matrix4.transformNormal = function(m, v) {
+ var mInverse = o3djs.flat_math.inverse4(m);
var v0 = v[0];
var v1 = v[1];
var v2 = v[2];
- var mi0 = mInverse[0];
- var mi1 = mInverse[1];
- var mi2 = mInverse[2];
- var mi3 = mInverse[3];
- return [v0 * mi0[0] + v1 * mi0[1] + v2 * mi0[2],
- v0 * mi1[0] + v1 * mi1[1] + v2 * mi1[2],
- v0 * mi2[0] + v1 * mi2[1] + v2 * mi2[2]];
+ return [v0 * mInverse[0] + v1 * mInverse[1] + v2 * mInverse[2],
+ v0 * mInverse[4] +
+ v1 * mInverse[5] +
+ v2 * mInverse[6],
+ v0 * mInverse[8] +
+ v1 * mInverse[9] +
+ v2 * mInverse[10]];
};
/**
* Creates a 4-by-4 identity matrix.
- * @return {!o3djs.math.Matrix4} The 4-by-4 identity.
+ * @return {!o3djs.flat_math.Matrix4} The 4-by-4 identity.
*/
-o3djs.math.matrix4.identity = function() {
- return [
- [1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0],
- [0, 0, 0, 1]
- ];
+o3djs.flat_math.matrix4.identity = function() {
+ return o3djs.flat_math.makeMatrix4(
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1);
};
/**
* Sets the given 4-by-4 matrix to the identity matrix.
- * @param {!o3djs.math.Matrix4} m The matrix to set to identity.
- * @return {!o3djs.math.Matrix4} m once modified.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix to set to identity.
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
*/
-o3djs.math.matrix4.setIdentity = function(m) {
+o3djs.flat_math.matrix4.setIdentity = function(m) {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (i == j) {
- m[i][j] = 1;
+ m[i * 4 + j] = 1;
} else {
- m[i][j] = 0;
+ m[i * 4 + j] = 0;
}
}
}
@@ -1804,18 +2366,18 @@ o3djs.math.matrix4.setIdentity = function(m) {
* of the near clipping plane.
* @param {number} far The depth (negative z coordinate)
* of the far clipping plane.
- * @return {!o3djs.math.Matrix4} The perspective matrix.
+ * @return {!o3djs.flat_math.Matrix4} The perspective matrix.
*/
-o3djs.math.matrix4.perspective = function(angle, aspect, near, far) {
+o3djs.flat_math.matrix4.perspective = function(angle, aspect, near, far) {
var f = Math.tan(0.5 * (Math.PI - angle));
var range = near - far;
- return [
- [f / aspect, 0, 0, 0],
- [0, f, 0, 0],
- [0, 0, far / range, -1],
- [0, 0, near * far / range, 0]
- ];
+ return o3djs.flat_math.makeMatrix4 (
+ f / aspect, 0, 0, 0,
+ 0, f, 0, 0,
+ 0, 0, 2 * far / range + 1, -1,
+ 0, 0, 2 * near * far / range, 0
+ );
};
/**
@@ -1832,18 +2394,17 @@ o3djs.math.matrix4.perspective = function(angle, aspect, near, far) {
* @param {number} top The y coordinate of the right plane of the box.
* @param {number} near The negative z coordinate of the near plane of the box.
* @param {number} far The negative z coordinate of the far plane of the box.
- * @return {!o3djs.math.Matrix4} The orthographic projection matrix.
+ * @return {!o3djs.flat_math.Matrix4} The orthographic projection matrix.
*/
-o3djs.math.matrix4.orthographic =
+o3djs.flat_math.matrix4.orthographic =
function(left, right, bottom, top, near, far) {
- return [
- [2 / (right - left), 0, 0, 0],
- [0, 2 / (top - bottom), 0, 0],
- [0, 0, 1 / (near - far), 0],
- [(left + right) / (left - right),
- (bottom + top) / (bottom - top),
- near / (near - far), 1]
- ];
+ return o3djs.flat_math.makeMatrix4 (
+ 2 / (right - left), 0, 0, 0,
+ 0, 2 / (top - bottom), 0, 0,
+ 0, 0, 2 / (near - far), 0,
+ (left + right) / (left - right),
+ (bottom + top) / (bottom - top),
+ (near + far) / (near - far), 1);
};
/**
@@ -1861,17 +2422,17 @@ o3djs.math.matrix4.orthographic =
* @param {number} top The y coordinate of the right plane of the box.
* @param {number} near The negative z coordinate of the near plane of the box.
* @param {number} far The negative z coordinate of the far plane of the box.
- * @return {!o3djs.math.Matrix4} The perspective projection matrix.
+ * @return {!o3djs.flat_math.Matrix4} The perspective projection matrix.
*/
-o3djs.math.matrix4.frustum = function(left, right, bottom, top, near, far) {
+o3djs.flat_math.matrix4.frustum = function(left, right, bottom, top, near, far) {
var dx = (right - left);
var dy = (top - bottom);
var dz = (near - far);
- return [
- [2 * near / dx, 0, 0, 0],
- [0, 2 * near / dy, 0, 0],
- [(left + right) / dx, (top + bottom) / dy, far / dz, -1],
- [0, 0, near * far / dz, 0]];
+ return o3djs.flat_math.makeMatrix4(
+ 2 * near / dx, 0, 0, 0,
+ 0, 2 * near / dy, 0, 0,
+ (left + right) / dx, (top + bottom) / dy, far / dz, -1,
+ 0, 0, near * far / dz, 0);
};
/**
@@ -1881,22 +2442,25 @@ o3djs.math.matrix4.frustum = function(left, right, bottom, top, near, far) {
* vector pointing from the eye to the target to a vector pointing in the
* negative z direction, and also sends the up vector into the upper half of
* the yz plane.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} eye The position
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} eye The position
* of the eye.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} target The
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} target The
* position meant to be viewed.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} up A vector
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} up A vector
* pointing up.
- * @return {!o3djs.math.Matrix4} The look-at matrix.
+ * @return {!o3djs.flat_math.Matrix4} The look-at matrix.
*/
-o3djs.math.matrix4.lookAt = function(eye, target, up) {
- var vz = o3djs.math.normalize(
- o3djs.math.subVector(eye, target).slice(0, 3)).concat(0);
- var vx = o3djs.math.normalize(
- o3djs.math.cross(up, vz)).concat(0);
- var vy = o3djs.math.cross(vz, vx).concat(0);
-
- return o3djs.math.inverse([vx, vy, vz, eye.concat(1)]);
+o3djs.flat_math.matrix4.lookAt = function(eye, target, up) {
+ var vz = o3djs.flat_math.normalize(
+ o3djs.flat_math.subVector(eye, target).slice(0, 3));
+ var vx = o3djs.flat_math.normalize(
+ o3djs.flat_math.cross(up, vz));
+ var vy = o3djs.flat_math.cross(vz, vx);
+ return o3djs.flat_math.inverse4(o3djs.flat_math.makeMatrix4(
+ vx[0], vx[1], vx[2], 0,
+ vy[0], vy[1], vy[2], 0,
+ vz[0], vz[1], vz[2], 0,
+ eye[0], eye[1], eye[2], 1));
};
/**
@@ -1905,67 +2469,60 @@ o3djs.math.matrix4.lookAt = function(eye, target, up) {
* transform by b first and then a. Note this is subtly different from just
* multiplying the matrices together. For given a and b, this function returns
* the same object in both row-major and column-major mode.
- * @param {!o3djs.math.Matrix4} a A 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} b A 4-by-4 matrix.
- * @return {!o3djs.math.Matrix4} the composition of a and b, b first then a.
- */
-o3djs.math.matrix4.composition = function(a, b) {
- 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];
- return [[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],
- [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],
- [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],
- [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]];
+ * @param {!o3djs.flat_math.Matrix4} a A 4-by-4 matrix.
+ * @param {!o3djs.flat_math.Matrix4} b A 4-by-4 matrix.
+ * @return {!o3djs.flat_math.Matrix4} the composition of a and b, b first then a.
+ */
+o3djs.flat_math.matrix4.composition = function(a, b) {
+ 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];
+ return o3djs.flat_math.makeMatrix(
+ 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,
+ 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,
+ 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,
+ 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);
};
/**
@@ -1974,121 +2531,105 @@ o3djs.math.matrix4.composition = function(a, b) {
* transform by b first and then a. Note this is subtly different from just
* multiplying the matrices together. For given a and b, a, upon modification,
* will be the same object in both row-major and column-major mode.
- * @param {!o3djs.math.Matrix4} a A 4-by-4 matrix.
- * @param {!o3djs.math.Matrix4} b A 4-by-4 matrix.
- * @return {!o3djs.math.Matrix4} a once modified.
- */
-o3djs.math.matrix4.compose = function(a, b) {
- 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];
- a[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);
- a[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);
- a[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),
- a[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);
+ * @param {!o3djs.flat_math.Matrix4} a A 4-by-4 matrix.
+ * @param {!o3djs.flat_math.Matrix4} b A 4-by-4 matrix.
+ * @return {!o3djs.flat_math.Matrix4} a once modified.
+ */
+o3djs.flat_math.matrix4.compose = function(a, b) {
+ 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];
+ a[0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;
+ a[1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;
+ a[2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;
+ a[3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;
+ a[4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;
+ a[5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;
+ a[6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;
+ a[7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;
+ a[8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;
+ a[9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;
+ a[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;
+ a[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;
+ a[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;
+ a[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;
+ a[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;
+ a[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;
return a;
};
/**
* Creates a 4-by-4 matrix which translates by the given vector v.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector by
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} v The vector by
* which to translate.
- * @return {!o3djs.math.Matrix4} The translation matrix.
+ * @return {!o3djs.flat_math.Matrix4} The translation matrix.
*/
-o3djs.math.matrix4.translation = function(v) {
- return [
- [1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0],
- [v[0], v[1], v[2], 1]
- ];
+o3djs.flat_math.matrix4.translation = function(v) {
+ return o3djs.flat_math.makeMatrix4(
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ v[0], v[1], v[2], 1);
};
/**
* Modifies the given 4-by-4 matrix by translation by the given vector v.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector by
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} v The vector by
* which to translate.
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.translate = 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 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);
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
+ */
+o3djs.flat_math.matrix4.translate = function(m, v) {
+ 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;
return m;
};
@@ -2097,41 +2638,38 @@ o3djs.math.matrix4.translate = function(m, v) {
* Creates a 4-by-4 matrix which scales in each dimension by an amount given by
* the corresponding entry in the given vector; assumes the vector has three
* entries.
- * @param {!o3djs.math.Vector3} v A vector of
+ * @param {!o3djs.flat_math.Vector3} v A vector of
* three entries specifying the factor by which to scale in each dimension.
- * @return {!o3djs.math.Matrix4} The scaling matrix.
+ * @return {!o3djs.flat_math.Matrix4} The scaling matrix.
*/
-o3djs.math.matrix4.scaling = function(v) {
- return [
- [v[0], 0, 0, 0],
- [0, v[1], 0, 0],
- [0, 0, v[2], 0],
- [0, 0, 0, 1]
- ];
+o3djs.flat_math.matrix4.scaling = function(v) {
+ return o3djs.flat_math.makeMatrix(
+ v[0], 0, 0, 0,
+ 0, v[1], 0, 0,
+ 0, 0, v[2], 0,
+ 0, 0, 0, 1
+ );
};
/**
* Modifies the given 4-by-4 matrix, scaling in each dimension by an amount
* given by the corresponding entry in the given vector; assumes the vector has
* three entries.
- * @param {!o3djs.math.Matrix4} m The matrix to be modified.
- * @param {!o3djs.math.Vector3} v A vector of three entries specifying the
+ * @param {!o3djs.flat_math.Matrix4} m The matrix to be modified.
+ * @param {!o3djs.flat_math.Vector3} v A vector of three entries specifying the
* factor by which to scale in each dimension.
- * @return {!o3djs.math.Matrix4} m once modified.
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
*/
-o3djs.math.matrix4.scale = function(m, v) {
+o3djs.flat_math.matrix4.scale = 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];
-
- 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]);
+ for (var i = 0; i < 4; ++i) {
+ m[i] *= v0;
+ m[4 + i] *= v1;
+ m[8 + i] *= v2;
+ }
return m;
};
@@ -2139,51 +2677,46 @@ o3djs.math.matrix4.scale = function(m, v) {
/**
* Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
+ * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
*/
-o3djs.math.matrix4.rotationX = function(angle) {
+o3djs.flat_math.matrix4.rotationX = function(angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
- return [
- [1, 0, 0, 0],
- [0, c, s, 0],
- [0, -s, c, 0],
- [0, 0, 0, 1]
- ];
+ return o3djs.flat_math.makeMatrix(
+ 1, 0, 0, 0,
+ 0, c, s, 0,
+ 0, -s, c, 0,
+ 0, 0, 0, 1);
};
/**
* Modifies the given 4-by-4 matrix by a rotation around the x-axis by the given
* angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateX = function(m, angle) {
- 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];
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
+ */
+o3djs.flat_math.matrix4.rotateX = function(m, angle) {
+ 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);
+ 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;
return m;
};
@@ -2191,51 +2724,46 @@ o3djs.math.matrix4.rotateX = function(m, angle) {
/**
* Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
+ * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
*/
-o3djs.math.matrix4.rotationY = function(angle) {
+o3djs.flat_math.matrix4.rotationY = function(angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
- return [
- [c, 0, -s, 0],
- [0, 1, 0, 0],
- [s, 0, c, 0],
- [0, 0, 0, 1]
- ];
+ return o3djs.flat_math.makeMatrix(
+ c, 0, -s, 0,
+ 0, 1, 0, 0,
+ s, 0, c, 0,
+ 0, 0, 0, 1);
};
/**
* Modifies the given 4-by-4 matrix by a rotation around the y-axis by the given
* angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateY = function(m, angle) {
- 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];
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
+ */
+o3djs.flat_math.matrix4.rotateY = function(m, angle) {
+ 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;
return m;
};
@@ -2243,51 +2771,46 @@ o3djs.math.matrix4.rotateY = function(m, angle) {
/**
* Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
+ * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
*/
-o3djs.math.matrix4.rotationZ = function(angle) {
+o3djs.flat_math.matrix4.rotationZ = function(angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
- return [
- [c, s, 0, 0],
- [-s, c, 0, 0],
- [0, 0, 1, 0],
- [0, 0, 0, 1]
- ];
+ return o3djs.flat_math.makeMatrix(
+ c, s, 0, 0,
+ -s, c, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1);
};
/**
* Modifies the given 4-by-4 matrix by a rotation around the z-axis by the given
* angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
- */
-o3djs.math.matrix4.rotateZ = function(m, angle) {
- 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];
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
+ */
+o3djs.flat_math.matrix4.rotateZ = function(m, angle) {
+ 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;
return m;
};
@@ -2297,10 +2820,10 @@ o3djs.math.matrix4.rotateZ = function(m, angle) {
* vector as angles by which to rotate around the x, y and z axes, returns a
* a matrix which rotates around the x-axis first, then the y-axis, then the
* z-axis.
- * @param {!o3djs.math.Vector3} v A vector of angles (in radians).
- * @return {!o3djs.math.Matrix4} The rotation matrix.
+ * @param {!o3djs.flat_math.Vector3} v A vector of angles (in radians).
+ * @return {!o3djs.flat_math.Matrix4} The rotation matrix.
*/
-o3djs.math.matrix4.rotationZYX = function(v) {
+o3djs.flat_math.matrix4.rotationZYX = function(v) {
var sinx = Math.sin(v[0]);
var cosx = Math.cos(v[0]);
var siny = Math.sin(v[1]);
@@ -2311,29 +2834,22 @@ o3djs.math.matrix4.rotationZYX = function(v) {
var coszsiny = cosz * siny;
var sinzsiny = sinz * siny;
- return [
- [cosz * cosy, sinz * cosy, -siny, 0],
- [coszsiny * sinx - sinz * cosx,
- sinzsiny * sinx + cosz * cosx,
- cosy * sinx,
- 0],
- [coszsiny * cosx + sinz * sinx,
- sinzsiny * cosx - cosz * sinx,
- cosy * cosx,
- 0],
- [0, 0, 0, 1]
- ];
+ return o3djs.flat_math.makeMatrix(
+ cosz * cosy, sinz * cosy, -siny, 0, coszsiny * sinx - sinz * cosx,
+ sinzsiny * sinx + cosz * cosx, cosy * sinx, 0,
+ coszsiny * cosx + sinz * sinx, sinzsiny * cosx - cosz * sinx, cosy * cosx,
+ 0, 0, 0, 0, 1);
};
/**
* Modifies a 4-by-4 matrix by a rotation. Interprets the coordinates of the
* given vector as angles by which to rotate around the x, y and z axes, rotates
* around the x-axis first, then the y-axis, then the z-axis.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {!o3djs.math.Vector3} v A vector of angles (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {!o3djs.flat_math.Vector3} v A vector of angles (in radians).
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
*/
-o3djs.math.matrix4.rotateZYX = function(m, v) {
+o3djs.flat_math.matrix4.rotateZYX = function(m, v) {
var sinX = Math.sin(v[0]);
var cosX = Math.cos(v[0]);
var sinY = Math.sin(v[1]);
@@ -2354,45 +2870,37 @@ o3djs.math.matrix4.rotateZYX = function(m, v) {
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;
return m;
};
@@ -2400,13 +2908,13 @@ o3djs.math.matrix4.rotateZYX = function(m, v) {
/**
* Creates a 4-by-4 matrix which rotates around the given axis by the given
* angle.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} axis The axis
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} axis The axis
* about which to rotate.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} A matrix which rotates angle radians
+ * @return {!o3djs.flat_math.Matrix4} A matrix which rotates angle radians
* around the axis.
*/
-o3djs.math.matrix4.axisRotation = function(axis, angle) {
+o3djs.flat_math.matrix4.axisRotation = function(axis, angle) {
var x = axis[0];
var y = axis[1];
var z = axis[2];
@@ -2421,33 +2929,33 @@ o3djs.math.matrix4.axisRotation = function(axis, angle) {
var s = Math.sin(angle);
var oneMinusCosine = 1 - c;
- return [
- [xx + (1 - xx) * c,
+ return o3djs.flat_math.makeMatrix(
+ xx + (1 - xx) * c,
x * y * oneMinusCosine + z * s,
x * z * oneMinusCosine - y * s,
- 0],
- [x * y * oneMinusCosine - z * s,
+ 0,
+ x * y * oneMinusCosine - z * s,
yy + (1 - yy) * c,
y * z * oneMinusCosine + x * s,
- 0],
- [x * z * oneMinusCosine + y * s,
+ 0,
+ x * z * oneMinusCosine + y * s,
y * z * oneMinusCosine - x * s,
zz + (1 - zz) * c,
- 0],
- [0, 0, 0, 1]
- ];
+ 0,
+ 0, 0, 0, 1
+ );
};
/**
* Modifies the given 4-by-4 matrix by rotation around the given axis by the
* given angle.
- * @param {!o3djs.math.Matrix4} m The matrix.
- * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} axis The axis
+ * @param {!o3djs.flat_math.Matrix4} m The matrix.
+ * @param {(!o3djs.flat_math.Vector3|!o3djs.flat_math.Vector4)} axis The axis
* about which to rotate.
* @param {number} angle The angle by which to rotate (in radians).
- * @return {!o3djs.math.Matrix4} m once modified.
+ * @return {!o3djs.flat_math.Matrix4} m once modified.
*/
-o3djs.math.matrix4.axisRotate = function(m, axis, angle) {
+o3djs.flat_math.matrix4.axisRotate = function(m, axis, angle) {
var x = axis[0];
var y = axis[1];
var z = axis[2];
@@ -2472,97 +2980,105 @@ o3djs.math.matrix4.axisRotate = function(m, axis, angle) {
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];
-
- 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;
return m;
};
/**
- * Sets each function in the namespace o3djs.math to the row major
- * version in o3djs.math.rowMajor (provided such a function exists in
- * o3djs.math.rowMajor). Call this function to establish the row major
+ * Sets each function in the namespace o3djs.flat_math to the row major
+ * version in o3djs.flat_math.rowMajor (provided such a function exists in
+ * o3djs.flat_math.rowMajor). Call this function to establish the row major
* convention.
*/
-o3djs.math.installRowMajorFunctions = function() {
- for (var f in o3djs.math.rowMajor) {
- o3djs.math[f] = o3djs.math.rowMajor[f];
+o3djs.flat_math.installRowMajorFunctions = function() {
+ for (var f in o3djs.flat_math.rowMajor) {
+ o3djs.flat_math[f] = o3djs.flat_math.rowMajor[f];
}
};
/**
- * Sets each function in the namespace o3djs.math to the column major
- * version in o3djs.math.columnMajor (provided such a function exists in
- * o3djs.math.columnMajor). Call this function to establish the column
+ * Sets each function in the namespace o3djs.flat_math to the column major
+ * version in o3djs.flat_math.columnMajor (provided such a function exists in
+ * o3djs.flat_math.columnMajor). Call this function to establish the column
* major convention.
*/
-o3djs.math.installColumnMajorFunctions = function() {
- for (var f in o3djs.math.columnMajor) {
- o3djs.math[f] = o3djs.math.columnMajor[f];
+o3djs.flat_math.installColumnMajorFunctions = function() {
+ for (var f in o3djs.flat_math.columnMajor) {
+ o3djs.flat_math[f] = o3djs.flat_math.columnMajor[f];
}
};
/**
- * Sets each function in the namespace o3djs.math to the error checking
- * version in o3djs.math.errorCheck (provided such a function exists in
- * o3djs.math.errorCheck).
+ * Sets each function in the namespace o3djs.flat_math to the error checking
+ * version in o3djs.flat_math.errorCheck (provided such a function exists in
+ * o3djs.flat_math.errorCheck).
*/
-o3djs.math.installErrorCheckFunctions = function() {
- for (var f in o3djs.math.errorCheck) {
- o3djs.math[f] = o3djs.math.errorCheck[f];
+o3djs.flat_math.installErrorCheckFunctions = function() {
+ for (var f in o3djs.flat_math.errorCheck) {
+ o3djs.flat_math[f] = o3djs.flat_math.errorCheck[f];
}
};
/**
- * Sets each function in the namespace o3djs.math to the error checking free
- * version in o3djs.math.errorCheckFree (provided such a function exists in
- * o3djs.math.errorCheckFree).
+ * Sets each function in the namespace o3djs.flat_math to the error checking free
+ * version in o3djs.flat_math.errorCheckFree (provided such a function exists in
+ * o3djs.flat_math.errorCheckFree).
*/
-o3djs.math.installErrorCheckFreeFunctions = function() {
- for (var f in o3djs.math.errorCheckFree) {
- o3djs.math[f] = o3djs.math.errorCheckFree[f];
+o3djs.flat_math.installErrorCheckFreeFunctions = function() {
+ for (var f in o3djs.flat_math.errorCheckFree) {
+ o3djs.flat_math[f] = o3djs.flat_math.errorCheckFree[f];
}
-}
+};
// By default, install the row-major functions.
-o3djs.math.installRowMajorFunctions();
+o3djs.flat_math.installRowMajorFunctions();
// By default, install prechecking.
-o3djs.math.installErrorCheckFunctions();
+o3djs.flat_math.installErrorCheckFunctions();
+
+if (!use_plugin_math) {
+ for (var i in o3djs.flat_math) {
+ o3djs.math[i] = o3djs.flat_math[i];
+ }
+}
+
+
+/**
+ * True if we are using the plugin math library in which matrices are
+ * represented by 2-dimensional arrays.
+ * @type {boolean}
+ * @private
+ */
+o3djs.math.usePluginMath_ = true;
+
diff --git a/o3d/samples/o3djs/plugin_math.js b/o3d/samples/o3djs/plugin_math.js
new file mode 100644
index 0000000..799ce78
--- /dev/null
+++ b/o3d/samples/o3djs/plugin_math.js
@@ -0,0 +1,2621 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * @fileoverview This file contains matrix/vector math functions.
+ * It adds them to the "math" module on the o3djs object.
+ *
+ * o3djs.math supports a row-major and a column-major mode. In both
+ * modes, vectors are stored as arrays of numbers, and matrices are stored as
+ * arrays of arrays of numbers.
+ *
+ * In row-major mode:
+ *
+ * - Rows of a matrix are sub-arrays.
+ * - Individual entries of a matrix M get accessed in M[row][column] fashion.
+ * - Tuples of coordinates are interpreted as row-vectors.
+ * - A vector v gets transformed by a matrix M by multiplying in the order v*M.
+ *
+ * In column-major mode:
+ *
+ * - Columns of a matrix are sub-arrays.
+ * - Individual entries of a matrix M get accessed in M[column][row] fashion.
+ * - Tuples of coordinates are interpreted as column-vectors.
+ * - A matrix M transforms a vector v by multiplying in the order M*v.
+ *
+ * When a function in o3djs.math requires separate row-major and
+ * column-major versions, a function with the same name gets added to each of
+ * the namespaces o3djs.math.rowMajor and o3djs.math.columnMajor. The
+ * function installRowMajorFunctions() or the function
+ * installColumnMajorFunctions() should get called during initialization to
+ * establish the mode. installRowMajorFunctions() works by iterating through
+ * the o3djs.math.rowMajor namespace and for each function foo, setting
+ * o3djs.math.foo equal to o3djs.math.rowMajor.foo.
+ * installRowMajorFunctions() works the same way, iterating over the columnMajor
+ * namespace. At the end of this file, we call installRowMajorFunctions().
+ *
+ * Switching modes changes two things. It changes how a matrix is encoded as an
+ * array, and it changes how the entries of a matrix get interpreted. Because
+ * those two things change together, the matrix representing a given
+ * transformation of space is the same JavaScript object in either mode.
+ * One consequence of this is that very few functions require separate row-major
+ * and column-major versions. Typically, a function requires separate versions
+ * only if it makes matrix multiplication order explicit, like
+ * mulMatrixMatrix(), mulMatrixVector(), or mulVectorMatrix(). Functions which
+ * create a new matrix, like scaling(), rotationZYX(), and translation() return
+ * the same JavaScript object in either mode, and functions which implicitly
+ * multiply like scale(), rotateZYX() and translate() modify the matrix in the
+ * same way in either mode.
+ *
+ * The convention choice made for math functions in this library is independent
+ * of the convention choice for how matrices get loaded into shaders. That
+ * convention is determined on a per-shader basis.
+ *
+ * Other utilities in o3djs should avoid making calls to functions that make
+ * multiplication order explicit. Instead they should appeal to functions like:
+ *
+ * o3djs.math.matrix4.transformPoint
+ * o3djs.math.matrix4.transformDirection
+ * o3djs.math.matrix4.transformNormal
+ * o3djs.math.matrix4.transformVector4
+ * o3djs.math.matrix4.composition
+ * o3djs.math.matrix4.compose
+ *
+ * These functions multiply matrices implicitly and internally choose the
+ * multiplication order to get the right result. That way, utilities which use
+ * o3djs.math work in either major mode. Note that this does not necessarily
+ * mean all sample code will work even if a line is added which switches major
+ * modes, but it does mean that calls to o3djs still do what they are supposed
+ * to.
+ *
+ */
+
+o3djs.provide('o3djs.math');
+
+/**
+ * A module for math for o3djs.math.
+ * @namespace
+ */
+o3djs.math = o3djs.math || {};
+
+/**
+ * A random seed for the pseudoRandom function.
+ * @private
+ * @type {number}
+ */
+o3djs.math.randomSeed_ = 0;
+
+/**
+ * A constant for the pseudoRandom function
+ * @private
+ * @type {number}
+ */
+o3djs.math.RANDOM_RANGE_ = Math.pow(2, 32);
+
+/**
+ * Functions which deal with 4-by-4 transformation matrices are kept in their
+ * own namespsace.
+ * @namespace
+ */
+o3djs.math.matrix4 = o3djs.math.matrix4 || {};
+
+/**
+ * Functions that are specifically row major are kept in their own namespace.
+ * @namespace
+ */
+o3djs.math.rowMajor = o3djs.math.rowMajor || {};
+
+/**
+ * Functions that are specifically column major are kept in their own namespace.
+ * @namespace
+ */
+o3djs.math.columnMajor = o3djs.math.columnMajor || {};
+
+/**
+ * Functions that do error checking are stored in their own namespace.
+ * @namespace
+ */
+o3djs.math.errorCheck = o3djs.math.errorCheck || {};
+
+/**
+ * Functions that do no error checking and have a separate version that does in
+ * o3djs.math.errorCheck are stored in their own namespace.
+ * @namespace
+ */
+o3djs.math.errorCheckFree = o3djs.math.errorCheckFree || {};
+
+/**
+ * An Array of 2 floats
+ * @type {(!Array.<number>|!o3d.Float2)}
+ */
+o3djs.math.Vector2 = goog.typedef;
+
+/**
+ * An Array of 3 floats
+ * @type {(!Array.<number>|!o3d.Float3)}
+ */
+o3djs.math.Vector3 = goog.typedef;
+
+/**
+ * An Array of 4 floats
+ * @type {(!Array.<number>|!o3d.Float4)}
+ */
+o3djs.math.Vector4 = goog.typedef;
+
+/**
+ * An Array of floats.
+ * @type {!Array.<number>}
+ */
+o3djs.math.Vector = goog.typedef;
+
+/**
+ * A 1x1 Matrix of floats
+ * @type {!Array.<!Array.<number>>}
+ */
+o3djs.math.Matrix1 = goog.typedef;
+
+/**
+ * A 2x2 Matrix of floats
+ * @type {!Array.<!Array.<number>>}
+ */
+o3djs.math.Matrix2 = goog.typedef;
+
+/**
+ * A 3x3 Matrix of floats
+ * @type {!Array.<!Array.<number>>}
+ */
+o3djs.math.Matrix3 = goog.typedef;
+
+/**
+ * A 4x4 Matrix of floats
+ * @type {(!Array.<!Array.<number>>|!o3d.Matrix4)}
+ */
+o3djs.math.Matrix4 = goog.typedef;
+
+/**
+ * A arbitrary size Matrix of floats
+ * @type {(!Array.<!Array.<number>>|!o3d.Matrix4)}
+ */
+o3djs.math.Matrix = goog.typedef;
+
+
+o3djs.math.makeMatrix = function(a,b,c,d,
+ e,f,g,h,
+ i,j,k,l,
+ m,n,o,p) {
+ if (p===undefined) {
+ if (i===undefined) {
+ return [[a,b],
+ [c,d]];
+ }
+ return [[a,b,c],
+ [d,e,f],
+ [g,h,i]];
+ }
+ return [[a,b,c,d],
+ [e,f,g,h],
+ [i,j,k,l],
+ [m,n,o,p]];
+};
+
+o3djs.math.makeMatrix2 = function(a,b,
+ c,d) {
+ return [[a,b],
+ [c,d]];
+};
+o3djs.math.makeMatrix3 = function(a,b,c,
+ d,e,f,
+ g,h,i) {
+ return [[a,b,c],
+ [d,e,f],
+ [g,h,i]];
+};
+o3djs.math.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]];
+};
+
+
+
+/**
+ * Returns a deterministic pseudorandom number between 0 and 1
+ * @return {number} a random number between 0 and 1
+ */
+o3djs.math.pseudoRandom = function() {
+ var math = o3djs.math;
+ return (math.randomSeed_ =
+ (134775813 * math.randomSeed_ + 1) %
+ math.RANDOM_RANGE_) / math.RANDOM_RANGE_;
+};
+
+/**
+ * Resets the pseudoRandom function sequence.
+ */
+o3djs.math.resetPseudoRandom = function() {
+ o3djs.math.randomSeed_ = 0;
+};
+
+/**
+ * Converts degrees to radians.
+ * @param {number} degrees A value in degrees.
+ * @return {number} the value in radians.
+ */
+o3djs.math.degToRad = function(degrees) {
+ return degrees * Math.PI / 180;
+};
+
+/**
+ * Converts radians to degrees.
+ * @param {number} radians A value in radians.
+ * @return {number} the value in degrees.
+ */
+o3djs.math.radToDeg = function(radians) {
+ return radians * 180 / Math.PI;
+};
+
+/**
+ * Performs linear interpolation on two scalars.
+ * Given scalars a and b and interpolation coefficient t, returns
+ * (1 - t) * a + t * b.
+ * @param {number} a Operand scalar.
+ * @param {number} b Operand scalar.
+ * @param {number} t Interpolation coefficient.
+ * @return {number} The weighted sum of a and b.
+ */
+o3djs.math.lerpScalar = function(a, b, t) {
+ return (1 - t) * a + t * b;
+};
+
+/**
+ * Adds two vectors; assumes a and b have the same dimension.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @return {!o3djs.math.Vector} The sum of a and b.
+ */
+o3djs.math.addVector = function(a, b) {
+ var r = [];
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r[i] = a[i] + b[i];
+ return r;
+};
+
+/**
+ * Subtracts two vectors.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @return {!o3djs.math.Vector} The difference of a and b.
+ */
+o3djs.math.subVector = function(a, b) {
+ var r = [];
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r[i] = a[i] - b[i];
+ return r;
+};
+
+/**
+ * Performs linear interpolation on two vectors.
+ * Given vectors a and b and interpolation coefficient t, returns
+ * (1 - t) * a + t * b.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @param {number} t Interpolation coefficient.
+ * @return {!o3djs.math.Vector} The weighted sum of a and b.
+ */
+o3djs.math.lerpVector = function(a, b, t) {
+ var r = [];
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r[i] = (1 - t) * a[i] + t * b[i];
+ return r;
+};
+
+/**
+ * Clamps a value between 0 and range using a modulo.
+ * @param {number} v Value to clamp mod.
+ * @param {number} range Range to clamp to.
+ * @param {number} opt_rangeStart start of range. Default = 0.
+ * @return {number} Clamp modded value.
+ */
+o3djs.math.modClamp = function(v, range, opt_rangeStart) {
+ var start = opt_rangeStart || 0;
+ if (range < 0.00001) {
+ return start;
+ }
+ v -= start;
+ if (v < 0) {
+ v -= Math.floor(v / range) * range;
+ } else {
+ v = v % range;
+ }
+ return v + start;
+};
+
+/**
+ * Lerps in a circle.
+ * Does a lerp between a and b but inside range so for example if
+ * range is 100, a is 95 and b is 5 lerping will go in the positive direction.
+ * @param {number} a Start value.
+ * @param {number} b Target value.
+ * @param {number} t Amount to lerp (0 to 1).
+ * @param {number} range Range of circle.
+ * @return {number} lerped result.
+ */
+o3djs.math.lerpCircular = function(a, b, t, range) {
+ a = o3djs.math.modClamp(a, range);
+ b = o3djs.math.modClamp(b, range);
+ var delta = b - a;
+ if (Math.abs(delta) > range * 0.5) {
+ if (delta > 0) {
+ b -= range;
+ } else {
+ b += range;
+ }
+ }
+ return o3djs.math.modClamp(o3djs.math.lerpScalar(a, b, t), range);
+};
+
+/**
+ * Lerps radians.
+ * @param {number} a Start value.
+ * @param {number} b Target value.
+ * @param {number} t Amount to lerp (0 to 1).
+ * @return {number} lerped result.
+ */
+o3djs.math.lerpRadian = function(a, b, t) {
+ return o3djs.math.lerpCircular(a, b, t, Math.PI * 2);
+};
+
+/**
+ * Divides a vector by a scalar.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @param {number} k The scalar.
+ * @return {!o3djs.math.Vector} v The vector v divided by k.
+ */
+o3djs.math.divVectorScalar = function(v, k) {
+ var r = [];
+ var vLength = v.length;
+ for (var i = 0; i < vLength; ++i)
+ r[i] = v[i] / k;
+ return r;
+};
+
+/**
+ * Computes the dot product of two vectors; assumes that a and b have
+ * the same dimension.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @return {number} The dot product of a and b.
+ */
+o3djs.math.dot = function(a, b) {
+ var r = 0.0;
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r += a[i] * b[i];
+ return r;
+};
+
+/**
+ * Computes the cross product of two vectors; assumes both vectors have
+ * three entries.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @return {!o3djs.math.Vector} The vector a cross b.
+ */
+o3djs.math.cross = function(a, b) {
+ return [a[1] * b[2] - a[2] * b[1],
+ a[2] * b[0] - a[0] * b[2],
+ a[0] * b[1] - a[1] * b[0]];
+};
+
+/**
+ * Computes the Euclidean length of a vector, i.e. the square root of the
+ * sum of the squares of the entries.
+ * @param {!o3djs.math.Vector} a The vector.
+ * @return {number} The length of a.
+ */
+o3djs.math.length = function(a) {
+ var r = 0.0;
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r += a[i] * a[i];
+ return Math.sqrt(r);
+};
+
+/**
+ * Computes the square of the Euclidean length of a vector, i.e. the sum
+ * of the squares of the entries.
+ * @param {!o3djs.math.Vector} a The vector.
+ * @return {number} The square of the length of a.
+ */
+o3djs.math.lengthSquared = function(a) {
+ var r = 0.0;
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r += a[i] * a[i];
+ return r;
+};
+
+/**
+ * Computes the Euclidean distance between two vectors.
+ * @param {!o3djs.math.Vector} a A vector.
+ * @param {!o3djs.math.Vector} b A vector.
+ * @return {number} The distance between a and b.
+ */
+o3djs.math.distance = function(a, b) {
+ var r = 0.0;
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i) {
+ var t = a[i] - b[i];
+ r += t * t;
+ }
+ return Math.sqrt(r);
+};
+
+/**
+ * Computes the square of the Euclidean distance between two vectors.
+ * @param {!o3djs.math.Vector} a A vector.
+ * @param {!o3djs.math.Vector} b A vector.
+ * @return {number} The distance between a and b.
+ */
+o3djs.math.distanceSquared = function(a, b) {
+ var r = 0.0;
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i) {
+ var t = a[i] - b[i];
+ r += t * t;
+ }
+ return r;
+};
+
+/**
+ * Divides a vector by its Euclidean length and returns the quotient.
+ * @param {!o3djs.math.Vector} a The vector.
+ * @return {!o3djs.math.Vector} The normalized vector.
+ */
+o3djs.math.normalize = function(a) {
+ var r = [];
+ var n = 0.0;
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ n += a[i] * a[i];
+ n = Math.sqrt(n);
+ for (var i = 0; i < aLength; ++i)
+ r[i] = a[i] / n;
+ return r;
+};
+
+/**
+ * Adds two matrices; assumes a and b are the same size.
+ * @param {!o3djs.math.Matrix} a Operand matrix.
+ * @param {!o3djs.math.Matrix} b Operand matrix.
+ * @return {!o3djs.math.Matrix} The sum of a and b.
+ */
+o3djs.math.addMatrix = function(a, b) {
+ var r = [];
+ var aLength = a.length;
+ var a0Length = a[0].length;
+ for (var i = 0; i < aLength; ++i) {
+ var row = [];
+ var ai = a[i];
+ var bi = b[i];
+ for (var j = 0; j < a0Length; ++j)
+ row[j] = ai[j] + bi[j];
+ r[i] = row;
+ }
+ return r;
+};
+
+/**
+ * Subtracts two matrices; assumes a and b are the same size.
+ * @param {!o3djs.math.Matrix} a Operand matrix.
+ * @param {!o3djs.math.Matrix} b Operand matrix.
+ * @return {!o3djs.math.Matrix} The sum of a and b.
+ */
+o3djs.math.subMatrix = function(a, b) {
+ var r = [];
+ var aLength = a.length;
+ var a0Length = a[0].length;
+ for (var i = 0; i < aLength; ++i) {
+ var row = [];
+ var ai = a[i];
+ var bi = b[i];
+ for (var j = 0; j < a0Length; ++j)
+ row[j] = ai[j] - bi[j];
+ r[i] = row;
+ }
+ return r;
+};
+
+/**
+ * Performs linear interpolation on two matrices.
+ * Given matrices a and b and interpolation coefficient t, returns
+ * (1 - t) * a + t * b.
+ * @param {!o3djs.math.Matrix} a Operand matrix.
+ * @param {!o3djs.math.Matrix} b Operand matrix.
+ * @param {number} t Interpolation coefficient.
+ * @return {!o3djs.math.Matrix} The weighted of a and b.
+ */
+o3djs.math.lerpMatrix = function(a, b, t) {
+ var r = [];
+ var aLength = a.length;
+ var a0Length = a[0].length;
+ for (var i = 0; i < aLength; ++i) {
+ var row = [];
+ var ai = a[i];
+ var bi = b[i];
+ for (var j = 0; j < a0Length; ++j)
+ row[j] = (1 - t) * ai[j] + t * bi[j];
+ r[i] = row;
+ }
+ return r;
+};
+
+/**
+ * Divides a matrix by a scalar.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} k The scalar.
+ * @return {!o3djs.math.Matrix} The matrix m divided by k.
+ */
+o3djs.math.divMatrixScalar = function(m, k) {
+ var r = [];
+ var mLength = m.length;
+ var m0Length = m[0].length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = [];
+ for (var j = 0; j < m0Length; ++j)
+ r[i][j] = m[i][j] / k;
+ }
+ return r;
+};
+
+/**
+ * Negates a scalar.
+ * @param {number} a The scalar.
+ * @return {number} -a.
+ */
+o3djs.math.negativeScalar = function(a) {
+ return -a;
+};
+
+/**
+ * Negates a vector.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} -v.
+ */
+o3djs.math.negativeVector = function(v) {
+ var r = [];
+ var vLength = v.length;
+ for (var i = 0; i < vLength; ++i) {
+ r[i] = -v[i];
+ }
+ return r;
+};
+
+/**
+ * Negates a matrix.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Matrix} -m.
+ */
+o3djs.math.negativeMatrix = function(m) {
+ var r = [];
+ var mLength = m.length;
+ var m0Length = m[0].length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = [];
+ for (var j = 0; j < m0Length; ++j)
+ r[i][j] = -m[i][j];
+ }
+ return r;
+};
+
+/**
+ * Copies a scalar.
+ * @param {number} a The scalar.
+ * @return {number} a.
+ */
+o3djs.math.copyScalar = function(a) {
+ return a;
+};
+
+/**
+ * Copies a vector.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} A copy of v.
+ */
+o3djs.math.copyVector = function(v) {
+ var r = [];
+ for (var i = 0; i < v.length; i++)
+ r[i] = v[i];
+ return r;
+};
+
+/**
+ * Copies a matrix.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Matrix} A copy of m.
+ */
+o3djs.math.copyMatrix = function(m) {
+ var r = [];
+ var mLength = m.length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = [];
+ for (var j = 0; j < m[i].length; j++) {
+ r[i][j] = m[i][j];
+ }
+ }
+ return r;
+};
+
+/**
+ * Returns the elements of a matrix as a one-dimensional array. The
+ * rows or columns (depending on whether the matrix is row-major or
+ * column-major) are concatenated.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!Array.<number>} The matrix's elements as a one-dimensional array.
+ */
+o3djs.math.getMatrixElements = function(m) {
+ var r = [];
+ var mLength = m.length;
+ var k = 0;
+ for (var i = 0; i < mLength; i++) {
+ for (var j = 0; j < m[i].length; j++) {
+ r[k++] = m[i][j];
+ }
+ }
+ return r;
+};
+
+/**
+ * Multiplies two scalars.
+ * @param {number} a Operand scalar.
+ * @param {number} b Operand scalar.
+ * @return {number} The product of a and b.
+ */
+o3djs.math.mulScalarScalar = function(a, b) {
+ return a * b;
+};
+
+/**
+ * Multiplies a scalar by a vector.
+ * @param {number} k The scalar.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} The product of k and v.
+ */
+o3djs.math.mulScalarVector = function(k, v) {
+ var r = [];
+ var vLength = v.length;
+ for (var i = 0; i < vLength; ++i) {
+ r[i] = k * v[i];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a vector by a scalar.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @param {number} k The scalar.
+ * @return {!o3djs.math.Vector} The product of k and v.
+ */
+o3djs.math.mulVectorScalar = function(v, k) {
+ return o3djs.math.mulScalarVector(k, v);
+};
+
+/**
+ * Multiplies a scalar by a matrix.
+ * @param {number} k The scalar.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Matrix} The product of m and k.
+ */
+o3djs.math.mulScalarMatrix = function(k, m) {
+ var r = [];
+ var mLength = m.length;
+ var m0Length = m[0].length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = [];
+ for (var j = 0; j < m0Length; ++j)
+ r[i][j] = k * m[i][j];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a matrix by a scalar.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} k The scalar.
+ * @return {!o3djs.math.Matrix} The product of m and k.
+ */
+o3djs.math.mulMatrixScalar = function(m, k) {
+ return o3djs.math.mulScalarMatrix(k, m);
+};
+
+/**
+ * Multiplies a vector by another vector (component-wise); assumes a and
+ * b have the same length.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @return {!o3djs.math.Vector} The vector of products of entries of a and
+ * b.
+ */
+o3djs.math.mulVectorVector = function(a, b) {
+ var r = [];
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r[i] = a[i] * b[i];
+ return r;
+};
+
+/**
+ * Divides a vector by another vector (component-wise); assumes a and
+ * b have the same length.
+ * @param {!o3djs.math.Vector} a Operand vector.
+ * @param {!o3djs.math.Vector} b Operand vector.
+ * @return {!o3djs.math.Vector} The vector of quotients of entries of a and
+ * b.
+ */
+o3djs.math.divVectorVector = function(a, b) {
+ var r = [];
+ var aLength = a.length;
+ for (var i = 0; i < aLength; ++i)
+ r[i] = a[i] / b[i];
+ return r;
+};
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [row][column] fashion.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Vector} The product of v and m as a row vector.
+ */
+o3djs.math.rowMajor.mulVectorMatrix = function(v, m) {
+ var r = [];
+ var m0Length = m[0].length;
+ var vLength = v.length;
+ for (var i = 0; i < m0Length; ++i) {
+ r[i] = 0.0;
+ for (var j = 0; j < vLength; ++j)
+ r[i] += v[j] * m[j][i];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector; assumes
+ * matrix entries are accessed in [column][row] fashion.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Vector} The product of v and m as a row vector.
+ */
+o3djs.math.columnMajor.mulVectorMatrix = function(v, m) {
+ var r = [];
+ var mLength = m.length;
+ var vLength = v.length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = 0.0;
+ var column = m[i];
+ for (var j = 0; j < vLength; ++j)
+ r[i] += v[j] * column[j];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a vector by a matrix; treats the vector as a row vector.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} The product of m and v as a row vector.
+ */
+o3djs.math.mulVectorMatrix = null;
+
+/**
+ * Multiplies a matrix by a vector; treats the vector as a column vector.
+ * assumes matrix entries are accessed in [row][column] fashion.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} The product of m and v as a column vector.
+ */
+o3djs.math.rowMajor.mulMatrixVector = function(m, v) {
+ var r = [];
+ var mLength = m.length;
+ var m0Length = m[0].length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = 0.0;
+ var row = m[i];
+ for (var j = 0; j < m0Length; ++j)
+ r[i] += row[j] * v[j];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a matrix by a vector; treats the vector as a column vector;
+ * assumes matrix entries are accessed in [column][row] fashion.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} The product of m and v as a column vector.
+ */
+o3djs.math.columnMajor.mulMatrixVector = function(m, v) {
+ var r = [];
+ var m0Length = m[0].length;
+ var vLength = v.length;
+ for (var i = 0; i < m0Length; ++i) {
+ r[i] = 0.0;
+ for (var j = 0; j < vLength; ++j)
+ r[i] += v[j] * m[j][i];
+ }
+ return r;
+};
+
+/**
+ * Multiplies a matrix by a vector; treats the vector as a column vector.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {!o3djs.math.Vector} v The vector.
+ * @return {!o3djs.math.Vector} The product of m and v as a column vector.
+ */
+o3djs.math.mulMatrixVector = null;
+
+/**
+ * Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
+ * assumes matrix entries are accessed in [row][column] fashion.
+ * @param {!o3djs.math.Matrix2} a The matrix on the left.
+ * @param {!o3djs.math.Matrix2} b The matrix on the right.
+ * @return {!o3djs.math.Matrix2} The matrix product of a and b.
+ */
+o3djs.math.rowMajor.mulMatrixMatrix2 = function(a, b) {
+ var a0 = a[0];
+ var a1 = a[1];
+ var b0 = b[0];
+ var b1 = b[1];
+ var a00 = a0[0];
+ var a01 = a0[1];
+ var a10 = a1[0];
+ var a11 = a1[1];
+ var b00 = b0[0];
+ var b01 = b0[1];
+ var b10 = b1[0];
+ var b11 = b1[1];
+ return [[a00 * b00 + a01 * b10, a00 * b01 + a01 * b11],
+ [a10 * b00 + a11 * b10, a10 * b01 + a11 * b11]];
+};
+
+/**
+ * Multiplies two 2-by-2 matrices; assumes that the given matrices are 2-by-2;
+ * assumes matrix entries are accessed in [column][row] fashion.
+ * @param {!o3djs.math.Matrix2} a The matrix on the left.
+ * @param {!o3djs.math.Matrix2} b The matrix on the right.
+ * @return {!o3djs.math.Matrix2} The matrix product of a and b.
+ */
+o3djs.math.columnMajor.mulMatrixMatrix2 = function(a, b) {
+ var a0 = a[0];
+ var a1 = a[1];
+ var b0 = b[0];
+ var b1 = b[1];
+ var a00 = a0[0];
+ var a01 = a0[1];
+ var a10 = a1[0];
+ var a11 = a1[1];
+ var b00 = b0[0];
+ var b01 = b0[1];
+ var b10 = b1[0];
+ var b11 = b1[1];
+ return [[a00 * b00 + a10 * b01, a01 * b00 + a11 * b01],
+ [a00 * b10 + a10 * b11, a01 * b10 + a11 * b11]];
+};
+
+/**
+ * Multiplies two 2-by-2 matrices.
+ * @param {!o3djs.math.Matrix2} a The matrix on the left.
+ * @param {!o3djs.math.Matrix2} b The matrix on the right.
+ * @return {!o3djs.math.Matrix2} The matrix product of a and b.
+ */
+o3djs.math.mulMatrixMatrix2 = null;
+
+
+/**
+ * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
+ * assumes matrix entries are accessed in [row][column] fashion.
+ * @param {!o3djs.math.Matrix3} a The matrix on the left.
+ * @param {!o3djs.math.Matrix3} b The matrix on the right.
+ * @return {!o3djs.math.Matrix3} The matrix product of a and b.
+ */
+o3djs.math.rowMajor.mulMatrixMatrix3 = function(a, b) {
+ var a0 = a[0];
+ var a1 = a[1];
+ var a2 = a[2];
+ var b0 = b[0];
+ var b1 = b[1];
+ var b2 = b[2];
+ var a00 = a0[0];
+ var a01 = a0[1];
+ var a02 = a0[2];
+ var a10 = a1[0];
+ var a11 = a1[1];
+ var a12 = a1[2];
+ var a20 = a2[0];
+ var a21 = a2[1];
+ var a22 = a2[2];
+ var b00 = b0[0];
+ var b01 = b0[1];
+ var b02 = b0[2];
+ var b10 = b1[0];
+ var b11 = b1[1];
+ var b12 = b1[2];
+ var b20 = b2[0];
+ var b21 = b2[1];
+ var b22 = b2[2];
+ return [[a00 * b00 + a01 * b10 + a02 * b20,
+ a00 * b01 + a01 * b11 + a02 * b21,
+ a00 * b02 + a01 * b12 + a02 * b22],
+ [a10 * b00 + a11 * b10 + a12 * b20,
+ a10 * b01 + a11 * b11 + a12 * b21,
+ a10 * b02 + a11 * b12 + a12 * b22],
+ [a20 * b00 + a21 * b10 + a22 * b20,
+ a20 * b01 + a21 * b11 + a22 * b21,
+ a20 * b02 + a21 * b12 + a22 * b22]];
+};
+
+/**
+ * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3;
+ * assumes matrix entries are accessed in [column][row] fashion.
+ * @param {!o3djs.math.Matrix3} a The matrix on the left.
+ * @param {!o3djs.math.Matrix3} b The matrix on the right.
+ * @return {!o3djs.math.Matrix3} The matrix product of a and b.
+ */
+o3djs.math.columnMajor.mulMatrixMatrix3 = function(a, b) {
+ var a0 = a[0];
+ var a1 = a[1];
+ var a2 = a[2];
+ var b0 = b[0];
+ var b1 = b[1];
+ var b2 = b[2];
+ var a00 = a0[0];
+ var a01 = a0[1];
+ var a02 = a0[2];
+ var a10 = a1[0];
+ var a11 = a1[1];
+ var a12 = a1[2];
+ var a20 = a2[0];
+ var a21 = a2[1];
+ var a22 = a2[2];
+ var b00 = b0[0];
+ var b01 = b0[1];
+ var b02 = b0[2];
+ var b10 = b1[0];
+ var b11 = b1[1];
+ var b12 = b1[2];
+ var b20 = b2[0];
+ var b21 = b2[1];
+ var b22 = b2[2];
+ return [[a00 * b00 + a10 * b01 + a20 * b02,
+ a01 * b00 + a11 * b01 + a21 * b02,
+ a02 * b00 + a12 * b01 + a22 * b02],
+ [a00 * b10 + a10 * b11 + a20 * b12,
+ a01 * b10 + a11 * b11 + a21 * b12,
+ a02 * b10 + a12 * b11 + a22 * b12],
+ [a00 * b20 + a10 * b21 + a20 * b22,
+ a01 * b20 + a11 * b21 + a21 * b22,
+ a02 * b20 + a12 * b21 + a22 * b22]];
+};
+
+/**
+ * Multiplies two 3-by-3 matrices; assumes that the given matrices are 3-by-3.
+ * @param {!o3djs.math.Matrix3} a The matrix on the left.
+ * @param {!o3djs.math.Matrix3} b The matrix on the right.
+ * @return {!o3djs.math.Matrix3} The matrix product of a and b.
+ */
+o3djs.math.mulMatrixMatrix3 = null;
+
+/**
+ * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
+ * assumes matrix entries are accessed in [row][column] fashion.
+ * @param {!o3djs.math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.math.Matrix4} The matrix product of a and b.
+ */
+o3djs.math.rowMajor.mulMatrixMatrix4 = function(a, b) {
+ 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];
+ return [[a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,
+ a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,
+ a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,
+ a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33],
+ [a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,
+ a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,
+ a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,
+ a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33],
+ [a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,
+ a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,
+ a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,
+ a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33],
+ [a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,
+ a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,
+ a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,
+ a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33]];
+};
+
+/**
+ * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4;
+ * assumes matrix entries are accessed in [column][row] fashion.
+ * @param {!o3djs.math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.math.Matrix4} The matrix product of a and b.
+ */
+o3djs.math.columnMajor.mulMatrixMatrix4 = function(a, b) {
+ 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];
+ return [[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],
+ [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],
+ [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],
+ [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]];
+};
+
+/**
+ * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
+ * @param {!o3djs.math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.math.Matrix4} The matrix product of a and b.
+ */
+o3djs.math.mulMatrixMatrix4 = null;
+
+/**
+ * Multiplies two matrices; assumes that the sizes of the matrices are
+ * appropriately compatible; assumes matrix entries are accessed in
+ * [row][column] fashion.
+ * @param {!o3djs.math.Matrix} a The matrix on the left.
+ * @param {!o3djs.math.Matrix} b The matrix on the right.
+ * @return {!o3djs.math.Matrix} The matrix product of a and b.
+ */
+o3djs.math.rowMajor.mulMatrixMatrix = function(a, b) {
+ var r = [];
+ var aRows = a.length;
+ var bColumns = b[0].length;
+ var bRows = b.length;
+ for (var i = 0; i < aRows; ++i) {
+ var v = []; // v becomes a row of the answer.
+ var ai = a[i]; // ith row of a.
+ for (var j = 0; j < bColumns; ++j) {
+ v[j] = 0.0;
+ for (var k = 0; k < bRows; ++k)
+ v[j] += ai[k] * b[k][j]; // kth row, jth column.
+ }
+ r[i] = v;
+ }
+ return r;
+};
+
+/**
+ * Multiplies two matrices; assumes that the sizes of the matrices are
+ * appropriately compatible; assumes matrix entries are accessed in
+ * [row][column] fashion.
+ * @param {!o3djs.math.Matrix} a The matrix on the left.
+ * @param {!o3djs.math.Matrix} b The matrix on the right.
+ * @return {!o3djs.math.Matrix} The matrix product of a and b.
+ */
+o3djs.math.columnMajor.mulMatrixMatrix = function(a, b) {
+ var r = [];
+ var bColumns = b.length;
+ var aRows = a[0].length;
+ var aColumns = a.length;
+ for (var i = 0; i < bColumns; ++i) {
+ var v = []; // v becomes a column of the answer.
+ var bi = b[i]; // ith column of b.
+ for (var j = 0; j < aRows; ++j) {
+ v[j] = 0.0;
+ for (var k = 0; k < aColumns; ++k)
+ v[j] += bi[k] * a[k][j]; // kth column, jth row.
+ }
+ r[i] = v;
+ }
+ return r;
+};
+
+/**
+ * Multiplies two matrices; assumes that the sizes of the matrices are
+ * appropriately compatible.
+ * @param {!o3djs.math.Matrix} a The matrix on the left.
+ * @param {!o3djs.math.Matrix} b The matrix on the right.
+ * @return {!o3djs.math.Matrix} The matrix product of a and b.
+ */
+o3djs.math.mulMatrixMatrix = null;
+
+/**
+ * Gets the jth column of the given matrix m; assumes matrix entries are
+ * accessed in [row][column] fashion.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} j The index of the desired column.
+ * @return {!o3djs.math.Vector} The jth column of m as a vector.
+ */
+o3djs.math.rowMajor.column = function(m, j) {
+ var r = [];
+ var mLength = m.length;
+ for (var i = 0; i < mLength; ++i) {
+ r[i] = m[i][j];
+ }
+ return r;
+};
+
+/**
+ * Gets the jth column of the given matrix m; assumes matrix entries are
+ * accessed in [column][row] fashion.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} j The index of the desired column.
+ * @return {!o3djs.math.Vector} The jth column of m as a vector.
+ */
+o3djs.math.columnMajor.column = function(m, j) {
+ return m[j].slice();
+};
+
+/**
+ * Gets the jth column of the given matrix m.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} j The index of the desired column.
+ * @return {!o3djs.math.Vector} The jth column of m as a vector.
+ */
+o3djs.math.column = null;
+
+/**
+ * Gets the ith row of the given matrix m; assumes matrix entries are
+ * accessed in [row][column] fashion.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} i The index of the desired row.
+ * @return {!o3djs.math.Vector} The ith row of m.
+ */
+o3djs.math.rowMajor.row = function(m, i) {
+ return m[i].slice();
+};
+
+/**
+ * Gets the ith row of the given matrix m; assumes matrix entries are
+ * accessed in [column][row] fashion.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} i The index of the desired row.
+ * @return {!o3djs.math.Vector} The ith row of m.
+ */
+o3djs.math.columnMajor.row = function(m, i) {
+ var r = [];
+ var mLength = m.length;
+ for (var j = 0; j < mLength; ++j) {
+ r[j] = m[j][i];
+ }
+ return r;
+};
+
+/**
+ * Gets the ith row of the given matrix m.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @param {number} i The index of the desired row.
+ * @return {!o3djs.math.Vector} The ith row of m.
+ */
+o3djs.math.row = null;
+
+/**
+ * Creates an n-by-n identity matrix.
+ * @param {number} n The dimension of the identity matrix required.
+ * @return {!o3djs.math.Matrix} An n-by-n identity matrix.
+ */
+o3djs.math.identity = function(n) {
+ var r = [];
+ for (var j = 0; j < n; ++j) {
+ r[j] = [];
+ for (var i = 0; i < n; ++i)
+ r[j][i] = (i == j) ? 1 : 0;
+ }
+ return r;
+};
+
+/**
+ * Takes the transpose of a matrix.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Matrix} The transpose of m.
+ */
+o3djs.math.transpose = function(m) {
+ var r = [];
+ var m0Length = m[0].length;
+ var mLength = m.length;
+ for (var j = 0; j < m0Length; ++j) {
+ r[j] = [];
+ for (var i = 0; i < mLength; ++i)
+ r[j][i] = m[i][j];
+ }
+ return r;
+};
+
+/**
+ * Computes the trace (sum of the diagonal entries) of a square matrix;
+ * assumes m is square.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {number} The trace of m.
+ */
+o3djs.math.trace = function(m) {
+ var r = 0.0;
+ var mLength = m.length;
+ for (var i = 0; i < mLength; ++i)
+ r += m[i][i];
+ return r;
+};
+
+/**
+ * Computes the determinant of a 1-by-1 matrix.
+ * @param {!o3djs.math.Matrix1} m The matrix.
+ * @return {number} The determinant of m.
+ */
+o3djs.math.det1 = function(m) {
+ return m[0][0];
+};
+
+/**
+ * Computes the determinant of a 2-by-2 matrix.
+ * @param {!o3djs.math.Matrix2} m The matrix.
+ * @return {number} The determinant of m.
+ */
+o3djs.math.det2 = function(m) {
+ return m[0][0] * m[1][1] - m[0][1] * m[1][0];
+};
+
+/**
+ * Computes the determinant of a 3-by-3 matrix.
+ * @param {!o3djs.math.Matrix3} m The matrix.
+ * @return {number} The determinant of m.
+ */
+o3djs.math.det3 = function(m) {
+ return m[2][2] * (m[0][0] * m[1][1] - m[0][1] * m[1][0]) -
+ m[2][1] * (m[0][0] * m[1][2] - m[0][2] * m[1][0]) +
+ m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]);
+};
+
+/**
+ * Computes the determinant of a 4-by-4 matrix.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {number} The determinant of m.
+ */
+o3djs.math.det4 = function(m) {
+ var t01 = m[0][0] * m[1][1] - m[0][1] * m[1][0];
+ var t02 = m[0][0] * m[1][2] - m[0][2] * m[1][0];
+ var t03 = m[0][0] * m[1][3] - m[0][3] * m[1][0];
+ var t12 = m[0][1] * m[1][2] - m[0][2] * m[1][1];
+ var t13 = m[0][1] * m[1][3] - m[0][3] * m[1][1];
+ var t23 = m[0][2] * m[1][3] - m[0][3] * m[1][2];
+ return m[3][3] * (m[2][2] * t01 - m[2][1] * t02 + m[2][0] * t12) -
+ m[3][2] * (m[2][3] * t01 - m[2][1] * t03 + m[2][0] * t13) +
+ m[3][1] * (m[2][3] * t02 - m[2][2] * t03 + m[2][0] * t23) -
+ m[3][0] * (m[2][3] * t12 - m[2][2] * t13 + m[2][1] * t23);
+};
+
+/**
+ * Computes the inverse of a 1-by-1 matrix.
+ * @param {!o3djs.math.Matrix1} m The matrix.
+ * @return {!o3djs.math.Matrix1} The inverse of m.
+ */
+o3djs.math.inverse1 = function(m) {
+ return [[1.0 / m[0][0]]];
+};
+
+/**
+ * Computes the inverse of a 2-by-2 matrix.
+ * @param {!o3djs.math.Matrix2} m The matrix.
+ * @return {!o3djs.math.Matrix2} The inverse of m.
+ */
+o3djs.math.inverse2 = function(m) {
+ var d = 1.0 / (m[0][0] * m[1][1] - m[0][1] * m[1][0]);
+ return [[d * m[1][1], -d * m[0][1]], [-d * m[1][0], d * m[0][0]]];
+};
+
+/**
+ * Computes the inverse of a 3-by-3 matrix.
+ * @param {!o3djs.math.Matrix3} m The matrix.
+ * @return {!o3djs.math.Matrix3} The inverse of m.
+ */
+o3djs.math.inverse3 = function(m) {
+ var t00 = m[1][1] * m[2][2] - m[1][2] * m[2][1];
+ var t10 = m[0][1] * m[2][2] - m[0][2] * m[2][1];
+ var t20 = m[0][1] * m[1][2] - m[0][2] * m[1][1];
+ var d = 1.0 / (m[0][0] * t00 - m[1][0] * t10 + m[2][0] * t20);
+ return [[d * t00, -d * t10, d * t20],
+ [-d * (m[1][0] * m[2][2] - m[1][2] * m[2][0]),
+ d * (m[0][0] * m[2][2] - m[0][2] * m[2][0]),
+ -d * (m[0][0] * m[1][2] - m[0][2] * m[1][0])],
+ [d * (m[1][0] * m[2][1] - m[1][1] * m[2][0]),
+ -d * (m[0][0] * m[2][1] - m[0][1] * m[2][0]),
+ d * (m[0][0] * m[1][1] - m[0][1] * m[1][0])]];
+};
+
+/**
+ * Computes the inverse of a 4-by-4 matrix.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {!o3djs.math.Matrix4} The inverse of m.
+ */
+o3djs.math.inverse4 = function(m) {
+ var tmp_0 = m[2][2] * m[3][3];
+ var tmp_1 = m[3][2] * m[2][3];
+ var tmp_2 = m[1][2] * m[3][3];
+ var tmp_3 = m[3][2] * m[1][3];
+ var tmp_4 = m[1][2] * m[2][3];
+ var tmp_5 = m[2][2] * m[1][3];
+ var tmp_6 = m[0][2] * m[3][3];
+ var tmp_7 = m[3][2] * m[0][3];
+ var tmp_8 = m[0][2] * m[2][3];
+ var tmp_9 = m[2][2] * m[0][3];
+ var tmp_10 = m[0][2] * m[1][3];
+ var tmp_11 = m[1][2] * m[0][3];
+ var tmp_12 = m[2][0] * m[3][1];
+ var tmp_13 = m[3][0] * m[2][1];
+ var tmp_14 = m[1][0] * m[3][1];
+ var tmp_15 = m[3][0] * m[1][1];
+ var tmp_16 = m[1][0] * m[2][1];
+ var tmp_17 = m[2][0] * m[1][1];
+ var tmp_18 = m[0][0] * m[3][1];
+ var tmp_19 = m[3][0] * m[0][1];
+ var tmp_20 = m[0][0] * m[2][1];
+ var tmp_21 = m[2][0] * m[0][1];
+ var tmp_22 = m[0][0] * m[1][1];
+ var tmp_23 = m[1][0] * m[0][1];
+
+ var t0 = (tmp_0 * m[1][1] + tmp_3 * m[2][1] + tmp_4 * m[3][1]) -
+ (tmp_1 * m[1][1] + tmp_2 * m[2][1] + tmp_5 * m[3][1]);
+ var t1 = (tmp_1 * m[0][1] + tmp_6 * m[2][1] + tmp_9 * m[3][1]) -
+ (tmp_0 * m[0][1] + tmp_7 * m[2][1] + tmp_8 * m[3][1]);
+ var t2 = (tmp_2 * m[0][1] + tmp_7 * m[1][1] + tmp_10 * m[3][1]) -
+ (tmp_3 * m[0][1] + tmp_6 * m[1][1] + tmp_11 * m[3][1]);
+ var t3 = (tmp_5 * m[0][1] + tmp_8 * m[1][1] + tmp_11 * m[2][1]) -
+ (tmp_4 * m[0][1] + tmp_9 * m[1][1] + tmp_10 * m[2][1]);
+
+ var d = 1.0 / (m[0][0] * t0 + m[1][0] * t1 + m[2][0] * t2 + m[3][0] * t3);
+
+ var row0 = [d * t0, d * t1, d * t2, d * t3];
+ var row1 = [d * ((tmp_1 * m[1][0] + tmp_2 * m[2][0] + tmp_5 * m[3][0]) -
+ (tmp_0 * m[1][0] + tmp_3 * m[2][0] + tmp_4 * m[3][0])),
+ d * ((tmp_0 * m[0][0] + tmp_7 * m[2][0] + tmp_8 * m[3][0]) -
+ (tmp_1 * m[0][0] + tmp_6 * m[2][0] + tmp_9 * m[3][0])),
+ d * ((tmp_3 * m[0][0] + tmp_6 * m[1][0] + tmp_11 * m[3][0]) -
+ (tmp_2 * m[0][0] + tmp_7 * m[1][0] + tmp_10 * m[3][0])),
+ d * ((tmp_4 * m[0][0] + tmp_9 * m[1][0] + tmp_10 * m[2][0]) -
+ (tmp_5 * m[0][0] + tmp_8 * m[1][0] + tmp_11 * m[2][0]))];
+ var row2 =[d * ((tmp_12 * m[1][3] + tmp_15 * m[2][3] + tmp_16 * m[3][3]) -
+ (tmp_13 * m[1][3] + tmp_14 * m[2][3] + tmp_17 * m[3][3])),
+ d * ((tmp_13 * m[0][3] + tmp_18 * m[2][3] + tmp_21 * m[3][3]) -
+ (tmp_12 * m[0][3] + tmp_19 * m[2][3] + tmp_20 * m[3][3])),
+ d * ((tmp_14 * m[0][3] + tmp_19 * m[1][3] + tmp_22 * m[3][3]) -
+ (tmp_15 * m[0][3] + tmp_18 * m[1][3] + tmp_23 * m[3][3])),
+ d * ((tmp_17 * m[0][3] + tmp_20 * m[1][3] + tmp_23 * m[2][3]) -
+ (tmp_16 * m[0][3] + tmp_21 * m[1][3] + tmp_22 * m[2][3]))];
+ var row3 = [d * ((tmp_14 * m[2][2] + tmp_17 * m[3][2] + tmp_13 * m[1][2]) -
+ (tmp_16 * m[3][2] + tmp_12 * m[1][2] + tmp_15 * m[2][2])),
+ d * ((tmp_20 * m[3][2] + tmp_12 * m[0][2] + tmp_19 * m[2][2]) -
+ (tmp_18 * m[2][2] + tmp_21 * m[3][2] + tmp_13 * m[0][2])),
+ d * ((tmp_18 * m[1][2] + tmp_23 * m[3][2] + tmp_15 * m[0][2]) -
+ (tmp_22 * m[3][2] + tmp_14 * m[0][2] + tmp_19 * m[1][2])),
+ d * ((tmp_22 * m[2][2] + tmp_16 * m[0][2] + tmp_21 * m[1][2]) -
+ (tmp_20 * m[1][2] + tmp_23 * m[2][2] + tmp_17 * m[0][2]))];
+ return [row0, row1, row2, row3];
+};
+
+/**
+ * Computes the determinant of the cofactor matrix obtained by removal
+ * of a specified row and column. This is a helper function for the general
+ * determinant and matrix inversion functions.
+ * @param {!o3djs.math.Matrix} a The original matrix.
+ * @param {number} x The row to be removed.
+ * @param {number} y The column to be removed.
+ * @return {number} The determinant of the matrix obtained by removing
+ * row x and column y from a.
+ */
+o3djs.math.codet = function(a, x, y) {
+ var size = a.length;
+ var b = [];
+ var ai = 0;
+ for (var bi = 0; bi < size - 1; ++bi) {
+ if (ai == x)
+ ai++;
+ b[bi] = [];
+ var aj = 0;
+ for (var bj = 0; bj < size - 1; ++bj) {
+ if (aj == y)
+ aj++;
+ b[bi][bj] = a[ai][aj];
+ aj++;
+ }
+ ai++;
+ }
+ return o3djs.math.det(b);
+};
+
+/**
+ * Computes the determinant of an arbitrary square matrix.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {number} the determinant of m.
+ */
+o3djs.math.det = function(m) {
+ var d = m.length;
+ if (d <= 4) {
+ return o3djs.math['det' + d](m);
+ }
+ var r = 0.0;
+ var sign = 1;
+ var row = m[0];
+ var mLength = m.length;
+ for (var y = 0; y < mLength; y++) {
+ r += sign * row[y] * o3djs.math.codet(m, 0, y);
+ sign *= -1;
+ }
+ return r;
+};
+
+/**
+ * Computes the inverse of an arbitrary square matrix.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Matrix} The inverse of m.
+ */
+o3djs.math.inverse = function(m) {
+ var d = m.length;
+ if (d <= 4) {
+ return o3djs.math['inverse' + d](m);
+ }
+ var r = [];
+ var size = m.length;
+ for (var j = 0; j < size; ++j) {
+ r[j] = [];
+ for (var i = 0; i < size; ++i)
+ r[j][i] = ((i + j) % 2 ? -1 : 1) * o3djs.math.codet(m, i, j);
+ }
+ return o3djs.math.divMatrixScalar(r, o3djs.math.det(m));
+};
+
+/**
+ * Performs Graham-Schmidt orthogonalization on the vectors which make up the
+ * given matrix and returns the result in the rows of a new matrix. When
+ * multiplying many orthogonal matrices together, errors can accumulate causing
+ * the product to fail to be orthogonal. This function can be used to correct
+ * that.
+ * @param {!o3djs.math.Matrix} m The matrix.
+ * @return {!o3djs.math.Matrix} A matrix whose rows are obtained from the
+ * rows of m by the Graham-Schmidt process.
+ */
+o3djs.math.orthonormalize = function(m) {
+ var r = [];
+ var mLength = m.length;
+ for (var i = 0; i < mLength; ++i) {
+ var v = m[i];
+ for (var j = 0; j < i; ++j) {
+ v = o3djs.math.subVector(v, o3djs.math.mulScalarVector(
+ o3djs.math.dot(r[j], m[i]), r[j]));
+ }
+ r[i] = o3djs.math.normalize(v);
+ }
+ return r;
+};
+
+/**
+ * Computes the inverse of a 4-by-4 matrix.
+ * Note: It is faster to call this than o3djs.math.inverse.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {!o3djs.math.Matrix4} The inverse of m.
+ */
+o3djs.math.matrix4.inverse = function(m) {
+ return o3djs.math.inverse4(m);
+};
+
+/**
+ * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4.
+ * Note: It is faster to call this than o3djs.math.mul.
+ * @param {!o3djs.math.Matrix4} a The matrix on the left.
+ * @param {!o3djs.math.Matrix4} b The matrix on the right.
+ * @return {!o3djs.math.Matrix4} The matrix product of a and b.
+ */
+o3djs.math.matrix4.mul = function(a, b) {
+ return o3djs.math.mulMatrixMatrix4(a, b);
+};
+
+/**
+ * Computes the determinant of a 4-by-4 matrix.
+ * Note: It is faster to call this than o3djs.math.det.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {number} The determinant of m.
+ */
+o3djs.math.matrix4.det = function(m) {
+ return o3djs.math.det4(m);
+};
+
+/**
+ * Copies a Matrix4.
+ * Note: It is faster to call this than o3djs.math.copy.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {!o3djs.math.Matrix4} A copy of m.
+ */
+o3djs.math.matrix4.copy = function(m) {
+ return o3djs.math.copyMatrix(m);
+};
+
+/**
+ * Sets the upper 3-by-3 block of matrix a to the upper 3-by-3 block of matrix
+ * b; assumes that a and b are big enough to contain an upper 3-by-3 block.
+ * @param {!o3djs.math.Matrix4} a A matrix.
+ * @param {!o3djs.math.Matrix3} b A 3-by-3 matrix.
+ * @return {!o3djs.math.Matrix4} a once modified.
+ */
+o3djs.math.matrix4.setUpper3x3 = function(a, b) {
+ var b0 = b[0];
+ var b1 = b[1];
+ var b2 = b[2];
+
+ a[0].splice(0, 3, b0[0], b0[1], b0[2]);
+ a[1].splice(0, 3, b1[0], b1[1], b1[2]);
+ a[2].splice(0, 3, b2[0], b2[1], b2[2]);
+
+ return a;
+};
+
+/**
+ * Returns a 3-by-3 matrix mimicking the upper 3-by-3 block of m; assumes m
+ * is big enough to contain an upper 3-by-3 block.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {!o3djs.math.Matrix3} The upper 3-by-3 block of m.
+ */
+o3djs.math.matrix4.getUpper3x3 = function(m) {
+ return [m[0].slice(0, 3), m[1].slice(0, 3), m[2].slice(0, 3)];
+};
+
+/**
+ * Sets the translation component of a 4-by-4 matrix to the given
+ * vector.
+ * @param {!o3djs.math.Matrix4} a The matrix.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector.
+ * @return {!o3djs.math.Matrix4} a once modified.
+ */
+o3djs.math.matrix4.setTranslation = function(a, v) {
+ a[3].splice(0, 4, v[0], v[1], v[2], 1);
+ return a;
+};
+
+/**
+ * Returns the translation component of a 4-by-4 matrix as a vector with 3
+ * entries.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @return {!o3djs.math.Vector3} The translation component of m.
+ */
+o3djs.math.matrix4.getTranslation = function(m) {
+ return m[3].slice(0, 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, 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.
+ */
+o3djs.math.matrix4.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, transforms that vector 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 point in homogenous coordinates.
+ * @return {!o3djs.math.Vector4} The transformed point in homogenous
+ * coordinates.
+ */
+o3djs.math.matrix4.transformVector4 = 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
+ * direction, transforms that direction by the matrix, and returns the result;
+ * assumes the transformation of 3-dimensional space represented by the matrix
+ * is parallel-preserving, i.e. any combination of rotation, scaling and
+ * translation, but not a perspective distortion. Returns a vector with 3
+ * entries.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector3} v The direction.
+ * @return {!o3djs.math.Vector3} The transformed direction.
+ */
+o3djs.math.matrix4.transformDirection = 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[0] + v1 * m1[0] + v2 * m2[0],
+ v0 * m0[1] + v1 * m1[1] + v2 * m2[1],
+ v0 * m0[2] + v1 * m1[2] + v2 * m2[2]];
+};
+
+/**
+ * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector
+ * as a normal to a surface, and computes a vector which is normal upon
+ * transforming that surface by the matrix. The effect of this function is the
+ * same as transforming v (as a direction) by the inverse-transpose of m. This
+ * function assumes the transformation of 3-dimensional space represented by the
+ * matrix is parallel-preserving, i.e. any combination of rotation, scaling and
+ * translation, but not a perspective distortion. Returns a vector with 3
+ * entries.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector3} v The normal.
+ * @return {!o3djs.math.Vector3} The transformed normal.
+ */
+o3djs.math.matrix4.transformNormal = function(m, v) {
+ var mInverse = o3djs.math.inverse4(m);
+ var v0 = v[0];
+ var v1 = v[1];
+ var v2 = v[2];
+ var mi0 = mInverse[0];
+ var mi1 = mInverse[1];
+ var mi2 = mInverse[2];
+ var mi3 = mInverse[3];
+
+ return [v0 * mi0[0] + v1 * mi0[1] + v2 * mi0[2],
+ v0 * mi1[0] + v1 * mi1[1] + v2 * mi1[2],
+ v0 * mi2[0] + v1 * mi2[1] + v2 * mi2[2]];
+};
+
+/**
+ * Creates a 4-by-4 identity matrix.
+ * @return {!o3djs.math.Matrix4} The 4-by-4 identity.
+ */
+o3djs.math.matrix4.identity = function() {
+ return [
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Sets the given 4-by-4 matrix to the identity matrix.
+ * @param {!o3djs.math.Matrix4} m The matrix to set to identity.
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.setIdentity = function(m) {
+ for (var i = 0; i < 4; i++) {
+ for (var j = 0; j < 4; j++) {
+ if (i == j) {
+ m[i][j] = 1;
+ } else {
+ m[i][j] = 0;
+ }
+ }
+ }
+ return m;
+};
+
+/**
+ * Computes a 4-by-4 perspective transformation matrix given the angular height
+ * of the frustum, the aspect ratio, and the near and far clipping planes. The
+ * arguments define a frustum extending in the negative z direction. The given
+ * angle is the vertical angle of the frustum, and the horizontal angle is
+ * determined to produce the given aspect ratio. The arguments near and far are
+ * the distances to the near and far clipping planes. Note that near and far
+ * are not z coordinates, but rather they are distances along the negative
+ * z-axis. The matrix generated sends the viewing frustum to the unit box.
+ * We assume a unit box extending from -1 to 1 in the x and y dimensions and
+ * from 0 to 1 in the z dimension.
+ * @param {number} angle The camera angle from top to bottom (in radians).
+ * @param {number} aspect The aspect ratio width / height.
+ * @param {number} near The depth (negative z coordinate)
+ * of the near clipping plane.
+ * @param {number} far The depth (negative z coordinate)
+ * of the far clipping plane.
+ * @return {!o3djs.math.Matrix4} The perspective matrix.
+ */
+o3djs.math.matrix4.perspective = function(angle, aspect, near, far) {
+ var f = Math.tan(0.5 * (Math.PI - angle));
+ var range = near - far;
+
+ return [
+ [f / aspect, 0, 0, 0],
+ [0, f, 0, 0],
+ [0, 0, far / range, -1],
+ [0, 0, near * far / range, 0]
+ ];
+};
+
+/**
+ * Computes a 4-by-4 orthographic projection matrix given the coordinates of the
+ * planes defining the axis-aligned, box-shaped viewing volume. The matrix
+ * generated sends that box to the unit box. Note that although left and right
+ * are x coordinates and bottom and top are y coordinates, near and far
+ * are not z coordinates, but rather they are distances along the negative
+ * z-axis. We assume a unit box extending from -1 to 1 in the x and y
+ * dimensions and from 0 to 1 in the z dimension.
+ * @param {number} left The x coordinate of the left plane of the box.
+ * @param {number} right The x coordinate of the right plane of the box.
+ * @param {number} bottom The y coordinate of the bottom plane of the box.
+ * @param {number} top The y coordinate of the right plane of the box.
+ * @param {number} near The negative z coordinate of the near plane of the box.
+ * @param {number} far The negative z coordinate of the far plane of the box.
+ * @return {!o3djs.math.Matrix4} The orthographic projection matrix.
+ */
+o3djs.math.matrix4.orthographic =
+ function(left, right, bottom, top, near, far) {
+ return [
+ [2 / (right - left), 0, 0, 0],
+ [0, 2 / (top - bottom), 0, 0],
+ [0, 0, 1 / (near - far), 0],
+ [(left + right) / (left - right),
+ (bottom + top) / (bottom - top),
+ near / (near - far), 1]
+ ];
+};
+
+/**
+ * Computes a 4-by-4 perspective transformation matrix given the left, right,
+ * top, bottom, near and far clipping planes. The arguments define a frustum
+ * extending in the negative z direction. The arguments near and far are the
+ * distances to the near and far clipping planes. Note that near and far are not
+ * z coordinates, but rather they are distances along the negative z-axis. The
+ * matrix generated sends the viewing frustum to the unit box. We assume a unit
+ * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z
+ * dimension.
+ * @param {number} left The x coordinate of the left plane of the box.
+ * @param {number} right The x coordinate of the right plane of the box.
+ * @param {number} bottom The y coordinate of the bottom plane of the box.
+ * @param {number} top The y coordinate of the right plane of the box.
+ * @param {number} near The negative z coordinate of the near plane of the box.
+ * @param {number} far The negative z coordinate of the far plane of the box.
+ * @return {!o3djs.math.Matrix4} The perspective projection matrix.
+ */
+o3djs.math.matrix4.frustum = function(left, right, bottom, top, near, far) {
+ var dx = (right - left);
+ var dy = (top - bottom);
+ var dz = (near - far);
+ return [
+ [2 * near / dx, 0, 0, 0],
+ [0, 2 * near / dy, 0, 0],
+ [(left + right) / dx, (top + bottom) / dy, far / dz, -1],
+ [0, 0, near * far / dz, 0]];
+};
+
+/**
+ * Computes a 4-by-4 look-at transformation. The transformation generated is
+ * an orthogonal rotation matrix with translation component. The translation
+ * component sends the eye to the origin. The rotation component sends the
+ * vector pointing from the eye to the target to a vector pointing in the
+ * negative z direction, and also sends the up vector into the upper half of
+ * the yz plane.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} eye The position
+ * of the eye.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} target The
+ * position meant to be viewed.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} up A vector
+ * pointing up.
+ * @return {!o3djs.math.Matrix4} The look-at matrix.
+ */
+o3djs.math.matrix4.lookAt = function(eye, target, up) {
+ var vz = o3djs.math.normalize(
+ o3djs.math.subVector(eye, target).slice(0, 3)).concat(0);
+ var vx = o3djs.math.normalize(
+ o3djs.math.cross(up, vz)).concat(0);
+ var vy = o3djs.math.cross(vz, vx).concat(0);
+
+ return o3djs.math.inverse([vx, vy, vz, eye.concat(1)]);
+};
+
+/**
+ * Takes two 4-by-4 matrices, a and b, and computes the product in the order
+ * that pre-composes b with a. In other words, the matrix returned will
+ * transform by b first and then a. Note this is subtly different from just
+ * multiplying the matrices together. For given a and b, this function returns
+ * the same object in both row-major and column-major mode.
+ * @param {!o3djs.math.Matrix4} a A 4-by-4 matrix.
+ * @param {!o3djs.math.Matrix4} b A 4-by-4 matrix.
+ * @return {!o3djs.math.Matrix4} the composition of a and b, b first then a.
+ */
+o3djs.math.matrix4.composition = function(a, b) {
+ 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];
+ return [[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],
+ [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],
+ [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],
+ [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]];
+};
+
+/**
+ * Takes two 4-by-4 matrices, a and b, and modifies a to be the product in the
+ * order that pre-composes b with a. The matrix a, upon modification will
+ * transform by b first and then a. Note this is subtly different from just
+ * multiplying the matrices together. For given a and b, a, upon modification,
+ * will be the same object in both row-major and column-major mode.
+ * @param {!o3djs.math.Matrix4} a A 4-by-4 matrix.
+ * @param {!o3djs.math.Matrix4} b A 4-by-4 matrix.
+ * @return {!o3djs.math.Matrix4} a once modified.
+ */
+o3djs.math.matrix4.compose = function(a, b) {
+ 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];
+ a[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);
+ a[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);
+ a[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),
+ a[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);
+ return a;
+};
+
+/**
+ * Creates a 4-by-4 matrix which translates by the given vector v.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector by
+ * which to translate.
+ * @return {!o3djs.math.Matrix4} The translation matrix.
+ */
+o3djs.math.matrix4.translation = function(v) {
+ return [
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, 0],
+ [v[0], v[1], v[2], 1]
+ ];
+};
+
+/**
+ * Modifies the given 4-by-4 matrix by translation by the given vector v.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} v The vector by
+ * which to translate.
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.translate = 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 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);
+
+ return m;
+};
+
+/**
+ * Creates a 4-by-4 matrix which scales in each dimension by an amount given by
+ * the corresponding entry in the given vector; assumes the vector has three
+ * entries.
+ * @param {!o3djs.math.Vector3} v A vector of
+ * three entries specifying the factor by which to scale in each dimension.
+ * @return {!o3djs.math.Matrix4} The scaling matrix.
+ */
+o3djs.math.matrix4.scaling = function(v) {
+ return [
+ [v[0], 0, 0, 0],
+ [0, v[1], 0, 0],
+ [0, 0, v[2], 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Modifies the given 4-by-4 matrix, scaling in each dimension by an amount
+ * given by the corresponding entry in the given vector; assumes the vector has
+ * three entries.
+ * @param {!o3djs.math.Matrix4} m The matrix to be modified.
+ * @param {!o3djs.math.Vector3} v A vector of three entries specifying the
+ * factor by which to scale in each dimension.
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.scale = 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];
+
+ 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]);
+
+ return m;
+};
+
+/**
+ * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} The rotation matrix.
+ */
+o3djs.math.matrix4.rotationX = function(angle) {
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+
+ return [
+ [1, 0, 0, 0],
+ [0, c, s, 0],
+ [0, -s, c, 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Modifies the given 4-by-4 matrix by a rotation around the x-axis by the given
+ * angle.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.rotateX = function(m, angle) {
+ 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 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);
+
+ return m;
+};
+
+/**
+ * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} The rotation matrix.
+ */
+o3djs.math.matrix4.rotationY = function(angle) {
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+
+ return [
+ [c, 0, -s, 0],
+ [0, 1, 0, 0],
+ [s, 0, c, 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Modifies the given 4-by-4 matrix by a rotation around the y-axis by the given
+ * angle.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.rotateY = function(m, angle) {
+ 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 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);
+
+ return m;
+};
+
+/**
+ * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} The rotation matrix.
+ */
+o3djs.math.matrix4.rotationZ = function(angle) {
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+
+ return [
+ [c, s, 0, 0],
+ [-s, c, 0, 0],
+ [0, 0, 1, 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Modifies the given 4-by-4 matrix by a rotation around the z-axis by the given
+ * angle.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.rotateZ = function(m, angle) {
+ 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 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);
+
+ return m;
+};
+
+/**
+ * Creates a 4-by-4 rotation matrix. Interprets the entries of the given
+ * vector as angles by which to rotate around the x, y and z axes, returns a
+ * a matrix which rotates around the x-axis first, then the y-axis, then the
+ * z-axis.
+ * @param {!o3djs.math.Vector3} v A vector of angles (in radians).
+ * @return {!o3djs.math.Matrix4} The rotation matrix.
+ */
+o3djs.math.matrix4.rotationZYX = function(v) {
+ var sinx = Math.sin(v[0]);
+ var cosx = Math.cos(v[0]);
+ var siny = Math.sin(v[1]);
+ var cosy = Math.cos(v[1]);
+ var sinz = Math.sin(v[2]);
+ var cosz = Math.cos(v[2]);
+
+ var coszsiny = cosz * siny;
+ var sinzsiny = sinz * siny;
+
+ return [
+ [cosz * cosy, sinz * cosy, -siny, 0],
+ [coszsiny * sinx - sinz * cosx,
+ sinzsiny * sinx + cosz * cosx,
+ cosy * sinx,
+ 0],
+ [coszsiny * cosx + sinz * sinx,
+ sinzsiny * cosx - cosz * sinx,
+ cosy * cosx,
+ 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Modifies a 4-by-4 matrix by a rotation. Interprets the coordinates of the
+ * given vector as angles by which to rotate around the x, y and z axes, rotates
+ * around the x-axis first, then the y-axis, then the z-axis.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {!o3djs.math.Vector3} v A vector of angles (in radians).
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.rotateZYX = function(m, v) {
+ var sinX = Math.sin(v[0]);
+ var cosX = Math.cos(v[0]);
+ var sinY = Math.sin(v[1]);
+ var cosY = Math.cos(v[1]);
+ var sinZ = Math.sin(v[2]);
+ var cosZ = Math.cos(v[2]);
+
+ var cosZSinY = cosZ * sinY;
+ var sinZSinY = sinZ * sinY;
+
+ var r00 = cosZ * cosY;
+ var r01 = sinZ * cosY;
+ var r02 = -sinY;
+ var r10 = cosZSinY * sinX - sinZ * cosX;
+ var r11 = sinZSinY * sinX + cosZ * cosX;
+ var r12 = cosY * sinX;
+ var r20 = cosZSinY * cosX + sinZ * sinX;
+ 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);
+
+ return m;
+};
+
+/**
+ * Creates a 4-by-4 matrix which rotates around the given axis by the given
+ * angle.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} axis The axis
+ * about which to rotate.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} A matrix which rotates angle radians
+ * around the axis.
+ */
+o3djs.math.matrix4.axisRotation = function(axis, angle) {
+ var x = axis[0];
+ var y = axis[1];
+ var z = axis[2];
+ var n = Math.sqrt(x * x + y * y + z * z);
+ x /= n;
+ y /= n;
+ z /= n;
+ var xx = x * x;
+ var yy = y * y;
+ var zz = z * z;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ var oneMinusCosine = 1 - c;
+
+ return [
+ [xx + (1 - xx) * c,
+ x * y * oneMinusCosine + z * s,
+ x * z * oneMinusCosine - y * s,
+ 0],
+ [x * y * oneMinusCosine - z * s,
+ yy + (1 - yy) * c,
+ y * z * oneMinusCosine + x * s,
+ 0],
+ [x * z * oneMinusCosine + y * s,
+ y * z * oneMinusCosine - x * s,
+ zz + (1 - zz) * c,
+ 0],
+ [0, 0, 0, 1]
+ ];
+};
+
+/**
+ * Modifies the given 4-by-4 matrix by rotation around the given axis by the
+ * given angle.
+ * @param {!o3djs.math.Matrix4} m The matrix.
+ * @param {(!o3djs.math.Vector3|!o3djs.math.Vector4)} axis The axis
+ * about which to rotate.
+ * @param {number} angle The angle by which to rotate (in radians).
+ * @return {!o3djs.math.Matrix4} m once modified.
+ */
+o3djs.math.matrix4.axisRotate = function(m, axis, angle) {
+ var x = axis[0];
+ var y = axis[1];
+ var z = axis[2];
+ var n = Math.sqrt(x * x + y * y + z * z);
+ x /= n;
+ y /= n;
+ z /= n;
+ var xx = x * x;
+ var yy = y * y;
+ var zz = z * z;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ var oneMinusCosine = 1 - c;
+
+ var r00 = xx + (1 - xx) * c;
+ var r01 = x * y * oneMinusCosine + z * s;
+ var r02 = x * z * oneMinusCosine - y * s;
+ var r10 = x * y * oneMinusCosine - z * s;
+ var r11 = yy + (1 - yy) * c;
+ var r12 = y * z * oneMinusCosine + x * s;
+ var r20 = x * z * oneMinusCosine + y * s;
+ 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];
+
+ 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);
+
+ return m;
+};
+
+/**
+ * Sets each function in the namespace o3djs.math to the row major
+ * version in o3djs.math.rowMajor (provided such a function exists in
+ * o3djs.math.rowMajor). Call this function to establish the row major
+ * convention.
+ */
+o3djs.math.installRowMajorFunctions = function() {
+ for (var f in o3djs.math.rowMajor) {
+ o3djs.math[f] = o3djs.math.rowMajor[f];
+ }
+};
+
+/**
+ * Sets each function in the namespace o3djs.math to the column major
+ * version in o3djs.math.columnMajor (provided such a function exists in
+ * o3djs.math.columnMajor). Call this function to establish the column
+ * major convention.
+ */
+o3djs.math.installColumnMajorFunctions = function() {
+ for (var f in o3djs.math.columnMajor) {
+ o3djs.math[f] = o3djs.math.columnMajor[f];
+ }
+};
+
+/**
+ * Sets each function in the namespace o3djs.math to the error checking
+ * version in o3djs.math.errorCheck (provided such a function exists in
+ * o3djs.math.errorCheck).
+ */
+o3djs.math.installErrorCheckFunctions = function() {
+ for (var f in o3djs.math.errorCheck) {
+ o3djs.math[f] = o3djs.math.errorCheck[f];
+ }
+};
+
+/**
+ * Sets each function in the namespace o3djs.math to the error checking free
+ * version in o3djs.math.errorCheckFree (provided such a function exists in
+ * o3djs.math.errorCheckFree).
+ */
+o3djs.math.installErrorCheckFreeFunctions = function() {
+ for (var f in o3djs.math.errorCheckFree) {
+ o3djs.math[f] = o3djs.math.errorCheckFree[f];
+ }
+}
+
+// By default, install the row-major functions.
+o3djs.math.installRowMajorFunctions();
+
+// By default, install prechecking.
+o3djs.math.installErrorCheckFunctions();
+
+
+/**
+ * True if we are using the plugin math library in which matrices are
+ * represented by 2-dimensional arrays.
+ * @type {boolean}
+ * @private
+ */
+o3djs.math.usePluginMath_ = true;
diff --git a/o3d/samples/o3djs/primitives.js b/o3d/samples/o3djs/primitives.js
index f736305..34d058d 100644
--- a/o3d/samples/o3djs/primitives.js
+++ b/o3d/samples/o3djs/primitives.js
@@ -707,7 +707,8 @@ o3djs.primitives.VertexInfo.prototype.addTangentStreams =
if (!frame) {
frame = [[0, 0, 0], [0, 0, 0]];
}
- frame = math.addMatrix(frame, [tangent, binormal]);
+ math.addVector3To(frame[0], tangent, frame[0]);
+ math.addVector3To(frame[1], binormal, frame[1]);
tangentFrames[key] = frame;
}
@@ -1054,10 +1055,10 @@ o3djs.primitives.createBox = function(pack,
depth,
opt_matrix) {
var vertexInfo = o3djs.primitives.createCubeVertices(1);
- vertexInfo.reorient([[width, 0, 0, 0],
- [0, height, 0, 0],
- [0, 0, depth, 0],
- [0, 0, 0, 1]]);
+ vertexInfo.reorient(o3djs.math.makeMatrix4(width, 0, 0, 0,
+ 0, height, 0, 0,
+ 0, 0, depth, 0,
+ 0, 0, 0, 1));
if (opt_matrix) {
vertexInfo.reorient(opt_matrix);
diff --git a/o3d/samples/o3djs/quaternions.js b/o3d/samples/o3djs/quaternions.js
index fe9c406..24d9d65 100644
--- a/o3d/samples/o3djs/quaternions.js
+++ b/o3d/samples/o3djs/quaternions.js
@@ -426,17 +426,17 @@ o3djs.quaternions.quaternionToRotation = function(q) {
var d = qWqW + qXqX + qYqY + qZqZ;
- return [
- [(qWqW + qXqX - qYqY - qZqZ) / d,
+ return o3djs.math.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);
};
/**
@@ -453,10 +453,16 @@ o3djs.quaternions.rotationToQuaternion = function(m) {
var w;
var q = [];
-
- var m0 = m[0];
- var m1 = m[1];
- var m2 = m[2];
+ var m0,m1,m2;
+ if (m.length==9) {
+ m0 = [m[0], m[1], m[2]];
+ m1 = [m[3], m[4], m[5]];
+ m2 = [m[6], m[7], m[8]];
+ }else {
+ m0 = [m[0], m[1], m[2]];
+ m1 = [m[4], m[5], m[6]];
+ m2 = [m[8], m[9], m[10]];
+ }
var m00 = m0[0];
var m11 = m1[1];
diff --git a/o3d/samples/o3djs/serialization.js b/o3d/samples/o3djs/serialization.js
index c300023..9a5ed29 100644
--- a/o3d/samples/o3djs/serialization.js
+++ b/o3d/samples/o3djs/serialization.js
@@ -38,6 +38,7 @@
o3djs.provide('o3djs.serialization');
+o3djs.require('o3djs.math');
o3djs.require('o3djs.error');
o3djs.require('o3djs.texture');
@@ -447,7 +448,10 @@ o3djs.serialization.Deserializer.prototype.deserializeValue = function(
for (var i = 0; i != valueAsObject.length; ++i) {
valueAsObject[i] = this.deserializeValue(valueAsObject[i]);
}
- return valueAsObject;
+ if (o3djs.math.usePluginMath_) {
+ return valueAsObject;
+ }
+ return o3djs.serialization.fixMatrices(valueAsObject);
}
var refId = valueAsObject['ref'];
@@ -746,6 +750,50 @@ o3djs.serialization.deserialize = function(pack, json) {
};
/**
+ * This function looks at a given data type, determines if it is an old style
+ * matrix that is a 2d doubly nested array. If so, it flattens the matrix in
+ * place so that it may be handled by the code.
+ * @param {object} parsed a potential array that will be repaired
+ */
+o3djs.serialization.fixMatrices = function(parsed) {
+ function isMatrix(m) {
+ var len = m && m.length;
+ if (len && len <= 4) {
+ for (var i = 0; i < len; ++i) {
+ var mi = m[i];
+ var mlen = mi.length;
+ if (mlen != len) {
+ return false;
+ }
+ for(var j = 0; j < len; ++j) {
+ if (Number(mi[j]) == NaN){
+ return false;
+ }
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function flatten(m) {
+ var len = m.length;
+ var retval = new o3djs.math.makeMatrix4(len * len);
+ for (var i = 0; i < len; ++i) {
+ for (var j = 0; j < len; ++j) {
+ retval[i * len + j] = m[i][j];
+ }
+ }
+ return retval;
+ }
+ if (isMatrix(parsed)) {
+ return flatten(parsed);
+ }
+ return parsed;
+};
+
+/**
* Deserializes a single json object named 'scene.json' from a loaded
* o3djs.io.ArchiveInfo.
* @param {!o3djs.io.ArchiveInfo} archiveInfo Archive to load from.