@@ -1,1789 +0,0 @@
3− * Copyright (c) 2010 Mozilla Corporation
4− * Copyright (c) 2010 Vladimir Vukicevic
5− * Copyright (c) 2013 John Mayer
7− * Permission is hereby granted, free of charge, to any person
8− * obtaining a copy of this software and associated documentation
9− * files (the "Software"), to deal in the Software without
10− * restriction, including without limitation the rights to use,
11− * copy, modify, merge, publish, distribute, sublicense, and/or sell
12− * copies of the Software, and to permit persons to whom the
13− * Software is furnished to do so, subject to the following
16− * The above copyright notice and this permission notice shall be
17− * included in all copies or substantial portions of the Software.
19− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21− * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23− * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24− * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25− * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26− * OTHER DEALINGS IN THE SOFTWARE.
32− * Vector and Matrix math utilities for JavaScript, optimized for WebGL.
33− * Edited to work with the Elm Programming Language
37−Elm.Native.MJS.make = function(elm) {
39− elm.Native = elm.Native || {};
40− elm.Native.MJS = elm.Native.MJS || {};
41− if (elm.Native.MJS.values) return elm.Native.MJS.values;
44− * Constant: MJS_VERSION
46− * mjs version number aa.bb.cc, encoded as an integer of the form:
49− var MJS_VERSION = 0x000000;
52− * Constant: MJS_DO_ASSERT
54− * Enables or disables runtime assertions.
56− * For potentially more performance, the assert methods can be
57− * commented out in each place where they are called.
59− // var MJS_DO_ASSERT = false;
62− * Constant: MJS_FLOAT_ARRAY_TYPE
64− * The base float array type. By default, WebGLFloatArray.
66− * mjs can work with any array-like elements, but if an array
67− * creation is requested, it will create an array of the type
68− * MJS_FLOAT_ARRAY_TYPE. Also, the builtin constants such as (M4x4.I)
69− * will be of this type.
71− //MJS_FLOAT_ARRAY_TYPE = WebGLFloatArray;
72− var MJS_FLOAT_ARRAY_TYPE = Float32Array;
73− //MJS_FLOAT_ARRAY_TYPE = Float64Array;
74− //MJS_FLOAT_ARRAY_TYPE = Array;
78− function MathUtils_assert(cond, msg) {
80− throw "Assertion failed: " + msg;
85− function MathUtils_assert() { }
91− * Methods for working with 3-element vectors. A vector is represented by a 3-element array.
92− * Any valid JavaScript array type may be used, but if new
93− * vectors are created they are created using the configured MJS_FLOAT_ARRAY_TYPE.
98− V3._temp1 = new MJS_FLOAT_ARRAY_TYPE(3);
99− V3._temp2 = new MJS_FLOAT_ARRAY_TYPE(3);
100− V3._temp3 = new MJS_FLOAT_ARRAY_TYPE(3);
102− if (MJS_FLOAT_ARRAY_TYPE == Array) {
103− V3.x = [1.0, 0.0, 0.0];
104− V3.y = [0.0, 1.0, 0.0];
105− V3.z = [0.0, 0.0, 1.0];
107− V3.$ = function V3_$(x, y, z) {
111− V3.x = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0]);
112− V3.y = new MJS_FLOAT_ARRAY_TYPE([0.0, 1.0, 0.0]);
113− V3.z = new MJS_FLOAT_ARRAY_TYPE([0.0, 0.0, 1.0]);
118− * Creates a new 3-element vector with the given values.
122− * x,y,z - the 3 elements of the new vector.
126− * A new vector containing with the given argument values.
129− V3.$ = function V3_$(x, y, z) {
130− return new MJS_FLOAT_ARRAY_TYPE([x, y, z]);
137− V3.getX = function V3_getX(a) {
140− V3.getY = function V3_getY(a) {
143− V3.getZ = function V3_getZ(a) {
146− V3.setX = function V3_setX(x, a) {
147− return new MJS_FLOAT_ARRAY_TYPE(x, a[1], a[2]);
149− V3.setY = function V3_setY(y, a) {
150− return new MJS_FLOAT_ARRAY_TYPE(a[0], y, a[2]);
152− V3.setZ = function V3_setZ(z, a) {
153− return new MJS_FLOAT_ARRAY_TYPE(a[0], a[1], z);
156− V3.toTuple3 = function V3_toTuple3(a) {
164− V3.fromTuple3 = function V3_fromTuple3(t) {
165− return new MJS_FLOAT_ARRAY_TYPE([t._0, t._1, t._2]);
168− V3.toRecord3 = function V3_toRecord3(a) {
176− V3.fromRecord3 = function V3_fromRecord3(r) {
177− return new MJS_FLOAT_ARRAY_TYPE([r.x, r.y, r.z]);
183− * Perform r = a + b.
187− * a - the first vector operand
188− * b - the second vector operand
189− * r - optional vector to store the result in
193− * If r is specified, returns r after performing the operation.
194− * Otherwise, returns a new 3-element vector with the result.
196− V3.add = function V3_add(a, b, r) {
197− //MathUtils_assert(a.length == 3, "a.length == 3");
198− //MathUtils_assert(b.length == 3, "b.length == 3");
199− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
202− r = new MJS_FLOAT_ARRAY_TYPE(3);
217− * a - the first vector operand
218− * b - the second vector operand
219− * r - optional vector to store the result in
223− * If r is specified, returns r after performing the operation.
224− * Otherwise, returns a new 3-element vector with the result.
226− V3.sub = function V3_sub(a, b, r) {
227− //MathUtils_assert(a.length == 3, "a.length == 3");
228− //MathUtils_assert(b.length == 3, "b.length == 3");
229− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
232− r = new MJS_FLOAT_ARRAY_TYPE(3);
247− * a - the vector operand
248− * r - optional vector to store the result in
252− * If r is specified, returns r after performing the operation.
253− * Otherwise, returns a new 3-element vector with the result.
255− V3.neg = function V3_neg(a, r) {
256− //MathUtils_assert(a.length == 3, "a.length == 3");
257− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
260− r = new MJS_FLOAT_ARRAY_TYPE(3);
268− * Function: V3.direction
271− * r = (a - b) / |a - b|. The result is the normalized
272− * direction from a to b.
276− * a - the first vector operand
277− * b - the second vector operand
278− * r - optional vector to store the result in
282− * If r is specified, returns r after performing the operation.
283− * Otherwise, returns a new 3-element vector with the result.
285− V3.direction = function V3_direction(a, b, r) {
286− //MathUtils_assert(a.length == 3, "a.length == 3");
287− //MathUtils_assert(b.length == 3, "b.length == 3");
288− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
291− r = new MJS_FLOAT_ARRAY_TYPE(3);
292− return V3.normalize(V3.sub(a, b, r), r);
296− * Function: V3.length
302− * a - the vector operand
306− * The length of the given vector.
308− V3.length = function V3_length(a) {
309− //MathUtils_assert(a.length == 3, "a.length == 3");
311− return Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
315− * Function: V3.lengthSquard
317− * Perform r = |a|*|a|.
321− * a - the vector operand
325− * The square of the length of the given vector.
327− V3.lengthSquared = function V3_lengthSquared(a) {
328− //MathUtils_assert(a.length == 3, "a.length == 3");
330− return a[0]*a[0] + a[1]*a[1] + a[2]*a[2];
333− V3.distance = function V3_distance(a, b) {
334− var dx = a[0] - b[0];
335− var dy = a[1] - b[1];
336− var dz = a[2] - b[2];
337− return Math.sqrt(dx * dx + dy * dy + dz * dz);
340− V3.distanceSquared = function V3_distanceSquared(a) {
341− var dx = a[0] - b[0];
342− var dy = a[1] - b[1];
343− var dz = a[2] - b[2];
344− return dx * dx + dy * dy + dz * dz;
348− * Function: V3.normalize
350− * Perform r = a / |a|.
354− * a - the vector operand
355− * r - optional vector to store the result in
359− * If r is specified, returns r after performing the operation.
360− * Otherwise, returns a new 3-element vector with the result.
362− V3.normalize = function V3_normalize(a, r) {
363− //MathUtils_assert(a.length == 3, "a.length == 3");
364− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
367− r = new MJS_FLOAT_ARRAY_TYPE(3);
368− var im = 1.0 / V3.length(a);
376− * Function: V3.scale
378− * Perform r = a * k.
382− * a - the vector operand
383− * k - a scalar value
384− * r - optional vector to store the result in
388− * If r is specified, returns r after performing the operation.
389− * Otherwise, returns a new 3-element vector with the result.
391− V3.scale = function V3_scale(a, k, r) {
392− //MathUtils_assert(a.length == 3, "a.length == 3");
393− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
396− r = new MJS_FLOAT_ARRAY_TYPE(3);
411− * a - the first vector operand
412− * b - the second vector operand
416− * The dot product of a and b.
418− V3.dot = function V3_dot(a, b) {
419− //MathUtils_assert(a.length == 3, "a.length == 3");
420− //MathUtils_assert(b.length == 3, "b.length == 3");
422− return a[0] * b[0] +
428− * Function: V3.cross
430− * Perform r = a x b.
434− * a - the first vector operand
435− * b - the second vector operand
436− * r - optional vector to store the result in
440− * If r is specified, returns r after performing the operation.
441− * Otherwise, returns a new 3-element vector with the result.
443− V3.cross = function V3_cross(a, b, r) {
444− //MathUtils_assert(a.length == 3, "a.length == 3");
445− //MathUtils_assert(b.length == 3, "b.length == 3");
446− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
449− r = new MJS_FLOAT_ARRAY_TYPE(3);
450− r[0] = a[1]*b[2] - a[2]*b[1];
451− r[1] = a[2]*b[0] - a[0]*b[2];
452− r[2] = a[0]*b[1] - a[1]*b[0];
457− * Function: V3.mul4x4
464− * m - the 4x4 matrix operand
465− * v - the 3-element vector operand
466− * r - optional vector to store the result in
470− * If r is specified, returns r after performing the operation.
471− * Otherwise, returns a new 3-element vector with the result.
472− * The 4-element result vector is divided by the w component
473− * and returned as a 3-element vector.
475− V3.mul4x4 = function V3_mul4x4(m, v, r) {
476− //MathUtils_assert(m.length == 16, "m.length == 16");
477− //MathUtils_assert(v.length == 3, "v.length == 3");
478− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
481− var tmp = V3._temp1;
483− r = new MJS_FLOAT_ARRAY_TYPE(3);
487− w = V3.dot(v, tmp) + m[15];
491− r[0] = (V3.dot(v, tmp) + m[12])/w;
495− r[1] = (V3.dot(v, tmp) + m[13])/w;
499− r[2] = (V3.dot(v, tmp) + m[14])/w;
506− * Methods for working with 4x4 matrices. A matrix is represented by a 16-element array
507− * in column-major order. Any valid JavaScript array type may be used, but if new
508− * matrices are created they are created using the configured MJS_FLOAT_ARRAY_TYPE.
513− M4x4._temp1 = new MJS_FLOAT_ARRAY_TYPE(16);
514− M4x4._temp2 = new MJS_FLOAT_ARRAY_TYPE(16);
516− if (MJS_FLOAT_ARRAY_TYPE == Array) {
517− M4x4.I = [1.0, 0.0, 0.0, 0.0,
520− 0.0, 0.0, 0.0, 1.0];
522− M4x4.$ = function M4x4_$(m00, m01, m02, m03,
527− return [m00, m01, m02, m03,
530− m12, m13, m14, m15];
533− M4x4.I = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0, 0.0,
536− 0.0, 0.0, 0.0, 1.0]);
541− * Creates a new 4x4 matrix with the given values.
545− * m00..m15 - the 16 elements of the new matrix.
549− * A new matrix filled with the given argument values.
551− M4x4.$ = function M4x4_$(m00, m01, m02, m03,
556− return new MJS_FLOAT_ARRAY_TYPE([m00, m01, m02, m03,
559− m12, m13, m14, m15]);
563− M4x4.identity = M4x4.I;
566− * Function: M4x4.topLeft3x3
568− * Return the top left 3x3 matrix from the given 4x4 matrix m.
573− * r - optional 3x3 matrix to store the result in
577− * If r is specified, returns r after performing the operation.
578− * Otherwise, returns a new 3x3 matrix with the result.
580− M4x4.topLeft3x3 = function M4x4_topLeft3x3(m, r) {
581− //MathUtils_assert(m.length == 16, "m.length == 16");
582− //MathUtils_assert(r == undefined || r.length == 9, "r == undefined || r.length == 9");
585− r = new MJS_FLOAT_ARRAY_TYPE(9);
586− r[0] = m[0]; r[1] = m[1]; r[2] = m[2];
587− r[3] = m[4]; r[4] = m[5]; r[5] = m[6];
588− r[6] = m[8]; r[7] = m[9]; r[8] = m[10];
593− * Function: M4x4.inverseOrthonormal
595− * Computes the inverse of the given matrix m, assuming that
596− * the matrix is orthonormal.
601− * r - optional 4x4 matrix to store the result in
605− * If r is specified, returns r after performing the operation.
606− * Otherwise, returns a new 4x4 matrix with the result.
608− M4x4.inverseOrthonormal = function M4x4_inverseOrthonormal(m, r) {
609− //MathUtils_assert(m.length == 16, "m.length == 16");
610− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
611− //MathUtils_assert(m != r, "m != r");
614− r = new MJS_FLOAT_ARRAY_TYPE(16);
615− M4x4.transpose(m, r);
616− var t = [m[12], m[13], m[14]];
617− r[3] = r[7] = r[11] = 0;
618− r[12] = -V3.dot([r[0], r[4], r[8]], t);
619− r[13] = -V3.dot([r[1], r[5], r[9]], t);
620− r[14] = -V3.dot([r[2], r[6], r[10]], t);
625− * Function: M4x4.inverseTo3x3
627− * Computes the inverse of the given matrix m, but calculates
628− * only the top left 3x3 values of the result.
633− * r - optional 3x3 matrix to store the result in
637− * If r is specified, returns r after performing the operation.
638− * Otherwise, returns a new 3x3 matrix with the result.
640− M4x4.inverseTo3x3 = function M4x4_inverseTo3x3(m, r) {
641− //MathUtils_assert(m.length == 16, "m.length == 16");
642− //MathUtils_assert(r == undefined || r.length == 9, "r == undefined || r.length == 9");
645− r = new MJS_FLOAT_ARRAY_TYPE(9);
647− var a11 = m[10]*m[5]-m[6]*m[9],
648− a21 = -m[10]*m[1]+m[2]*m[9],
649− a31 = m[6]*m[1]-m[2]*m[5],
650− a12 = -m[10]*m[4]+m[6]*m[8],
651− a22 = m[10]*m[0]-m[2]*m[8],
652− a32 = -m[6]*m[0]+m[2]*m[4],
653− a13 = m[9]*m[4]-m[5]*m[8],
654− a23 = -m[9]*m[0]+m[1]*m[8],
655− a33 = m[5]*m[0]-m[1]*m[4];
656− var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
657− if (det == 0) // no inverse
658− throw "matrix not invertible";
659− var idet = 1.0 / det;
675− * Function: M4x4.makeFrustum
677− * Creates a matrix for a projection frustum with the given parameters.
681− * left - the left coordinate of the frustum
682− * right- the right coordinate of the frustum
683− * bottom - the bottom coordinate of the frustum
684− * top - the top coordinate of the frustum
685− * znear - the near z distance of the frustum
686− * zfar - the far z distance of the frustum
687− * r - optional 4x4 matrix to store the result in
691− * If r is specified, returns r after creating the projection matrix.
692− * Otherwise, returns a new 4x4 matrix.
694− M4x4.makeFrustum = function M4x4_makeFrustum(left, right, bottom, top, znear, zfar, r) {
695− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
698− r = new MJS_FLOAT_ARRAY_TYPE(16);
700− var X = 2*znear/(right-left);
701− var Y = 2*znear/(top-bottom);
702− var A = (right+left)/(right-left);
703− var B = (top+bottom)/(top-bottom);
704− var C = -(zfar+znear)/(zfar-znear);
705− var D = -2*zfar*znear/(zfar-znear);
707− r[0] = 2*znear/(right-left);
712− r[5] = 2*znear/(top-bottom);
715− r[8] = (right+left)/(right-left);
716− r[9] = (top+bottom)/(top-bottom);
717− r[10] = -(zfar+znear)/(zfar-znear);
721− r[14] = -2*zfar*znear/(zfar-znear);
728− * Function: M4x4.makePerspective
730− * Creates a matrix for a perspective projection with the given parameters.
734− * fovy - field of view in the y axis, in degrees
735− * aspect - aspect ratio
736− * znear - the near z distance of the projection
737− * zfar - the far z distance of the projection
738− * r - optional 4x4 matrix to store the result in
742− * If r is specified, returns r after creating the projection matrix.
743− * Otherwise, returns a new 4x4 matrix.
745− M4x4.makePerspective = function M4x4_makePerspective (fovy, aspect, znear, zfar, r) {
746− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
748− var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
750− var xmin = ymin * aspect;
751− var xmax = ymax * aspect;
753− return M4x4.makeFrustum(xmin, xmax, ymin, ymax, znear, zfar, r);
757− * Function: M4x4.makeOrtho
759− * Creates a matrix for an orthogonal frustum projection with the given parameters.
763− * left - the left coordinate of the frustum
764− * right- the right coordinate of the frustum
765− * bottom - the bottom coordinate of the frustum
766− * top - the top coordinate of the frustum
767− * znear - the near z distance of the frustum
768− * zfar - the far z distance of the frustum
769− * r - optional 4x4 matrix to store the result in
773− * If r is specified, returns r after creating the projection matrix.
774− * Otherwise, returns a new 4x4 matrix.
776− M4x4.makeOrtho = function M4x4_makeOrtho (left, right, bottom, top, znear, zfar, r) {
777− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
780− r = new MJS_FLOAT_ARRAY_TYPE(16);
782− var tX = -(right+left)/(right-left);
783− var tY = -(top+bottom)/(top-bottom);
784− var tZ = -(zfar+znear)/(zfar-znear);
785− var X = 2 / (right-left);
786− var Y = 2 / (top-bottom);
787− var Z = -2 / (zfar-znear);
789− r[0] = 2 / (right-left);
794− r[5] = 2 / (top-bottom);
799− r[10] = -2 / (zfar-znear);
801− r[12] = -(right+left)/(right-left);
802− r[13] = -(top+bottom)/(top-bottom);
803− r[14] = -(zfar+znear)/(zfar-znear);
810− * Function: M4x4.makeOrtho2D
812− * Creates a matrix for a 2D orthogonal frustum projection with the given parameters.
813− * znear and zfar are assumed to be -1 and 1, respectively.
817− * left - the left coordinate of the frustum
818− * right- the right coordinate of the frustum
819− * bottom - the bottom coordinate of the frustum
820− * top - the top coordinate of the frustum
821− * r - optional 4x4 matrix to store the result in
825− * If r is specified, returns r after creating the projection matrix.
826− * Otherwise, returns a new 4x4 matrix.
828− M4x4.makeOrtho2D = function M4x4_makeOrtho2D (left, right, bottom, top, r) {
829− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
831− return M4x4.makeOrtho(left, right, bottom, top, -1, 1, r);
835− * Function: M4x4.mul
837− * Performs r = a * b.
841− * a - the first matrix operand
842− * b - the second matrix operand
843− * r - optional 4x4 matrix to store the result in
847− * If r is specified, returns r after performing the operation.
848− * Otherwise, returns a new 4x4 matrix with the result.
850− M4x4.mul = function M4x4_mul(a, b, r) {
851− //MathUtils_assert(a.length == 16, "a.length == 16");
852− //MathUtils_assert(b.length == 16, "b.length == 16");
853− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
854− //MathUtils_assert(a != r && b != r, "a != r && b != r");
857− r = new MJS_FLOAT_ARRAY_TYPE(16);
893− r[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
894− r[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
895− r[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
896− r[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
897− r[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
898− r[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
899− r[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
900− r[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
901− r[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
902− r[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
903− r[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
904− r[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
905− r[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
906− r[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
907− r[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
908− r[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
914− * Function: M4x4.mulAffine
916− * Performs r = a * b, assuming a and b are affine (elements 3,7,11,15 = 0,0,0,1)
920− * a - the first matrix operand
921− * b - the second matrix operand
922− * r - optional 4x4 matrix to store the result in
926− * If r is specified, returns r after performing the operation.
927− * Otherwise, returns a new 4x4 matrix with the result.
929− M4x4.mulAffine = function M4x4_mulAffine(a, b, r) {
930− //MathUtils_assert(a.length == 16, "a.length == 16");
931− //MathUtils_assert(b.length == 16, "b.length == 16");
932− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
933− //MathUtils_assert(a != r && b != r, "a != r && b != r");
936− r = new MJS_FLOAT_ARRAY_TYPE(16);
963− r[0] = a11 * b11 + a12 * b21 + a13 * b31;
964− r[1] = a21 * b11 + a22 * b21 + a23 * b31;
965− r[2] = a31 * b11 + a32 * b21 + a33 * b31;
967− r[4] = a11 * b12 + a12 * b22 + a13 * b32;
968− r[5] = a21 * b12 + a22 * b22 + a23 * b32;
969− r[6] = a31 * b12 + a32 * b22 + a33 * b32;
971− r[8] = a11 * b13 + a12 * b23 + a13 * b33;
972− r[9] = a21 * b13 + a22 * b23 + a23 * b33;
973− r[10] = a31 * b13 + a32 * b23 + a33 * b33;
975− r[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14;
976− r[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24;
977− r[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34;
984− * Function: M4x4.makeRotate
986− * Creates a transformation matrix for rotation by angle radians about the 3-element vector axis.
990− * angle - the angle of rotation, in radians
991− * axis - the axis around which the rotation is performed, a 3-element vector
992− * r - optional 4x4 matrix to store the result in
996− * If r is specified, returns r after creating the matrix.
997− * Otherwise, returns a new 4x4 matrix with the result.
999− M4x4.makeRotate = function M4x4_makeRotate(angle, axis, r) {
1000− //MathUtils_assert(angle.length == 3, "angle.length == 3");
1001− //MathUtils_assert(axis.length == 3, "axis.length == 3");
1002− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1004− if (r == undefined)
1005− r = new MJS_FLOAT_ARRAY_TYPE(16);
1007− axis = V3.normalize(axis, V3._temp1);
1008− var x = axis[0], y = axis[1], z = axis[2];
1009− var c = Math.cos(angle);
1011− var s = Math.sin(angle);
1034− * Function: M4x4.rotate
1036− * Concatenates a rotation of angle radians about the axis to the give matrix m.
1040− * angle - the angle of rotation, in radians
1041− * axis - the axis around which the rotation is performed, a 3-element vector
1042− * m - the matrix to concatenate the rotation to
1043− * r - optional 4x4 matrix to store the result in
1047− * If r is specified, returns r after performing the operation.
1048− * Otherwise, returns a new 4x4 matrix with the result.
1050− M4x4.rotate = function M4x4_rotate(angle, axis, m, r) {
1051− //MathUtils_assert(angle.length == 3, "angle.length == 3");
1052− //MathUtils_assert(axis.length == 3, "axis.length == 3");
1053− //MathUtils_assert(m.length == 16, "m.length == 16");
1054− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1056− if (r == undefined)
1057− r = new MJS_FLOAT_ARRAY_TYPE(16);
1058− var a0=axis [0], a1=axis [1], a2=axis [2];
1059− var l = Math.sqrt(a0*a0 + a1*a1 + a2*a2);
1060− var x = a0, y = a1, z = a2;
1067− var c = Math.cos(angle);
1069− var s = Math.sin(angle);
1073− var xyc1 = x * y * c1;
1074− var xzc1 = x * z * c1;
1075− var yzc1 = y * z * c1;
1090− var t11 = x * x * c1 + c;
1091− var t21 = xyc1 + zs;
1092− var t31 = xzc1 - ys;
1093− var t12 = xyc1 - zs;
1094− var t22 = y * y * c1 + c;
1095− var t32 = yzc1 + xs;
1096− var t13 = xzc1 + ys;
1097− var t23 = yzc1 - xs;
1098− var t33 = z * z * c1 + c;
1100− r[0] = m11 * t11 + m12 * t21 + m13 * t31;
1101− r[1] = m21 * t11 + m22 * t21 + m23 * t31;
1102− r[2] = m31 * t11 + m32 * t21 + m33 * t31;
1103− r[3] = m41 * t11 + m42 * t21 + m43 * t31;
1104− r[4] = m11 * t12 + m12 * t22 + m13 * t32;
1105− r[5] = m21 * t12 + m22 * t22 + m23 * t32;
1106− r[6] = m31 * t12 + m32 * t22 + m33 * t32;
1107− r[7] = m41 * t12 + m42 * t22 + m43 * t32;
1108− r[8] = m11 * t13 + m12 * t23 + m13 * t33;
1109− r[9] = m21 * t13 + m22 * t23 + m23 * t33;
1110− r[10] = m31 * t13 + m32 * t23 + m33 * t33;
1111− r[11] = m41 * t13 + m42 * t23 + m43 * t33;
1122− * Function: M4x4.makeScale3
1124− * Creates a transformation matrix for scaling by 3 scalar values, one for
1125− * each of the x, y, and z directions.
1129− * x - the scale for the x axis
1130− * y - the scale for the y axis
1131− * z - the scale for the z axis
1132− * r - optional 4x4 matrix to store the result in
1136− * If r is specified, returns r after creating the matrix.
1137− * Otherwise, returns a new 4x4 matrix with the result.
1139− M4x4.makeScale3 = function M4x4_makeScale3(x, y, z, r) {
1140− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1142− if (r == undefined)
1143− r = new MJS_FLOAT_ARRAY_TYPE(16);
1166− * Function: M4x4.makeScale1
1168− * Creates a transformation matrix for a uniform scale by a single scalar value.
1172− * k - the scale factor
1173− * r - optional 4x4 matrix to store the result in
1177− * If r is specified, returns r after creating the matrix.
1178− * Otherwise, returns a new 4x4 matrix with the result.
1180− M4x4.makeScale1 = function M4x4_makeScale1(k, r) {
1181− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1183− return M4x4.makeScale3(k, k, k, r);
1187− * Function: M4x4.makeScale
1189− * Creates a transformation matrix for scaling each of the x, y, and z axes by the amount
1190− * given in the corresponding element of the 3-element vector.
1194− * v - the 3-element vector containing the scale factors
1195− * r - optional 4x4 matrix to store the result in
1199− * If r is specified, returns r after creating the matrix.
1200− * Otherwise, returns a new 4x4 matrix with the result.
1202− M4x4.makeScale = function M4x4_makeScale(v, r) {
1203− //MathUtils_assert(v.length == 3, "v.length == 3");
1204− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1206− return M4x4.makeScale3(v[0], v[1], v[2], r);
1210− * Function: M4x4.scale3
1212− M4x4.scale3 = function M4x4_scale3(x, y, z, m, r) {
1213− //MathUtils_assert(m.length == 16, "m.length == 16");
1214− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1232− if (r == undefined)
1233− r = new MJS_FLOAT_ARRAY_TYPE(16);
1256− * Function: M4x4.scale1
1258− M4x4.scale1 = function M4x4_scale1(k, m, r) {
1259− //MathUtils_assert(m.length == 16, "m.length == 16");
1260− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1278− if (r == undefined)
1279− r = new MJS_FLOAT_ARRAY_TYPE(16);
1302− * Function: M4x4.scale1
1304− M4x4.scale = function M4x4_scale(v, m, r) {
1305− //MathUtils_assert(v.length == 3, "v.length == 3");
1306− //MathUtils_assert(m.length == 16, "m.length == 16");
1307− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1308− var x = v[0], y = v[1], z = v[2];
1326− if (r == undefined)
1327− r = new MJS_FLOAT_ARRAY_TYPE(16);
1351− * Function: M4x4.makeTranslate3
1353− M4x4.makeTranslate3 = function M4x4_makeTranslate3(x, y, z, r) {
1354− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1356− if (r == undefined)
1357− r = new MJS_FLOAT_ARRAY_TYPE(16);
1380− * Function: M4x4.makeTranslate1
1382− M4x4.makeTranslate1 = function M4x4_makeTranslate1 (k, r) {
1383− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1385− return M4x4.makeTranslate3(k, k, k, r);
1389− * Function: M4x4.makeTranslate
1391− M4x4.makeTranslate = function M4x4_makeTranslate (v, r) {
1392− //MathUtils_assert(v.length == 3, "v.length == 3");
1393− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1395− return M4x4.makeTranslate3(v[0], v[1], v[2], r);
1399− * Function: M4x4.translate3Self
1401− M4x4.translate3Self = function M4x4_translate3Self (x, y, z, m) {
1402− //MathUtils_assert(m.length == 16, "m.length == 16");
1403− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1404− m[12] += m[0] * x + m[4] * y + m[8] * z;
1405− m[13] += m[1] * x + m[5] * y + m[9] * z;
1406− m[14] += m[2] * x + m[6] * y + m[10] * z;
1407− m[15] += m[3] * x + m[7] * y + m[11] * z;
1412− * Function: M4x4.translate3
1414− M4x4.translate3 = function M4x4_translate3 (x, y, z, m, r) {
1415− //MathUtils_assert(m.length == 16, "m.length == 16");
1416− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1419− m[12] += m[0] * x + m[4] * y + m[8] * z;
1420− m[13] += m[1] * x + m[5] * y + m[9] * z;
1421− m[14] += m[2] * x + m[6] * y + m[10] * z;
1422− m[15] += m[3] * x + m[7] * y + m[11] * z;
1426− if (r == undefined)
1427− r = new MJS_FLOAT_ARRAY_TYPE(16);
1455− r[12] = m11 * x + m12 * y + m13 * z + m[12];
1456− r[13] = m21 * x + m22 * y + m23 * z + m[13];
1457− r[14] = m31 * x + m32 * y + m33 * z + m[14];
1458− r[15] = m41 * x + m42 * y + m43 * z + m[15];
1464− * Function: M4x4.translate1
1466− M4x4.translate1 = function M4x4_translate1 (k, m, r) {
1467− //MathUtils_assert(m.length == 16, "m.length == 16");
1468− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1470− return M4x4.translate3(k, k, k, m, r);
1473− * Function: M4x4.translateSelf
1475− M4x4.translateSelf = function M4x4_translateSelf (v, m) {
1476− //MathUtils_assert(v.length == 3, "v.length == 3");
1477− //MathUtils_assert(m.length == 16, "m.length == 16");
1478− var x=v[0], y=v[1], z=v[2];
1479− m[12] += m[0] * x + m[4] * y + m[8] * z;
1480− m[13] += m[1] * x + m[5] * y + m[9] * z;
1481− m[14] += m[2] * x + m[6] * y + m[10] * z;
1482− m[15] += m[3] * x + m[7] * y + m[11] * z;
1486− * Function: M4x4.translate
1488− M4x4.translate = function M4x4_translate (v, m, r) {
1489− //MathUtils_assert(v.length == 3, "v.length == 3");
1490− //MathUtils_assert(m.length == 16, "m.length == 16");
1491− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1492− var x=v[0], y=v[1], z=v[2];
1494− m[12] += m[0] * x + m[4] * y + m[8] * z;
1495− m[13] += m[1] * x + m[5] * y + m[9] * z;
1496− m[14] += m[2] * x + m[6] * y + m[10] * z;
1497− m[15] += m[3] * x + m[7] * y + m[11] * z;
1501− if (r == undefined)
1502− r = new MJS_FLOAT_ARRAY_TYPE(16);
1529− r[12] = m11 * x + m12 * y + m13 * z + m[12];
1530− r[13] = m21 * x + m22 * y + m23 * z + m[13];
1531− r[14] = m31 * x + m32 * y + m33 * z + m[14];
1532− r[15] = m41 * x + m42 * y + m43 * z + m[15];
1538− * Function: M4x4.makeLookAt
1540− M4x4.makeLookAt = function M4x4_makeLookAt (eye, center, up, r) {
1541− //MathUtils_assert(eye.length == 3, "eye.length == 3");
1542− //MathUtils_assert(center.length == 3, "center.length == 3");
1543− //MathUtils_assert(up.length == 3, "up.length == 3");
1544− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1546− var z = V3.direction(eye, center, V3._temp1);
1547− var x = V3.normalize(V3.cross(up, z, V3._temp2), V3._temp2);
1548− var y = V3.normalize(V3.cross(z, x, V3._temp3), V3._temp3);
1550− var tm1 = M4x4._temp1;
1551− var tm2 = M4x4._temp2;
1570− tm2[0] = 1; tm2[1] = 0; tm2[2] = 0; tm2[3] = 0;
1571− tm2[4] = 0; tm2[5] = 1; tm2[6] = 0; tm2[7] = 0;
1572− tm2[8] = 0; tm2[9] = 0; tm2[10] = 1; tm2[11] = 0;
1573− tm2[12] = -eye[0]; tm2[13] = -eye[1]; tm2[14] = -eye[2]; tm2[15] = 1;
1575− if (r == undefined)
1576− r = new MJS_FLOAT_ARRAY_TYPE(16);
1577− return M4x4.mul(tm1, tm2, r);
1581− * Function: M4x4.transposeSelf
1583− M4x4.transposeSelf = function M4x4_transposeSelf (m) {
1584− //MathUtils_assert(m.length == 16, "m.length == 16");
1585− var tmp = m[1]; m[1] = m[4]; m[4] = tmp;
1586− tmp = m[2]; m[2] = m[8]; m[8] = tmp;
1587− tmp = m[3]; m[3] = m[12]; m[12] = tmp;
1588− tmp = m[6]; m[6] = m[9]; m[9] = tmp;
1589− tmp = m[7]; m[7] = m[13]; m[13] = tmp;
1590− tmp = m[11]; m[11] = m[14]; m[14] = tmp;
1594− * Function: M4x4.transpose
1596− M4x4.transpose = function M4x4_transpose (m, r) {
1597− //MathUtils_assert(m.length == 16, "m.length == 16");
1598− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1602− tmp = m[1]; m[1] = m[4]; m[4] = tmp;
1603− tmp = m[2]; m[2] = m[8]; m[8] = tmp;
1604− tmp = m[3]; m[3] = m[12]; m[12] = tmp;
1605− tmp = m[6]; m[6] = m[9]; m[9] = tmp;
1606− tmp = m[7]; m[7] = m[13]; m[13] = tmp;
1607− tmp = m[11]; m[11] = m[14]; m[14] = tmp;
1611− if (r == undefined)
1612− r = new MJS_FLOAT_ARRAY_TYPE(16);
1614− r[0] = m[0]; r[1] = m[4]; r[2] = m[8]; r[3] = m[12];
1615− r[4] = m[1]; r[5] = m[5]; r[6] = m[9]; r[7] = m[13];
1616− r[8] = m[2]; r[9] = m[6]; r[10] = m[10]; r[11] = m[14];
1617− r[12] = m[3]; r[13] = m[7]; r[14] = m[11]; r[15] = m[15];
1624− * Function: M4x4.transformPoint
1626− M4x4.transformPoint = function M4x4_transformPoint (m, v, r) {
1627− //MathUtils_assert(m.length == 16, "m.length == 16");
1628− //MathUtils_assert(v.length == 3, "v.length == 3");
1629− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1630− if (r == undefined)
1631− r = new MJS_FLOAT_ARRAY_TYPE(3);
1633− var v0 = v[0], v1 = v[1], v2 = v[2];
1635− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12];
1636− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13];
1637− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14];
1638− var w = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15];
1650− * Function: M4x4.transformLine
1652− M4x4.transformLine = function M4x4_transformLine(m, v, r) {
1653− //MathUtils_assert(m.length == 16, "m.length == 16");
1654− //MathUtils_assert(v.length == 3, "v.length == 3");
1655− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1656− if (r == undefined)
1657− r = new MJS_FLOAT_ARRAY_TYPE(3);
1659− var v0 = v[0], v1 = v[1], v2 = v[2];
1660− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2;
1661− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2;
1662− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2;
1663− var w = m[3] * v0 + m[7] * v1 + m[11] * v2;
1676− * Function: M4x4.transformPointAffine
1678− M4x4.transformPointAffine = function M4x4_transformPointAffine (m, v, r) {
1679− //MathUtils_assert(m.length == 16, "m.length == 16");
1680− //MathUtils_assert(v.length == 3, "v.length == 3");
1681− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1682− if (r == undefined)
1683− r = new MJS_FLOAT_ARRAY_TYPE(3);
1685− var v0 = v[0], v1 = v[1], v2 = v[2];
1687− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12];
1688− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13];
1689− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14];
1695− * Function: M4x4.transformLineAffine
1697− M4x4.transformLineAffine = function M4x4_transformLineAffine(m, v, r) {
1698− //MathUtils_assert(m.length == 16, "m.length == 16");
1699− //MathUtils_assert(v.length == 3, "v.length == 3");
1700− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1701− if (r == undefined)
1702− r = new MJS_FLOAT_ARRAY_TYPE(3);
1704− var v0 = v[0], v1 = v[1], v2 = v[2];
1705− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2;
1706− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2;
1707− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2;
1712− M4x4.makeBasis = function M4x4_makeBasis(vx,vy,vz) {
1714− var r = new MJS_FLOAT_ARRAY_TYPE(16);
1742− v3setX: F2(V3.setX),
1743− v3setY: F2(V3.setY),
1744− v3setZ: F2(V3.setZ),
1745− toTuple3: V3.toTuple3,
1746− toRecord3: V3.toRecord3,
1747− fromTuple3: V3.fromTuple3,
1748− fromRecord3: V3.fromRecord3,
1752− v3direction: F2(V3.direction),
1753− v3length: V3.length,
1754− v3lengthSquared: V3.lengthSquared,
1755− v3distance: F2(V3.distance),
1756− v3distanceSquared: F2(V3.distanceSquared),
1757− v3normalize: V3.normalize,
1758− v3scale: F2(V3.scale),
1760− v3cross: F2(V3.cross),
1761− v3mul4x4: F2(V3.mul4x4),
1762− m4x4identity: M4x4.identity,
1763− m4x4topLeft3x3: M4x4.topLeft3x3,
1764− m4x4inverseOrthonormal: M4x4.inverseOrthonormal,
1765− m4x4inverseTo3x3: M4x4.inverseTo3x3,
1766− m4x4makeFrustum: F6(M4x4.makeFrustum),
1767− m4x4makePerspective: F4(M4x4.makePerspective),
1768− m4x4makeOrtho: F6(M4x4.makeOrtho),
1769− m4x4makeOrtho2D: F4(M4x4.makeOrtho2D),
1770− m4x4mul: F2(M4x4.mul),
1771− m4x4Affine: F2(M4x4.mulAffine),
1772− m4x4makeRotate: F2(M4x4.makeRotate),
1773− m4x4rotate: F3(M4x4.rotate),
1774− m4x4makeScale3: F3(M4x4.makeScale3),
1775− m4x4makeScale1: M4x4.makeScale1,
1776− m4x4makeScale: M4x4.makeScale,
1777− m4x4scale3: F4(M4x4.scale3),
1778− m4x4scale: F2(M4x4.scale),
1779− m4x4makeTranslate3: F3(M4x4.makeTranslate3),
1780− m4x4makeTranslate: M4x4.makeTranslate,
1781− m4x4translate3: F4(M4x4.translate3),
1782− m4x4translate: F2(M4x4.translate),
1783− m4x4makeLookAt: F3(M4x4.makeLookAt),
1784− m4x4transpose: M4x4.transpose,
1785− m4x4transformPoint: F2(M4x4.transformPoint),
1786− m4x4makeBasis: F3(M4x4.makeBasis)