@@ -0,0 +1,1896 @@
1+
2+/*
3+ * Copyright (c) 2010 Mozilla Corporation
4+ * Copyright (c) 2010 Vladimir Vukicevic
5+ * Copyright (c) 2013 John Mayer
6+ *
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
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
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.
27+ */
28+
29+/*
30+ * File: mjs
31+ *
32+ * Vector and Matrix math utilities for JavaScript, optimized for WebGL.
33+ * Edited to work with Elm Programming Language
34+ */
35+
36+Elm.Native.MJS = {};
37+Elm.Native.MJS.make = function(elm) {
38+
39+ elm.Native = elm.Native || {};
40+ elm.Native.MJS = elm.Native.MJS || {};
41+ if (elm.Native.WebGL.values) return elm.Native.WebGL.values;
42+
43+ /*
44+ * Constant: MJS_VERSION
45+ *
46+ * mjs version number aa.bb.cc, encoded as an integer of the form:
47+ * 0xaabbcc.
48+ */
49+ const MJS_VERSION = 0x000000;
50+
51+ /*
52+ * Constant: MJS_DO_ASSERT
53+ *
54+ * Enables or disables runtime assertions.
55+ *
56+ * For potentially more performance, the assert methods can be
57+ * commented out in each place where they are called.
58+ */
59+ const MJS_DO_ASSERT = true;
60+
61+ // Some hacks for running in both the shell and browser,
62+ // and for supporting F32 and WebGLFloat arrays
63+ try { WebGLFloatArray; } catch (x) { WebGLFloatArray = Float32Array; }
64+
65+ /*
66+ * Constant: MJS_FLOAT_ARRAY_TYPE
67+ *
68+ * The base float array type. By default, WebGLFloatArray.
69+ *
70+ * mjs can work with any array-like elements, but if an array
71+ * creation is requested, it will create an array of the type
72+ * MJS_FLOAT_ARRAY_TYPE. Also, the builtin constants such as (M4x4.I)
73+ * will be of this type.
74+ */
75+ const MJS_FLOAT_ARRAY_TYPE = WebGLFloatArray;
76+ //const MJS_FLOAT_ARRAY_TYPE = Float32Array;
77+ //const MJS_FLOAT_ARRAY_TYPE = Float64Array;
78+ //const MJS_FLOAT_ARRAY_TYPE = Array;
79+
80+ if (MJS_DO_ASSERT) {
81+ function MathUtils_assert(cond, msg) {
82+ if (!cond)
83+ throw "Assertion failed: " + msg;
84+ }
85+ } else {
86+ function MathUtils_assert() { }
87+ }
88+
89+ /*
90+ * Class: V3
91+ *
92+ * Methods for working with 3-element vectors. A vector is represented by a 3-element array.
93+ * Any valid JavaScript array type may be used, but if new
94+ * vectors are created they are created using the configured MJS_FLOAT_ARRAY_TYPE.
95+ */
96+
97+ var V3 = { };
98+
99+ V3._temp1 = new MJS_FLOAT_ARRAY_TYPE(3);
100+ V3._temp2 = new MJS_FLOAT_ARRAY_TYPE(3);
101+ V3._temp3 = new MJS_FLOAT_ARRAY_TYPE(3);
102+
103+ if (MJS_FLOAT_ARRAY_TYPE == Array) {
104+ V3.x = [1.0, 0.0, 0.0];
105+ V3.y = [0.0, 1.0, 0.0];
106+ V3.z = [0.0, 0.0, 1.0];
107+
108+ V3.$ = function V3_$(x, y, z) {
109+ return [x, y, z];
110+ };
111+
112+ V3.clone = function V3_clone(a) {
113+ //MathUtils_assert(a.length == 3, "a.length == 3");
114+ return [a[0], a[1], a[2]];
115+ };
116+ } else {
117+ V3.x = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0]);
118+ V3.y = new MJS_FLOAT_ARRAY_TYPE([0.0, 1.0, 0.0]);
119+ V3.z = new MJS_FLOAT_ARRAY_TYPE([0.0, 0.0, 1.0]);
120+
121+ /*
122+ * Function: V3.$
123+ *
124+ * Creates a new 3-element vector with the given values.
125+ *
126+ * Parameters:
127+ *
128+ * x,y,z - the 3 elements of the new vector.
129+ *
130+ * Returns:
131+ *
132+ * A new vector containing with the given argument values.
133+ */
134+
135+ V3.$ = function V3_$(x, y, z) {
136+ return new MJS_FLOAT_ARRAY_TYPE([x, y, z]);
137+ };
138+
139+ /*
140+ * Function: V3.clone
141+ *
142+ * Clone the given 3-element vector.
143+ *
144+ * Parameters:
145+ *
146+ * a - the 3-element vector to clone
147+ *
148+ * Returns:
149+ *
150+ * A new vector with the same values as the passed-in one.
151+ */
152+
153+ V3.clone = function V3_clone(a) {
154+ //MathUtils_assert(a.length == 3, "a.length == 3");
155+ return new MJS_FLOAT_ARRAY_TYPE(a);
156+ };
157+ }
158+
159+ V3.u = V3.x;
160+ V3.v = V3.y;
161+
162+ /*
163+ * Function: V3.add
164+ *
165+ * Perform r = a + b.
166+ *
167+ * Parameters:
168+ *
169+ * a - the first vector operand
170+ * b - the second vector operand
171+ * r - optional vector to store the result in
172+ *
173+ * Returns:
174+ *
175+ * If r is specified, returns r after performing the operation.
176+ * Otherwise, returns a new 3-element vector with the result.
177+ */
178+ V3.add = function V3_add(a, b, r) {
179+ //MathUtils_assert(a.length == 3, "a.length == 3");
180+ //MathUtils_assert(b.length == 3, "b.length == 3");
181+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
182+
183+ if (r == undefined)
184+ r = new MJS_FLOAT_ARRAY_TYPE(3);
185+ r[0] = a[0] + b[0];
186+ r[1] = a[1] + b[1];
187+ r[2] = a[2] + b[2];
188+ return r;
189+ };
190+
191+ /*
192+ * Function: V3.sub
193+ *
194+ * Perform
195+ * r = a - b.
196+ *
197+ * Parameters:
198+ *
199+ * a - the first vector operand
200+ * b - the second vector operand
201+ * r - optional vector to store the result in
202+ *
203+ * Returns:
204+ *
205+ * If r is specified, returns r after performing the operation.
206+ * Otherwise, returns a new 3-element vector with the result.
207+ */
208+ V3.sub = function V3_sub(a, b, r) {
209+ //MathUtils_assert(a.length == 3, "a.length == 3");
210+ //MathUtils_assert(b.length == 3, "b.length == 3");
211+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
212+
213+ if (r == undefined)
214+ r = new MJS_FLOAT_ARRAY_TYPE(3);
215+ r[0] = a[0] - b[0];
216+ r[1] = a[1] - b[1];
217+ r[2] = a[2] - b[2];
218+ return r;
219+ };
220+
221+ /*
222+ * Function: V3.neg
223+ *
224+ * Perform
225+ * r = - a.
226+ *
227+ * Parameters:
228+ *
229+ * a - the vector operand
230+ * r - optional vector to store the result in
231+ *
232+ * Returns:
233+ *
234+ * If r is specified, returns r after performing the operation.
235+ * Otherwise, returns a new 3-element vector with the result.
236+ */
237+ V3.neg = function V3_neg(a, r) {
238+ //MathUtils_assert(a.length == 3, "a.length == 3");
239+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
240+
241+ if (r == undefined)
242+ r = new MJS_FLOAT_ARRAY_TYPE(3);
243+ r[0] = - a[0];
244+ r[1] = - a[1];
245+ r[2] = - a[2];
246+ return r;
247+ };
248+
249+ /*
250+ * Function: V3.direction
251+ *
252+ * Perform
253+ * r = (a - b) / |a - b|. The result is the normalized
254+ * direction from a to b.
255+ *
256+ * Parameters:
257+ *
258+ * a - the first vector operand
259+ * b - the second vector operand
260+ * r - optional vector to store the result in
261+ *
262+ * Returns:
263+ *
264+ * If r is specified, returns r after performing the operation.
265+ * Otherwise, returns a new 3-element vector with the result.
266+ */
267+ V3.direction = function V3_direction(a, b, r) {
268+ //MathUtils_assert(a.length == 3, "a.length == 3");
269+ //MathUtils_assert(b.length == 3, "b.length == 3");
270+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
271+
272+ if (r == undefined)
273+ r = new MJS_FLOAT_ARRAY_TYPE(3);
274+ return V3.normalize(V3.sub(a, b, r), r);
275+ };
276+
277+ /*
278+ * Function: V3.length
279+ *
280+ * Perform r = |a|.
281+ *
282+ * Parameters:
283+ *
284+ * a - the vector operand
285+ *
286+ * Returns:
287+ *
288+ * The length of the given vector.
289+ */
290+ V3.length = function V3_length(a) {
291+ //MathUtils_assert(a.length == 3, "a.length == 3");
292+
293+ return Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
294+ };
295+
296+ /*
297+ * Function: V3.lengthSquard
298+ *
299+ * Perform r = |a|*|a|.
300+ *
301+ * Parameters:
302+ *
303+ * a - the vector operand
304+ *
305+ * Returns:
306+ *
307+ * The square of the length of the given vector.
308+ */
309+ V3.lengthSquared = function V3_lengthSquared(a) {
310+ //MathUtils_assert(a.length == 3, "a.length == 3");
311+
312+ return a[0]*a[0] + a[1]*a[1] + a[2]*a[2];
313+ };
314+
315+ /*
316+ * Function: V3.normalize
317+ *
318+ * Perform r = a / |a|.
319+ *
320+ * Parameters:
321+ *
322+ * a - the vector operand
323+ * r - optional vector to store the result in
324+ *
325+ * Returns:
326+ *
327+ * If r is specified, returns r after performing the operation.
328+ * Otherwise, returns a new 3-element vector with the result.
329+ */
330+ V3.normalize = function V3_normalize(a, r) {
331+ //MathUtils_assert(a.length == 3, "a.length == 3");
332+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
333+
334+ if (r == undefined)
335+ r = new MJS_FLOAT_ARRAY_TYPE(3);
336+ var im = 1.0 / V3.length(a);
337+ r[0] = a[0] * im;
338+ r[1] = a[1] * im;
339+ r[2] = a[2] * im;
340+ return r;
341+ };
342+
343+ /*
344+ * Function: V3.scale
345+ *
346+ * Perform r = a * k.
347+ *
348+ * Parameters:
349+ *
350+ * a - the vector operand
351+ * k - a scalar value
352+ * r - optional vector to store the result in
353+ *
354+ * Returns:
355+ *
356+ * If r is specified, returns r after performing the operation.
357+ * Otherwise, returns a new 3-element vector with the result.
358+ */
359+ V3.scale = function V3_scale(a, k, r) {
360+ //MathUtils_assert(a.length == 3, "a.length == 3");
361+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
362+
363+ if (r == undefined)
364+ r = new MJS_FLOAT_ARRAY_TYPE(3);
365+ r[0] = a[0] * k;
366+ r[1] = a[1] * k;
367+ r[2] = a[2] * k;
368+ return r;
369+ };
370+
371+ /*
372+ * Function: V3.dot
373+ *
374+ * Perform
375+ * r = dot(a, b).
376+ *
377+ * Parameters:
378+ *
379+ * a - the first vector operand
380+ * b - the second vector operand
381+ *
382+ * Returns:
383+ *
384+ * The dot product of a and b.
385+ */
386+ V3.dot = function V3_dot(a, b) {
387+ //MathUtils_assert(a.length == 3, "a.length == 3");
388+ //MathUtils_assert(b.length == 3, "b.length == 3");
389+
390+ return a[0] * b[0] +
391+ a[1] * b[1] +
392+ a[2] * b[2];
393+ };
394+
395+ /*
396+ * Function: V3.cross
397+ *
398+ * Perform r = a x b.
399+ *
400+ * Parameters:
401+ *
402+ * a - the first vector operand
403+ * b - the second vector operand
404+ * r - optional vector to store the result in
405+ *
406+ * Returns:
407+ *
408+ * If r is specified, returns r after performing the operation.
409+ * Otherwise, returns a new 3-element vector with the result.
410+ */
411+ V3.cross = function V3_cross(a, b, r) {
412+ //MathUtils_assert(a.length == 3, "a.length == 3");
413+ //MathUtils_assert(b.length == 3, "b.length == 3");
414+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
415+
416+ if (r == undefined)
417+ r = new MJS_FLOAT_ARRAY_TYPE(3);
418+ r[0] = a[1]*b[2] - a[2]*b[1];
419+ r[1] = a[2]*b[0] - a[0]*b[2];
420+ r[2] = a[0]*b[1] - a[1]*b[0];
421+ return r;
422+ };
423+
424+ /*
425+ * Function: V3.mul4x4
426+ *
427+ * Perform
428+ * r = m * v.
429+ *
430+ * Parameters:
431+ *
432+ * m - the 4x4 matrix operand
433+ * v - the 3-element vector operand
434+ * r - optional vector to store the result in
435+ *
436+ * Returns:
437+ *
438+ * If r is specified, returns r after performing the operation.
439+ * Otherwise, returns a new 3-element vector with the result.
440+ * The 4-element result vector is divided by the w component
441+ * and returned as a 3-element vector.
442+ */
443+ V3.mul4x4 = function V3_mul4x4(m, v, r) {
444+ //MathUtils_assert(m.length == 16, "m.length == 16");
445+ //MathUtils_assert(v.length == 3, "v.length == 3");
446+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
447+
448+ var w;
449+ var tmp = V3._temp1;
450+ if (r == undefined)
451+ r = new MJS_FLOAT_ARRAY_TYPE(3);
452+ tmp[0] = m[ 3];
453+ tmp[1] = m[ 7];
454+ tmp[2] = m[11];
455+ w = V3.dot(v, tmp) + m[15];
456+ tmp[0] = m[ 0];
457+ tmp[1] = m[ 4];
458+ tmp[2] = m[ 8];
459+ r[0] = (V3.dot(v, tmp) + m[12])/w;
460+ tmp[0] = m[ 1];
461+ tmp[1] = m[ 5];
462+ tmp[2] = m[ 9];
463+ r[1] = (V3.dot(v, tmp) + m[13])/w;
464+ tmp[0] = m[ 2];
465+ tmp[1] = m[ 6];
466+ tmp[2] = m[10];
467+ r[2] = (V3.dot(v, tmp) + m[14])/w;
468+ return r;
469+ };
470+
471+ /*
472+ * Class: M4x4
473+ *
474+ * Methods for working with 4x4 matrices. A matrix is represented by a 16-element array
475+ * in column-major order. Any valid JavaScript array type may be used, but if new
476+ * matrices are created they are created using the configured MJS_FLOAT_ARRAY_TYPE.
477+ */
478+
479+ var M4x4 = { };
480+
481+ M4x4._temp1 = new MJS_FLOAT_ARRAY_TYPE(16);
482+ M4x4._temp2 = new MJS_FLOAT_ARRAY_TYPE(16);
483+
484+ if (MJS_FLOAT_ARRAY_TYPE == Array) {
485+ M4x4.I = [1.0, 0.0, 0.0, 0.0,
486+ 0.0, 1.0, 0.0, 0.0,
487+ 0.0, 0.0, 1.0, 0.0,
488+ 0.0, 0.0, 0.0, 1.0];
489+
490+ M4x4.$ = function M4x4_$(m00, m01, m02, m03,
491+ m04, m05, m06, m07,
492+ m08, m09, m10, m11,
493+ m12, m13, m14, m15)
494+ {
495+ return [m00, m01, m02, m03,
496+ m04, m05, m06, m07,
497+ m08, m09, m10, m11,
498+ m12, m13, m14, m15];
499+ };
500+
501+ M4x4.clone = function M4x4_clone(m) {
502+ //MathUtils_assert(m.length == 16, "m.length == 16");
503+ return new [m[0], m[1], m[2], m[3],
504+ m[4], m[5], m[6], m[7],
505+ m[8], m[9], m[10], m[11],
506+ m[12], m[13], m[14], m[15]];
507+ };
508+ } else {
509+ M4x4.I = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0, 0.0,
510+ 0.0, 1.0, 0.0, 0.0,
511+ 0.0, 0.0, 1.0, 0.0,
512+ 0.0, 0.0, 0.0, 1.0]);
513+
514+ /*
515+ * Function: M4x4.$
516+ *
517+ * Creates a new 4x4 matrix with the given values.
518+ *
519+ * Parameters:
520+ *
521+ * m00..m15 - the 16 elements of the new matrix.
522+ *
523+ * Returns:
524+ *
525+ * A new matrix filled with the given argument values.
526+ */
527+ M4x4.$ = function M4x4_$(m00, m01, m02, m03,
528+ m04, m05, m06, m07,
529+ m08, m09, m10, m11,
530+ m12, m13, m14, m15)
531+ {
532+ return new MJS_FLOAT_ARRAY_TYPE([m00, m01, m02, m03,
533+ m04, m05, m06, m07,
534+ m08, m09, m10, m11,
535+ m12, m13, m14, m15]);
536+ };
537+
538+ /*
539+ * Function: M4x4.clone
540+ *
541+ * Clone the given 4x4 matrix.
542+ *
543+ * Parameters:
544+ *
545+ * m - the 4x4 matrix to clone
546+ *
547+ * Returns:
548+ *
549+ * A new matrix with the same values as the passed-in one.
550+ */
551+ M4x4.clone = function M4x4_clone(m) {
552+ //MathUtils_assert(m.length == 16, "m.length == 16");
553+ return new MJS_FLOAT_ARRAY_TYPE(m);
554+ };
555+ }
556+
557+ M4x4.identity = M4x4.I;
558+
559+ /*
560+ * Function: M4x4.topLeft3x3
561+ *
562+ * Return the top left 3x3 matrix from the given 4x4 matrix m.
563+ *
564+ * Parameters:
565+ *
566+ * m - the matrix
567+ * r - optional 3x3 matrix to store the result in
568+ *
569+ * Returns:
570+ *
571+ * If r is specified, returns r after performing the operation.
572+ * Otherwise, returns a new 3x3 matrix with the result.
573+ */
574+ M4x4.topLeft3x3 = function M4x4_topLeft3x3(m, r) {
575+ //MathUtils_assert(m.length == 16, "m.length == 16");
576+ //MathUtils_assert(r == undefined || r.length == 9, "r == undefined || r.length == 9");
577+
578+ if (r == undefined)
579+ r = new MJS_FLOAT_ARRAY_TYPE(9);
580+ r[0] = m[0]; r[1] = m[1]; r[2] = m[2];
581+ r[3] = m[4]; r[4] = m[5]; r[5] = m[6];
582+ r[6] = m[8]; r[7] = m[9]; r[8] = m[10];
583+ return r;
584+ };
585+
586+ /*
587+ * Function: M4x4.inverseOrthonormal
588+ *
589+ * Computes the inverse of the given matrix m, assuming that
590+ * the matrix is orthonormal.
591+ *
592+ * Parameters:
593+ *
594+ * m - the matrix
595+ * r - optional 4x4 matrix to store the result in
596+ *
597+ * Returns:
598+ *
599+ * If r is specified, returns r after performing the operation.
600+ * Otherwise, returns a new 4x4 matrix with the result.
601+ */
602+ M4x4.inverseOrthonormal = function M4x4_inverseOrthonormal(m, r) {
603+ //MathUtils_assert(m.length == 16, "m.length == 16");
604+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
605+ //MathUtils_assert(m != r, "m != r");
606+
607+ if (r == undefined)
608+ r = new MJS_FLOAT_ARRAY_TYPE(16);
609+ M4x4.transpose(m, r);
610+ var t = [m[12], m[13], m[14]];
611+ r[3] = r[7] = r[11] = 0;
612+ r[12] = -V3.dot([r[0], r[4], r[8]], t);
613+ r[13] = -V3.dot([r[1], r[5], r[9]], t);
614+ r[14] = -V3.dot([r[2], r[6], r[10]], t);
615+ return r;
616+ };
617+
618+ /*
619+ * Function: M4x4.inverseTo3x3
620+ *
621+ * Computes the inverse of the given matrix m, but calculates
622+ * only the top left 3x3 values of the result.
623+ *
624+ * Parameters:
625+ *
626+ * m - the matrix
627+ * r - optional 3x3 matrix to store the result in
628+ *
629+ * Returns:
630+ *
631+ * If r is specified, returns r after performing the operation.
632+ * Otherwise, returns a new 3x3 matrix with the result.
633+ */
634+ M4x4.inverseTo3x3 = function M4x4_inverseTo3x3(m, r) {
635+ //MathUtils_assert(m.length == 16, "m.length == 16");
636+ //MathUtils_assert(r == undefined || r.length == 9, "r == undefined || r.length == 9");
637+
638+ if (r == undefined)
639+ r = new MJS_FLOAT_ARRAY_TYPE(9);
640+
641+ var a11 = m[10]*m[5]-m[6]*m[9],
642+ a21 = -m[10]*m[1]+m[2]*m[9],
643+ a31 = m[6]*m[1]-m[2]*m[5],
644+ a12 = -m[10]*m[4]+m[6]*m[8],
645+ a22 = m[10]*m[0]-m[2]*m[8],
646+ a32 = -m[6]*m[0]+m[2]*m[4],
647+ a13 = m[9]*m[4]-m[5]*m[8],
648+ a23 = -m[9]*m[0]+m[1]*m[8],
649+ a33 = m[5]*m[0]-m[1]*m[4];
650+ var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
651+ if (det == 0) // no inverse
652+ throw "matrix not invertible";
653+ var idet = 1.0 / det;
654+
655+ r[0] = idet*a11;
656+ r[1] = idet*a21;
657+ r[2] = idet*a31;
658+ r[3] = idet*a12;
659+ r[4] = idet*a22;
660+ r[5] = idet*a32;
661+ r[6] = idet*a13;
662+ r[7] = idet*a23;
663+ r[8] = idet*a33;
664+
665+ return r;
666+ };
667+
668+ /*
669+ * Function: M4x4.makeFrustum
670+ *
671+ * Creates a matrix for a projection frustum with the given parameters.
672+ *
673+ * Parameters:
674+ *
675+ * left - the left coordinate of the frustum
676+ * right- the right coordinate of the frustum
677+ * bottom - the bottom coordinate of the frustum
678+ * top - the top coordinate of the frustum
679+ * znear - the near z distance of the frustum
680+ * zfar - the far z distance of the frustum
681+ * r - optional 4x4 matrix to store the result in
682+ *
683+ * Returns:
684+ *
685+ * If r is specified, returns r after creating the projection matrix.
686+ * Otherwise, returns a new 4x4 matrix.
687+ */
688+ M4x4.makeFrustum = function M4x4_makeFrustum(left, right, bottom, top, znear, zfar, r) {
689+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
690+
691+ if (r == undefined)
692+ r = new MJS_FLOAT_ARRAY_TYPE(16);
693+
694+ var X = 2*znear/(right-left);
695+ var Y = 2*znear/(top-bottom);
696+ var A = (right+left)/(right-left);
697+ var B = (top+bottom)/(top-bottom);
698+ var C = -(zfar+znear)/(zfar-znear);
699+ var D = -2*zfar*znear/(zfar-znear);
700+
701+ r[0] = 2*znear/(right-left);
702+ r[1] = 0;
703+ r[2] = 0;
704+ r[3] = 0;
705+ r[4] = 0;
706+ r[5] = 2*znear/(top-bottom);
707+ r[6] = 0;
708+ r[7] = 0;
709+ r[8] = (right+left)/(right-left);
710+ r[9] = (top+bottom)/(top-bottom);
711+ r[10] = -(zfar+znear)/(zfar-znear);
712+ r[11] = -1;
713+ r[12] = 0;
714+ r[13] = 0;
715+ r[14] = -2*zfar*znear/(zfar-znear);
716+ r[15] = 0;
717+
718+ return r;
719+ };
720+
721+ /*
722+ * Function: M4x4.makePerspective
723+ *
724+ * Creates a matrix for a perspective projection with the given parameters.
725+ *
726+ * Parameters:
727+ *
728+ * fovy - field of view in the y axis, in degrees
729+ * aspect - aspect ratio
730+ * znear - the near z distance of the projection
731+ * zfar - the far z distance of the projection
732+ * r - optional 4x4 matrix to store the result in
733+ *
734+ * Returns:
735+ *
736+ * If r is specified, returns r after creating the projection matrix.
737+ * Otherwise, returns a new 4x4 matrix.
738+ */
739+ M4x4.makePerspective = function M4x4_makePerspective (fovy, aspect, znear, zfar, r) {
740+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
741+
742+ var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
743+ var ymin = -ymax;
744+ var xmin = ymin * aspect;
745+ var xmax = ymax * aspect;
746+
747+ return M4x4.makeFrustum(xmin, xmax, ymin, ymax, znear, zfar, r);
748+ };
749+
750+ /*
751+ * Function: M4x4.makeOrtho
752+ *
753+ * Creates a matrix for an orthogonal frustum projection with the given parameters.
754+ *
755+ * Parameters:
756+ *
757+ * left - the left coordinate of the frustum
758+ * right- the right coordinate of the frustum
759+ * bottom - the bottom coordinate of the frustum
760+ * top - the top coordinate of the frustum
761+ * znear - the near z distance of the frustum
762+ * zfar - the far z distance of the frustum
763+ * r - optional 4x4 matrix to store the result in
764+ *
765+ * Returns:
766+ *
767+ * If r is specified, returns r after creating the projection matrix.
768+ * Otherwise, returns a new 4x4 matrix.
769+ */
770+ M4x4.makeOrtho = function M4x4_makeOrtho (left, right, bottom, top, znear, zfar, r) {
771+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
772+
773+ if (r == undefined)
774+ r = new MJS_FLOAT_ARRAY_TYPE(16);
775+
776+ var tX = -(right+left)/(right-left);
777+ var tY = -(top+bottom)/(top-bottom);
778+ var tZ = -(zfar+znear)/(zfar-znear);
779+ var X = 2 / (right-left);
780+ var Y = 2 / (top-bottom);
781+ var Z = -2 / (zfar-znear);
782+
783+ r[0] = 2 / (right-left);
784+ r[1] = 0;
785+ r[2] = 0;
786+ r[3] = 0;
787+ r[4] = 0;
788+ r[5] = 2 / (top-bottom);
789+ r[6] = 0;
790+ r[7] = 0;
791+ r[8] = 0;
792+ r[9] = 0;
793+ r[10] = -2 / (zfar-znear);
794+ r[11] = 0;
795+ r[12] = -(right+left)/(right-left);
796+ r[13] = -(top+bottom)/(top-bottom);
797+ r[14] = -(zfar+znear)/(zfar-znear);
798+ r[15] = 1;
799+
800+ return r;
801+ };
802+
803+ /*
804+ * Function: M4x4.makeOrtho
805+ *
806+ * Creates a matrix for a 2D orthogonal frustum projection with the given parameters.
807+ * znear and zfar are assumed to be -1 and 1, respectively.
808+ *
809+ * Parameters:
810+ *
811+ * left - the left coordinate of the frustum
812+ * right- the right coordinate of the frustum
813+ * bottom - the bottom coordinate of the frustum
814+ * top - the top coordinate of the frustum
815+ * r - optional 4x4 matrix to store the result in
816+ *
817+ * Returns:
818+ *
819+ * If r is specified, returns r after creating the projection matrix.
820+ * Otherwise, returns a new 4x4 matrix.
821+ */
822+ M4x4.makeOrtho2D = function M4x4_makeOrtho2D (left, right, bottom, top, r) {
823+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
824+
825+ return M4x4.makeOrtho(left, right, bottom, top, -1, 1, r);
826+ };
827+
828+ /*
829+ * Function: M4x4.mul
830+ *
831+ * Performs r = a * b.
832+ *
833+ * Parameters:
834+ *
835+ * a - the first matrix operand
836+ * b - the second matrix operand
837+ * r - optional 4x4 matrix to store the result in
838+ *
839+ * Returns:
840+ *
841+ * If r is specified, returns r after performing the operation.
842+ * Otherwise, returns a new 4x4 matrix with the result.
843+ */
844+ M4x4.mul = function M4x4_mul(a, b, r) {
845+ //MathUtils_assert(a.length == 16, "a.length == 16");
846+ //MathUtils_assert(b.length == 16, "b.length == 16");
847+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
848+ //MathUtils_assert(a != r && b != r, "a != r && b != r");
849+
850+ if (r == undefined)
851+ r = new MJS_FLOAT_ARRAY_TYPE(16);
852+
853+ var a11 = a[0];
854+ var a21 = a[1];
855+ var a31 = a[2];
856+ var a41 = a[3];
857+ var a12 = a[4];
858+ var a22 = a[5];
859+ var a32 = a[6];
860+ var a42 = a[7];
861+ var a13 = a[8];
862+ var a23 = a[9];
863+ var a33 = a[10];
864+ var a43 = a[11];
865+ var a14 = a[12];
866+ var a24 = a[13];
867+ var a34 = a[14];
868+ var a44 = a[15];
869+
870+ var b11 = b[0];
871+ var b21 = b[1];
872+ var b31 = b[2];
873+ var b41 = b[3];
874+ var b12 = b[4];
875+ var b22 = b[5];
876+ var b32 = b[6];
877+ var b42 = b[7];
878+ var b13 = b[8];
879+ var b23 = b[9];
880+ var b33 = b[10];
881+ var b43 = b[11];
882+ var b14 = b[12];
883+ var b24 = b[13];
884+ var b34 = b[14];
885+ var b44 = b[15];
886+
887+ r[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
888+ r[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
889+ r[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
890+ r[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
891+ r[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
892+ r[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
893+ r[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
894+ r[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
895+ r[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
896+ r[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
897+ r[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
898+ r[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
899+ r[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
900+ r[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
901+ r[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
902+ r[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
903+
904+ return r;
905+ };
906+
907+ /*
908+ * Function: M4x4.mulOffset
909+ *
910+ * Performs r' = a * b, where r' is the 16 elements of r starting at element o.
911+ *
912+ * Parameters:
913+ *
914+ * a - the first matrix operand
915+ * b - the second matrix operand
916+ * r - array to store the result in
917+ * o - offset into r at which to start storing results
918+ *
919+ * Returns:
920+ *
921+ * r
922+ */
923+ M4x4.mulOffset = function M4x4_mulOffset(a, b, r, o) {
924+ //MathUtils_assert(a.length == 16, "a.length == 16");
925+ //MathUtils_assert(b.length == 16, "b.length == 16");
926+
927+ var a21 = a[1];
928+ var a31 = a[2];
929+ var a41 = a[3];
930+ var a12 = a[4];
931+ var a22 = a[5];
932+ var a32 = a[6];
933+ var a42 = a[7];
934+ var a13 = a[8];
935+ var a23 = a[9];
936+ var a33 = a[10];
937+ var a43 = a[11];
938+ var a14 = a[12];
939+ var a24 = a[13];
940+ var a34 = a[14];
941+ var a44 = a[15];
942+
943+ var b11 = b[0];
944+ var b21 = b[1];
945+ var b31 = b[2];
946+ var b41 = b[3];
947+ var b12 = b[4];
948+ var b22 = b[5];
949+ var b32 = b[6];
950+ var b42 = b[7];
951+ var b13 = b[8];
952+ var b23 = b[9];
953+ var b33 = b[10];
954+ var b43 = b[11];
955+ var b14 = b[12];
956+ var b24 = b[13];
957+ var b34 = b[14];
958+ var b44 = b[15];
959+
960+ r[o+0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
961+ r[o+1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
962+ r[o+2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
963+ r[o+3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
964+ r[o+4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
965+ r[o+5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
966+ r[o+6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
967+ r[o+7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
968+ r[o+8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
969+ r[o+9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
970+ r[o+10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
971+ r[o+11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
972+ r[o+12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
973+ r[o+13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
974+ r[o+14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
975+ r[o+15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
976+
977+ return r;
978+ };
979+
980+ /*
981+ * Function: M4x4.mulAffine
982+ *
983+ * Performs r = a * b, assuming a and b are affine (elements 3,7,11,15 = 0,0,0,1)
984+ *
985+ * Parameters:
986+ *
987+ * a - the first matrix operand
988+ * b - the second matrix operand
989+ * r - optional 4x4 matrix to store the result in
990+ *
991+ * Returns:
992+ *
993+ * If r is specified, returns r after performing the operation.
994+ * Otherwise, returns a new 4x4 matrix with the result.
995+ */
996+ M4x4.mulAffine = function M4x4_mulAffine(a, b, r) {
997+ //MathUtils_assert(a.length == 16, "a.length == 16");
998+ //MathUtils_assert(b.length == 16, "b.length == 16");
999+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1000+ //MathUtils_assert(a != r && b != r, "a != r && b != r");
1001+
1002+ if (r == undefined)
1003+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1004+ var a11 = a[0];
1005+ var a21 = a[1];
1006+ var a31 = a[2];
1007+ var a12 = a[4];
1008+ var a22 = a[5];
1009+ var a32 = a[6];
1010+ var a13 = a[8];
1011+ var a23 = a[9];
1012+ var a33 = a[10];
1013+ var a14 = a[12];
1014+ var a24 = a[13];
1015+ var a34 = a[14];
1016+
1017+ var b11 = b[0];
1018+ var b21 = b[1];
1019+ var b31 = b[2];
1020+ var b12 = b[4];
1021+ var b22 = b[5];
1022+ var b32 = b[6];
1023+ var b13 = b[8];
1024+ var b23 = b[9];
1025+ var b33 = b[10];
1026+ var b14 = b[12];
1027+ var b24 = b[13];
1028+ var b34 = b[14];
1029+
1030+ r[0] = a11 * b11 + a12 * b21 + a13 * b31;
1031+ r[1] = a21 * b11 + a22 * b21 + a23 * b31;
1032+ r[2] = a31 * b11 + a32 * b21 + a33 * b31;
1033+ r[3] = 0;
1034+ r[4] = a11 * b12 + a12 * b22 + a13 * b32;
1035+ r[5] = a21 * b12 + a22 * b22 + a23 * b32;
1036+ r[6] = a31 * b12 + a32 * b22 + a33 * b32;
1037+ r[7] = 0;
1038+ r[8] = a11 * b13 + a12 * b23 + a13 * b33;
1039+ r[9] = a21 * b13 + a22 * b23 + a23 * b33;
1040+ r[10] = a31 * b13 + a32 * b23 + a33 * b33;
1041+ r[11] = 0;
1042+ r[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14;
1043+ r[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24;
1044+ r[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34;
1045+ r[15] = 1;
1046+
1047+ return r;
1048+ };
1049+
1050+ /*
1051+ * Function: M4x4.mulAffineOffset
1052+ *
1053+ * Performs r' = a * b, assuming a and b are affine (elements 3,7,11,15 = 0,0,0,1), where r' is the 16 elements of r starting at element o
1054+ *
1055+ * Parameters:
1056+ *
1057+ * a - the first matrix operand
1058+ * b - the second matrix operand
1059+ * r - array to store the result in
1060+ * o - offset into r at which to start storing results
1061+ *
1062+ * Returns:
1063+ *
1064+ * r
1065+ */
1066+ M4x4.mulAffine = function M4x4_mulAffine(a, b, r, o) {
1067+ //MathUtils_assert(a.length == 16, "a.length == 16");
1068+ //MathUtils_assert(b.length == 16, "b.length == 16");
1069+
1070+ if (r == undefined)
1071+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1072+ var a11 = a[0];
1073+ var a21 = a[1];
1074+ var a31 = a[2];
1075+ var a12 = a[4];
1076+ var a22 = a[5];
1077+ var a32 = a[6];
1078+ var a13 = a[8];
1079+ var a23 = a[9];
1080+ var a33 = a[10];
1081+ var a14 = a[12];
1082+ var a24 = a[13];
1083+ var a34 = a[14];
1084+
1085+ var b11 = b[0];
1086+ var b21 = b[1];
1087+ var b31 = b[2];
1088+ var b12 = b[4];
1089+ var b22 = b[5];
1090+ var b32 = b[6];
1091+ var b13 = b[8];
1092+ var b23 = b[9];
1093+ var b33 = b[10];
1094+ var b14 = b[12];
1095+ var b24 = b[13];
1096+ var b34 = b[14];
1097+
1098+ r[o+0] = a11 * b11 + a12 * b21 + a13 * b31;
1099+ r[o+1] = a21 * b11 + a22 * b21 + a23 * b31;
1100+ r[o+2] = a31 * b11 + a32 * b21 + a33 * b31;
1101+ r[o+3] = 0;
1102+ r[o+4] = a11 * b12 + a12 * b22 + a13 * b32;
1103+ r[o+5] = a21 * b12 + a22 * b22 + a23 * b32;
1104+ r[o+6] = a31 * b12 + a32 * b22 + a33 * b32;
1105+ r[o+7] = 0;
1106+ r[o+8] = a11 * b13 + a12 * b23 + a13 * b33;
1107+ r[o+9] = a21 * b13 + a22 * b23 + a23 * b33;
1108+ r[o+10] = a31 * b13 + a32 * b23 + a33 * b33;
1109+ r[o+11] = 0;
1110+ r[o+12] = a11 * b14 + a12 * b24 + a13 * b34 + a14;
1111+ r[o+13] = a21 * b14 + a22 * b24 + a23 * b34 + a24;
1112+ r[o+14] = a31 * b14 + a32 * b24 + a33 * b34 + a34;
1113+ r[o+15] = 1;
1114+
1115+ return r;
1116+ };
1117+
1118+ /*
1119+ * Function: M4x4.makeRotate
1120+ *
1121+ * Creates a transformation matrix for rotation by angle radians about the 3-element vector axis.
1122+ *
1123+ * Parameters:
1124+ *
1125+ * angle - the angle of rotation, in radians
1126+ * axis - the axis around which the rotation is performed, a 3-element vector
1127+ * r - optional 4x4 matrix to store the result in
1128+ *
1129+ * Returns:
1130+ *
1131+ * If r is specified, returns r after creating the matrix.
1132+ * Otherwise, returns a new 4x4 matrix with the result.
1133+ */
1134+ M4x4.makeRotate = function M4x4_makeRotate(angle, axis, r) {
1135+ //MathUtils_assert(angle.length == 3, "angle.length == 3");
1136+ //MathUtils_assert(axis.length == 3, "axis.length == 3");
1137+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1138+
1139+ if (r == undefined)
1140+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1141+
1142+ axis = V3.normalize(axis, V3._temp1);
1143+ var x = axis[0], y = axis[1], z = axis[2];
1144+ var c = Math.cos(angle);
1145+ var c1 = 1-c;
1146+ var s = Math.sin(angle);
1147+
1148+ r[0] = x*x*c1+c;
1149+ r[1] = y*x*c1+z*s;
1150+ r[2] = z*x*c1-y*s;
1151+ r[3] = 0;
1152+ r[4] = x*y*c1-z*s;
1153+ r[5] = y*y*c1+c;
1154+ r[6] = y*z*c1+x*s;
1155+ r[7] = 0;
1156+ r[8] = x*z*c1+y*s;
1157+ r[9] = y*z*c1-x*s;
1158+ r[10] = z*z*c1+c;
1159+ r[11] = 0;
1160+ r[12] = 0;
1161+ r[13] = 0;
1162+ r[14] = 0;
1163+ r[15] = 1;
1164+
1165+ return r;
1166+ };
1167+
1168+ /*
1169+ * Function: M4x4.rotate
1170+ *
1171+ * Concatenates a rotation of angle radians about the axis to the give matrix m.
1172+ *
1173+ * Parameters:
1174+ *
1175+ * angle - the angle of rotation, in radians
1176+ * axis - the axis around which the rotation is performed, a 3-element vector
1177+ * m - the matrix to concatenate the rotation to
1178+ * r - optional 4x4 matrix to store the result in
1179+ *
1180+ * Returns:
1181+ *
1182+ * If r is specified, returns r after performing the operation.
1183+ * Otherwise, returns a new 4x4 matrix with the result.
1184+ */
1185+ M4x4.rotate = function M4x4_rotate(angle, axis, m, r) {
1186+ //MathUtils_assert(angle.length == 3, "angle.length == 3");
1187+ //MathUtils_assert(axis.length == 3, "axis.length == 3");
1188+ //MathUtils_assert(m.length == 16, "m.length == 16");
1189+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1190+
1191+ if (r == undefined)
1192+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1193+ var a0=axis [0], a1=axis [1], a2=axis [2];
1194+ var l = Math.sqrt(a0*a0 + a1*a1 + a2*a2);
1195+ var x = a0, y = a1, z = a2;
1196+ if (l != 1.0) {
1197+ var im = 1.0 / l;
1198+ x *= im;
1199+ y *= im;
1200+ z *= im;
1201+ }
1202+ var c = Math.cos(angle);
1203+ var c1 = 1-c;
1204+ var s = Math.sin(angle);
1205+ var xs = x*s;
1206+ var ys = y*s;
1207+ var zs = z*s;
1208+ var xyc1 = x * y * c1;
1209+ var xzc1 = x * z * c1;
1210+ var yzc1 = y * z * c1;
1211+
1212+ var m11 = m[0];
1213+ var m21 = m[1];
1214+ var m31 = m[2];
1215+ var m41 = m[3];
1216+ var m12 = m[4];
1217+ var m22 = m[5];
1218+ var m32 = m[6];
1219+ var m42 = m[7];
1220+ var m13 = m[8];
1221+ var m23 = m[9];
1222+ var m33 = m[10];
1223+ var m43 = m[11];
1224+
1225+ var t11 = x * x * c1 + c;
1226+ var t21 = xyc1 + zs;
1227+ var t31 = xzc1 - ys;
1228+ var t12 = xyc1 - zs;
1229+ var t22 = y * y * c1 + c;
1230+ var t32 = yzc1 + xs;
1231+ var t13 = xzc1 + ys;
1232+ var t23 = yzc1 - xs;
1233+ var t33 = z * z * c1 + c;
1234+
1235+ r[0] = m11 * t11 + m12 * t21 + m13 * t31;
1236+ r[1] = m21 * t11 + m22 * t21 + m23 * t31;
1237+ r[2] = m31 * t11 + m32 * t21 + m33 * t31;
1238+ r[3] = m41 * t11 + m42 * t21 + m43 * t31;
1239+ r[4] = m11 * t12 + m12 * t22 + m13 * t32;
1240+ r[5] = m21 * t12 + m22 * t22 + m23 * t32;
1241+ r[6] = m31 * t12 + m32 * t22 + m33 * t32;
1242+ r[7] = m41 * t12 + m42 * t22 + m43 * t32;
1243+ r[8] = m11 * t13 + m12 * t23 + m13 * t33;
1244+ r[9] = m21 * t13 + m22 * t23 + m23 * t33;
1245+ r[10] = m31 * t13 + m32 * t23 + m33 * t33;
1246+ r[11] = m41 * t13 + m42 * t23 + m43 * t33;
1247+ if (r != m) {
1248+ r[12] = m[12];
1249+ r[13] = m[13];
1250+ r[14] = m[14];
1251+ r[15] = m[15];
1252+ }
1253+ return r;
1254+ };
1255+
1256+ /*
1257+ * Function: M4x4.makeScale3
1258+ *
1259+ * Creates a transformation matrix for scaling by 3 scalar values, one for
1260+ * each of the x, y, and z directions.
1261+ *
1262+ * Parameters:
1263+ *
1264+ * x - the scale for the x axis
1265+ * y - the scale for the y axis
1266+ * z - the scale for the z axis
1267+ * r - optional 4x4 matrix to store the result in
1268+ *
1269+ * Returns:
1270+ *
1271+ * If r is specified, returns r after creating the matrix.
1272+ * Otherwise, returns a new 4x4 matrix with the result.
1273+ */
1274+ M4x4.makeScale3 = function M4x4_makeScale3(x, y, z, r) {
1275+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1276+
1277+ if (r == undefined)
1278+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1279+
1280+ r[0] = x;
1281+ r[1] = 0;
1282+ r[2] = 0;
1283+ r[3] = 0;
1284+ r[4] = 0;
1285+ r[5] = y;
1286+ r[6] = 0;
1287+ r[7] = 0;
1288+ r[8] = 0;
1289+ r[9] = 0;
1290+ r[10] = z;
1291+ r[11] = 0;
1292+ r[12] = 0;
1293+ r[13] = 0;
1294+ r[14] = 0;
1295+ r[15] = 1;
1296+
1297+ return r;
1298+ };
1299+
1300+ /*
1301+ * Function: M4x4.makeScale1
1302+ *
1303+ * Creates a transformation matrix for a uniform scale by a single scalar value.
1304+ *
1305+ * Parameters:
1306+ *
1307+ * k - the scale factor
1308+ * r - optional 4x4 matrix to store the result in
1309+ *
1310+ * Returns:
1311+ *
1312+ * If r is specified, returns r after creating the matrix.
1313+ * Otherwise, returns a new 4x4 matrix with the result.
1314+ */
1315+ M4x4.makeScale1 = function M4x4_makeScale1(k, r) {
1316+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1317+
1318+ return M4x4.makeScale3(k, k, k, r);
1319+ };
1320+
1321+ /*
1322+ * Function: M4x4.makeScale
1323+ *
1324+ * Creates a transformation matrix for scaling each of the x, y, and z axes by the amount
1325+ * given in the corresponding element of the 3-element vector.
1326+ *
1327+ * Parameters:
1328+ *
1329+ * v - the 3-element vector containing the scale factors
1330+ * r - optional 4x4 matrix to store the result in
1331+ *
1332+ * Returns:
1333+ *
1334+ * If r is specified, returns r after creating the matrix.
1335+ * Otherwise, returns a new 4x4 matrix with the result.
1336+ */
1337+ M4x4.makeScale = function M4x4_makeScale(v, r) {
1338+ //MathUtils_assert(v.length == 3, "v.length == 3");
1339+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1340+
1341+ return M4x4.makeScale3(v[0], v[1], v[2], r);
1342+ };
1343+
1344+ /*
1345+ * Function: M4x4.scale3
1346+ */
1347+ M4x4.scale3 = function M4x4_scale3(x, y, z, m, r) {
1348+ //MathUtils_assert(m.length == 16, "m.length == 16");
1349+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1350+
1351+ if (r == m) {
1352+ m[0] *= x;
1353+ m[1] *= x;
1354+ m[2] *= x;
1355+ m[3] *= x;
1356+ m[4] *= y;
1357+ m[5] *= y;
1358+ m[6] *= y;
1359+ m[7] *= y;
1360+ m[8] *= z;
1361+ m[9] *= z;
1362+ m[10] *= z;
1363+ m[11] *= z;
1364+ return m;
1365+ }
1366+
1367+ if (r == undefined)
1368+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1369+
1370+ r[0] = m[0] * x;
1371+ r[1] = m[1] * x;
1372+ r[2] = m[2] * x;
1373+ r[3] = m[3] * x;
1374+ r[4] = m[4] * y;
1375+ r[5] = m[5] * y;
1376+ r[6] = m[6] * y;
1377+ r[7] = m[7] * y;
1378+ r[8] = m[8] * z;
1379+ r[9] = m[9] * z;
1380+ r[10] = m[10] * z;
1381+ r[11] = m[11] * z;
1382+ r[12] = m[12];
1383+ r[13] = m[13];
1384+ r[14] = m[14];
1385+ r[15] = m[15];
1386+
1387+ return r;
1388+ };
1389+
1390+ /*
1391+ * Function: M4x4.scale1
1392+ */
1393+ M4x4.scale1 = function M4x4_scale1(k, m, r) {
1394+ //MathUtils_assert(m.length == 16, "m.length == 16");
1395+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1396+ if (r == m) {
1397+ m[0] *= k;
1398+ m[1] *= k;
1399+ m[2] *= k;
1400+ m[3] *= k;
1401+ m[4] *= k;
1402+ m[5] *= k;
1403+ m[6] *= k;
1404+ m[7] *= k;
1405+ m[8] *= k;
1406+ m[9] *= k;
1407+ m[10] *= k;
1408+ m[11] *= k;
1409+ return m;
1410+ }
1411+
1412+
1413+ if (r == undefined)
1414+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1415+
1416+ r[0] = m[0] * k;
1417+ r[1] = m[1] * k;
1418+ r[2] = m[2] * k;
1419+ r[3] = m[3] * k;
1420+ r[4] = m[4] * k;
1421+ r[5] = m[5] * k;
1422+ r[6] = m[6] * k;
1423+ r[7] = m[7] * k;
1424+ r[8] = m[8] * k;
1425+ r[9] = m[9] * k;
1426+ r[10] = m[10] * k;
1427+ r[11] = m[11] * k;
1428+ r[12] = m[12];
1429+ r[13] = m[13];
1430+ r[14] = m[14];
1431+ r[15] = m[15];
1432+
1433+ return r;
1434+ };
1435+
1436+ /*
1437+ * Function: M4x4.scale1
1438+ */
1439+ M4x4.scale = function M4x4_scale(v, m, r) {
1440+ //MathUtils_assert(v.length == 3, "v.length == 3");
1441+ //MathUtils_assert(m.length == 16, "m.length == 16");
1442+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1443+ var x = v[0], y = v[1], z = v[2];
1444+
1445+ if (r == m) {
1446+ m[0] *= x;
1447+ m[1] *= x;
1448+ m[2] *= x;
1449+ m[3] *= x;
1450+ m[4] *= y;
1451+ m[5] *= y;
1452+ m[6] *= y;
1453+ m[7] *= y;
1454+ m[8] *= z;
1455+ m[9] *= z;
1456+ m[10] *= z;
1457+ m[11] *= z;
1458+ return m;
1459+ }
1460+
1461+ if (r == undefined)
1462+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1463+
1464+
1465+ r[0] = m[0] * x;
1466+ r[1] = m[1] * x;
1467+ r[2] = m[2] * x;
1468+ r[3] = m[3] * x;
1469+ r[4] = m[4] * y;
1470+ r[5] = m[5] * y;
1471+ r[6] = m[6] * y;
1472+ r[7] = m[7] * y;
1473+ r[8] = m[8] * z;
1474+ r[9] = m[9] * z;
1475+ r[10] = m[10] * z;
1476+ r[11] = m[11] * z;
1477+ r[12] = m[12];
1478+ r[13] = m[13];
1479+ r[14] = m[14];
1480+ r[15] = m[15];
1481+
1482+ return r;
1483+ };
1484+
1485+ /*
1486+ * Function: M4x4.makeTranslate3
1487+ */
1488+ M4x4.makeTranslate3 = function M4x4_makeTranslate3(x, y, z, r) {
1489+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1490+
1491+ if (r == undefined)
1492+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1493+
1494+ r[0] = 1;
1495+ r[1] = 0;
1496+ r[2] = 0;
1497+ r[3] = 0;
1498+ r[4] = 0;
1499+ r[5] = 1;
1500+ r[6] = 0;
1501+ r[7] = 0;
1502+ r[8] = 0;
1503+ r[9] = 0;
1504+ r[10] = 1;
1505+ r[11] = 0;
1506+ r[12] = x;
1507+ r[13] = y;
1508+ r[14] = z;
1509+ r[15] = 1;
1510+
1511+ return r;
1512+ };
1513+
1514+ /*
1515+ * Function: M4x4.makeTranslate1
1516+ */
1517+ M4x4.makeTranslate1 = function M4x4_makeTranslate1 (k, r) {
1518+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1519+
1520+ return M4x4.makeTranslate3(k, k, k, r);
1521+ };
1522+
1523+ /*
1524+ * Function: M4x4.makeTranslate
1525+ */
1526+ M4x4.makeTranslate = function M4x4_makeTranslate (v, r) {
1527+ //MathUtils_assert(v.length == 3, "v.length == 3");
1528+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1529+
1530+ return M4x4.makeTranslate3(v[0], v[1], v[2], r);
1531+ };
1532+
1533+ /*
1534+ * Function: M4x4.translate3Self
1535+ */
1536+ M4x4.translate3Self = function M4x4_translate3Self (x, y, z, m) {
1537+ //MathUtils_assert(m.length == 16, "m.length == 16");
1538+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1539+ m[12] += m[0] * x + m[4] * y + m[8] * z;
1540+ m[13] += m[1] * x + m[5] * y + m[9] * z;
1541+ m[14] += m[2] * x + m[6] * y + m[10] * z;
1542+ m[15] += m[3] * x + m[7] * y + m[11] * z;
1543+ return m;
1544+ };
1545+
1546+ /*
1547+ * Function: M4x4.translate3
1548+ */
1549+ M4x4.translate3 = function M4x4_translate3 (x, y, z, m, r) {
1550+ //MathUtils_assert(m.length == 16, "m.length == 16");
1551+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1552+
1553+ if (r == m) {
1554+ m[12] += m[0] * x + m[4] * y + m[8] * z;
1555+ m[13] += m[1] * x + m[5] * y + m[9] * z;
1556+ m[14] += m[2] * x + m[6] * y + m[10] * z;
1557+ m[15] += m[3] * x + m[7] * y + m[11] * z;
1558+ return m;
1559+ }
1560+
1561+ if (r == undefined)
1562+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1563+
1564+ var m11 = m[0];
1565+ var m21 = m[1];
1566+ var m31 = m[2];
1567+ var m41 = m[3];
1568+ var m12 = m[4];
1569+ var m22 = m[5];
1570+ var m32 = m[6];
1571+ var m42 = m[7];
1572+ var m13 = m[8];
1573+ var m23 = m[9];
1574+ var m33 = m[10];
1575+ var m43 = m[11];
1576+
1577+
1578+ r[0] = m11;
1579+ r[1] = m21;
1580+ r[2] = m31;
1581+ r[3] = m41;
1582+ r[4] = m12;
1583+ r[5] = m22;
1584+ r[6] = m32;
1585+ r[7] = m42;
1586+ r[8] = m13;
1587+ r[9] = m23;
1588+ r[10] = m33;
1589+ r[11] = m43;
1590+ r[12] = m11 * x + m12 * y + m13 * z + m[12];
1591+ r[13] = m21 * x + m22 * y + m23 * z + m[13];
1592+ r[14] = m31 * x + m32 * y + m33 * z + m[14];
1593+ r[15] = m41 * x + m42 * y + m43 * z + m[15];
1594+
1595+ return r;
1596+ };
1597+
1598+ /*
1599+ * Function: M4x4.translate1
1600+ */
1601+ M4x4.translate1 = function M4x4_translate1 (k, m, r) {
1602+ //MathUtils_assert(m.length == 16, "m.length == 16");
1603+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1604+
1605+ return M4x4.translate3(k, k, k, m, r);
1606+ };
1607+ /*
1608+ * Function: M4x4.translateSelf
1609+ */
1610+ M4x4.translateSelf = function M4x4_translateSelf (v, m) {
1611+ //MathUtils_assert(v.length == 3, "v.length == 3");
1612+ //MathUtils_assert(m.length == 16, "m.length == 16");
1613+ var x=v[0], y=v[1], z=v[2];
1614+ m[12] += m[0] * x + m[4] * y + m[8] * z;
1615+ m[13] += m[1] * x + m[5] * y + m[9] * z;
1616+ m[14] += m[2] * x + m[6] * y + m[10] * z;
1617+ m[15] += m[3] * x + m[7] * y + m[11] * z;
1618+ return m;
1619+ };
1620+ /*
1621+ * Function: M4x4.translate
1622+ */
1623+ M4x4.translate = function M4x4_translate (v, m, r) {
1624+ //MathUtils_assert(v.length == 3, "v.length == 3");
1625+ //MathUtils_assert(m.length == 16, "m.length == 16");
1626+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1627+ var x=v[0], y=v[1], z=v[2];
1628+ if (r == m) {
1629+ m[12] += m[0] * x + m[4] * y + m[8] * z;
1630+ m[13] += m[1] * x + m[5] * y + m[9] * z;
1631+ m[14] += m[2] * x + m[6] * y + m[10] * z;
1632+ m[15] += m[3] * x + m[7] * y + m[11] * z;
1633+ return m;
1634+ }
1635+
1636+ if (r == undefined)
1637+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1638+
1639+ var m11 = m[0];
1640+ var m21 = m[1];
1641+ var m31 = m[2];
1642+ var m41 = m[3];
1643+ var m12 = m[4];
1644+ var m22 = m[5];
1645+ var m32 = m[6];
1646+ var m42 = m[7];
1647+ var m13 = m[8];
1648+ var m23 = m[9];
1649+ var m33 = m[10];
1650+ var m43 = m[11];
1651+
1652+ r[0] = m11;
1653+ r[1] = m21;
1654+ r[2] = m31;
1655+ r[3] = m41;
1656+ r[4] = m12;
1657+ r[5] = m22;
1658+ r[6] = m32;
1659+ r[7] = m42;
1660+ r[8] = m13;
1661+ r[9] = m23;
1662+ r[10] = m33;
1663+ r[11] = m43;
1664+ r[12] = m11 * x + m12 * y + m13 * z + m[12];
1665+ r[13] = m21 * x + m22 * y + m23 * z + m[13];
1666+ r[14] = m31 * x + m32 * y + m33 * z + m[14];
1667+ r[15] = m41 * x + m42 * y + m43 * z + m[15];
1668+
1669+ return r;
1670+ };
1671+
1672+ /*
1673+ * Function: M4x4.makeLookAt
1674+ */
1675+ M4x4.makeLookAt = function M4x4_makeLookAt (eye, center, up, r) {
1676+ //MathUtils_assert(eye.length == 3, "eye.length == 3");
1677+ //MathUtils_assert(center.length == 3, "center.length == 3");
1678+ //MathUtils_assert(up.length == 3, "up.length == 3");
1679+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1680+
1681+ var z = V3.direction(eye, center, V3._temp1);
1682+ var x = V3.normalize(V3.cross(up, z, V3._temp2), V3._temp2);
1683+ var y = V3.normalize(V3.cross(z, x, V3._temp3), V3._temp3);
1684+
1685+ var tm1 = M4x4._temp1;
1686+ var tm2 = M4x4._temp2;
1687+
1688+ tm1[0] = x[0];
1689+ tm1[1] = y[0];
1690+ tm1[2] = z[0];
1691+ tm1[3] = 0;
1692+ tm1[4] = x[1];
1693+ tm1[5] = y[1];
1694+ tm1[6] = z[1];
1695+ tm1[7] = 0;
1696+ tm1[8] = x[2];
1697+ tm1[9] = y[2];
1698+ tm1[10] = z[2];
1699+ tm1[11] = 0;
1700+ tm1[12] = 0;
1701+ tm1[13] = 0;
1702+ tm1[14] = 0;
1703+ tm1[15] = 1;
1704+
1705+ tm2[0] = 1; tm2[1] = 0; tm2[2] = 0; tm2[3] = 0;
1706+ tm2[4] = 0; tm2[5] = 1; tm2[6] = 0; tm2[7] = 0;
1707+ tm2[8] = 0; tm2[9] = 0; tm2[10] = 1; tm2[11] = 0;
1708+ tm2[12] = -eye[0]; tm2[13] = -eye[1]; tm2[14] = -eye[2]; tm2[15] = 1;
1709+
1710+ if (r == undefined)
1711+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1712+ return M4x4.mul(tm1, tm2, r);
1713+ };
1714+
1715+ /*
1716+ * Function: M4x4.transposeSelf
1717+ */
1718+ M4x4.transposeSelf = function M4x4_transposeSelf (m) {
1719+ //MathUtils_assert(m.length == 16, "m.length == 16");
1720+ var tmp = m[1]; m[1] = m[4]; m[4] = tmp;
1721+ tmp = m[2]; m[2] = m[8]; m[8] = tmp;
1722+ tmp = m[3]; m[3] = m[12]; m[12] = tmp;
1723+ tmp = m[6]; m[6] = m[9]; m[9] = tmp;
1724+ tmp = m[7]; m[7] = m[13]; m[13] = tmp;
1725+ tmp = m[11]; m[11] = m[14]; m[14] = tmp;
1726+ return m;
1727+ };
1728+ /*
1729+ * Function: M4x4.transpose
1730+ */
1731+ M4x4.transpose = function M4x4_transpose (m, r) {
1732+ //MathUtils_assert(m.length == 16, "m.length == 16");
1733+ //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1734+
1735+ if (m == r) {
1736+ var tmp = 0.0;
1737+ tmp = m[1]; m[1] = m[4]; m[4] = tmp;
1738+ tmp = m[2]; m[2] = m[8]; m[8] = tmp;
1739+ tmp = m[3]; m[3] = m[12]; m[12] = tmp;
1740+ tmp = m[6]; m[6] = m[9]; m[9] = tmp;
1741+ tmp = m[7]; m[7] = m[13]; m[13] = tmp;
1742+ tmp = m[11]; m[11] = m[14]; m[14] = tmp;
1743+ return m;
1744+ }
1745+
1746+ if (r == undefined)
1747+ r = new MJS_FLOAT_ARRAY_TYPE(16);
1748+
1749+ r[0] = m[0]; r[1] = m[4]; r[2] = m[8]; r[3] = m[12];
1750+ r[4] = m[1]; r[5] = m[5]; r[6] = m[9]; r[7] = m[13];
1751+ r[8] = m[2]; r[9] = m[6]; r[10] = m[10]; r[11] = m[14];
1752+ r[12] = m[3]; r[13] = m[7]; r[14] = m[11]; r[15] = m[15];
1753+
1754+ return r;
1755+ };
1756+
1757+
1758+ /*
1759+ * Function: M4x4.transformPoint
1760+ */
1761+ M4x4.transformPoint = function M4x4_transformPoint (m, v, r) {
1762+ //MathUtils_assert(m.length == 16, "m.length == 16");
1763+ //MathUtils_assert(v.length == 3, "v.length == 3");
1764+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1765+ if (r == undefined)
1766+ r = new MJS_FLOAT_ARRAY_TYPE(3);
1767+
1768+ var v0 = v[0], v1 = v[1], v2 = v[2];
1769+
1770+ r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12];
1771+ r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13];
1772+ r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14];
1773+ var w = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15];
1774+
1775+ if (w != 1.0) {
1776+ r[0] /= w;
1777+ r[1] /= w;
1778+ r[2] /= w;
1779+ }
1780+
1781+ return r;
1782+ };
1783+
1784+ /*
1785+ * Function: M4x4.transformLine
1786+ */
1787+ M4x4.transformLine = function M4x4_transformLine(m, v, r) {
1788+ //MathUtils_assert(m.length == 16, "m.length == 16");
1789+ //MathUtils_assert(v.length == 3, "v.length == 3");
1790+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1791+ if (r == undefined)
1792+ r = new MJS_FLOAT_ARRAY_TYPE(3);
1793+
1794+ var v0 = v[0], v1 = v[1], v2 = v[2];
1795+ r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2;
1796+ r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2;
1797+ r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2;
1798+ var w = m[3] * v0 + m[7] * v1 + m[11] * v2;
1799+
1800+ if (w != 1.0) {
1801+ r[0] /= w;
1802+ r[1] /= w;
1803+ r[2] /= w;
1804+ }
1805+
1806+ return r;
1807+ };
1808+
1809+
1810+ /*
1811+ * Function: M4x4.transformPointAffine
1812+ */
1813+ M4x4.transformPointAffine = function M4x4_transformPointAffine (m, v, r) {
1814+ //MathUtils_assert(m.length == 16, "m.length == 16");
1815+ //MathUtils_assert(v.length == 3, "v.length == 3");
1816+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1817+ if (r == undefined)
1818+ r = new MJS_FLOAT_ARRAY_TYPE(3);
1819+
1820+ var v0 = v[0], v1 = v[1], v2 = v[2];
1821+
1822+ r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12];
1823+ r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13];
1824+ r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14];
1825+
1826+ return r;
1827+ };
1828+
1829+ /*
1830+ * Function: M4x4.transformLineAffine
1831+ */
1832+ M4x4.transformLineAffine = function M4x4_transformLineAffine(m, v, r) {
1833+ //MathUtils_assert(m.length == 16, "m.length == 16");
1834+ //MathUtils_assert(v.length == 3, "v.length == 3");
1835+ //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1836+ if (r == undefined)
1837+ r = new MJS_FLOAT_ARRAY_TYPE(3);
1838+
1839+ var v0 = v[0], v1 = v[1], v2 = v[2];
1840+ r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2;
1841+ r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2;
1842+ r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2;
1843+
1844+ return r;
1845+ };
1846+
1847+ return {
1848+ v3: A3(V3.$),
1849+ v3clone: V3.clone,
1850+ v3add: A2(V3.add),
1851+ v3sub: A2(V3.sub),
1852+ v3neg: V3.neg,
1853+ v3direction: A2(V3.direction),
1854+ v3length: V3.length,
1855+ v3lengthSquared: V3.lengthSquared,
1856+ v3normalize: V3.normalize,
1857+ v3scale: A2(V3.scale),
1858+ v3dot: A2(V3.dot),
1859+ v3cross: A2(V3.cross),
1860+ v3mul4x4: A2(V3.mul4x4),
1861+ m4x4: A16(M4x4.$),
1862+ m4x4clone: M4x4.clone,
1863+ m4x4topLeft3x3: M4x4.topLeft3x3,
1864+ m4x4inverseOrthonormal: M4x4.inverseOrthonormal,
1865+ m4x4inverseTo3x3: M4x4.inverseTo3x3,
1866+ m4x4makeFrustum: A6(M4x4.makeFrustum),
1867+ m4x4makePerspective: A4(M4x4.makePerspective),
1868+ m4x4makeOrtho: A6(M4x4.makeOrtho),
1869+ m4x4makeOrtho2D: A4(M4x4.makeOrtho2D),
1870+ m4x4mul: A2(M4x4.mul),
1871+ m4x4Affine: A2(M4x4.mulAffine),
1872+ m4x4makeRotate: A2(M4x4.makeRotate),
1873+ m4x4rotate: A3(M4x4.rotate),
1874+ m4x4makeScale3: A3(M4x4.makeScale3),
1875+ m4x4makeScale1: M4x4.makeScale1,
1876+ m4x4makeScale: M4x4.makeScale,
1877+ m4x4scale3: A4(M4x4.scale3),
1878+ m4x4scale1: A2(M4x4.scale1),
1879+ m4x4scale: A2(M4x4.scale),
1880+ m4x4makeTranslate3: A3(M4x4.makeTranslate3),
1881+ m4x4makeTranslate1: M4x4.makeTranslate1,
1882+ m4x4makeTranslate: M4x4.makeTranslate,
1883+ m4x4translate3: A4(M4x4.translate3),
1884+ m4x4translate1: A2(M4x4.translate1),
1885+ m4x4translate: A2(M4x4.translate),
1886+ m4x4makeLookAt: A3(M4x4.makeLookAt),
1887+ m4x4transpose: M4x4.transpose,
1888+ m4x4transformPoint: A2(M4x4.transformPoint),
1889+ /*
1890+ m4x4_transformLine(m, v, r) {
1891+ m4x4_transformPointAffine (m, v, r) {
1892+ m4x4_transformLineAffine(m, v, r) {
1893+ */
1894+ };
1895+
1896+}