1/**
2 * @fileoverview gl-matrix - High performance matrix and vector operations
3 * @author Brandon Jones
4 * @author Colin MacKenzie IV
5 * @version 2.1.0
6 */
7
8/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
9
10Redistribution and use in source and binary forms, with or without modification,
11are permitted provided that the following conditions are met:
12
13  * Redistributions of source code must retain the above copyright notice, this
14    list of conditions and the following disclaimer.
15  * Redistributions in binary form must reproduce the above copyright notice,
16    this list of conditions and the following disclaimer in the documentation
17    and/or other materials provided with the distribution.
18
19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29
30
31(function() {
32  "use strict";
33
34  var shim = {};
35  if (typeof(exports) === 'undefined') {
36    if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
37      shim.exports = {};
38      define(function() {
39        return shim.exports;
40      });
41    } else {
42      // gl-matrix lives in a browser, define its namespaces in global
43      shim.exports = window;
44    }
45  }
46  else {
47    // gl-matrix lives in commonjs, define its namespaces in exports
48    shim.exports = exports;
49  }
50
51  (function(exports) {
52    /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
53
54Redistribution and use in source and binary forms, with or without modification,
55are permitted provided that the following conditions are met:
56
57  * Redistributions of source code must retain the above copyright notice, this
58    list of conditions and the following disclaimer.
59  * Redistributions in binary form must reproduce the above copyright notice,
60    this list of conditions and the following disclaimer in the documentation
61    and/or other materials provided with the distribution.
62
63THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
64ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
67ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
70ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
73
74
75if(!GLMAT_EPSILON) {
76    var GLMAT_EPSILON = 0.000001;
77}
78
79if(!GLMAT_ARRAY_TYPE) {
80    var GLMAT_ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
81}
82
83/**
84 * @class Common utilities
85 * @name glMatrix
86 */
87var glMatrix = {};
88
89/**
90 * Sets the type of array used when creating new vectors and matricies
91 *
92 * @param {Type} type Array type, such as Float32Array or Array
93 */
94glMatrix.setMatrixArrayType = function(type) {
95    GLMAT_ARRAY_TYPE = type;
96}
97
98if(typeof(exports) !== 'undefined') {
99    exports.glMatrix = glMatrix;
100}
101;
102/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
103
104Redistribution and use in source and binary forms, with or without modification,
105are permitted provided that the following conditions are met:
106
107  * Redistributions of source code must retain the above copyright notice, this
108    list of conditions and the following disclaimer.
109  * Redistributions in binary form must reproduce the above copyright notice,
110    this list of conditions and the following disclaimer in the documentation
111    and/or other materials provided with the distribution.
112
113THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
114ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
115WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
117ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
120ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
123
124/**
125 * @class 2 Dimensional Vector
126 * @name vec2
127 */
128
129var vec2 = {};
130
131/**
132 * Creates a new, empty vec2
133 *
134 * @returns {vec2} a new 2D vector
135 */
136vec2.create = function() {
137    var out = new GLMAT_ARRAY_TYPE(2);
138    out[0] = 0;
139    out[1] = 0;
140    return out;
141};
142
143/**
144 * Creates a new vec2 initialized with values from an existing vector
145 *
146 * @param {vec2} a vector to clone
147 * @returns {vec2} a new 2D vector
148 */
149vec2.clone = function(a) {
150    var out = new GLMAT_ARRAY_TYPE(2);
151    out[0] = a[0];
152    out[1] = a[1];
153    return out;
154};
155
156/**
157 * Creates a new vec2 initialized with the given values
158 *
159 * @param {Number} x X component
160 * @param {Number} y Y component
161 * @returns {vec2} a new 2D vector
162 */
163vec2.fromValues = function(x, y) {
164    var out = new GLMAT_ARRAY_TYPE(2);
165    out[0] = x;
166    out[1] = y;
167    return out;
168};
169
170/**
171 * Copy the values from one vec2 to another
172 *
173 * @param {vec2} out the receiving vector
174 * @param {vec2} a the source vector
175 * @returns {vec2} out
176 */
177vec2.copy = function(out, a) {
178    out[0] = a[0];
179    out[1] = a[1];
180    return out;
181};
182
183/**
184 * Set the components of a vec2 to the given values
185 *
186 * @param {vec2} out the receiving vector
187 * @param {Number} x X component
188 * @param {Number} y Y component
189 * @returns {vec2} out
190 */
191vec2.set = function(out, x, y) {
192    out[0] = x;
193    out[1] = y;
194    return out;
195};
196
197/**
198 * Adds two vec2's
199 *
200 * @param {vec2} out the receiving vector
201 * @param {vec2} a the first operand
202 * @param {vec2} b the second operand
203 * @returns {vec2} out
204 */
205vec2.add = function(out, a, b) {
206    out[0] = a[0] + b[0];
207    out[1] = a[1] + b[1];
208    return out;
209};
210
211/**
212 * Subtracts two vec2's
213 *
214 * @param {vec2} out the receiving vector
215 * @param {vec2} a the first operand
216 * @param {vec2} b the second operand
217 * @returns {vec2} out
218 */
219vec2.subtract = function(out, a, b) {
220    out[0] = a[0] - b[0];
221    out[1] = a[1] - b[1];
222    return out;
223};
224
225/**
226 * Alias for {@link vec2.subtract}
227 * @function
228 */
229vec2.sub = vec2.subtract;
230
231/**
232 * Multiplies two vec2's
233 *
234 * @param {vec2} out the receiving vector
235 * @param {vec2} a the first operand
236 * @param {vec2} b the second operand
237 * @returns {vec2} out
238 */
239vec2.multiply = function(out, a, b) {
240    out[0] = a[0] * b[0];
241    out[1] = a[1] * b[1];
242    return out;
243};
244
245/**
246 * Alias for {@link vec2.multiply}
247 * @function
248 */
249vec2.mul = vec2.multiply;
250
251/**
252 * Divides two vec2's
253 *
254 * @param {vec2} out the receiving vector
255 * @param {vec2} a the first operand
256 * @param {vec2} b the second operand
257 * @returns {vec2} out
258 */
259vec2.divide = function(out, a, b) {
260    out[0] = a[0] / b[0];
261    out[1] = a[1] / b[1];
262    return out;
263};
264
265/**
266 * Alias for {@link vec2.divide}
267 * @function
268 */
269vec2.div = vec2.divide;
270
271/**
272 * Returns the minimum of two vec2's
273 *
274 * @param {vec2} out the receiving vector
275 * @param {vec2} a the first operand
276 * @param {vec2} b the second operand
277 * @returns {vec2} out
278 */
279vec2.min = function(out, a, b) {
280    out[0] = Math.min(a[0], b[0]);
281    out[1] = Math.min(a[1], b[1]);
282    return out;
283};
284
285/**
286 * Returns the maximum of two vec2's
287 *
288 * @param {vec2} out the receiving vector
289 * @param {vec2} a the first operand
290 * @param {vec2} b the second operand
291 * @returns {vec2} out
292 */
293vec2.max = function(out, a, b) {
294    out[0] = Math.max(a[0], b[0]);
295    out[1] = Math.max(a[1], b[1]);
296    return out;
297};
298
299/**
300 * Scales a vec2 by a scalar number
301 *
302 * @param {vec2} out the receiving vector
303 * @param {vec2} a the vector to scale
304 * @param {Number} b amount to scale the vector by
305 * @returns {vec2} out
306 */
307vec2.scale = function(out, a, b) {
308    out[0] = a[0] * b;
309    out[1] = a[1] * b;
310    return out;
311};
312
313/**
314 * Calculates the euclidian distance between two vec2's
315 *
316 * @param {vec2} a the first operand
317 * @param {vec2} b the second operand
318 * @returns {Number} distance between a and b
319 */
320vec2.distance = function(a, b) {
321    var x = b[0] - a[0],
322        y = b[1] - a[1];
323    return Math.sqrt(x*x + y*y);
324};
325
326/**
327 * Alias for {@link vec2.distance}
328 * @function
329 */
330vec2.dist = vec2.distance;
331
332/**
333 * Calculates the squared euclidian distance between two vec2's
334 *
335 * @param {vec2} a the first operand
336 * @param {vec2} b the second operand
337 * @returns {Number} squared distance between a and b
338 */
339vec2.squaredDistance = function(a, b) {
340    var x = b[0] - a[0],
341        y = b[1] - a[1];
342    return x*x + y*y;
343};
344
345/**
346 * Alias for {@link vec2.squaredDistance}
347 * @function
348 */
349vec2.sqrDist = vec2.squaredDistance;
350
351/**
352 * Calculates the length of a vec2
353 *
354 * @param {vec2} a vector to calculate length of
355 * @returns {Number} length of a
356 */
357vec2.length = function (a) {
358    var x = a[0],
359        y = a[1];
360    return Math.sqrt(x*x + y*y);
361};
362
363/**
364 * Alias for {@link vec2.length}
365 * @function
366 */
367vec2.len = vec2.length;
368
369/**
370 * Calculates the squared length of a vec2
371 *
372 * @param {vec2} a vector to calculate squared length of
373 * @returns {Number} squared length of a
374 */
375vec2.squaredLength = function (a) {
376    var x = a[0],
377        y = a[1];
378    return x*x + y*y;
379};
380
381/**
382 * Alias for {@link vec2.squaredLength}
383 * @function
384 */
385vec2.sqrLen = vec2.squaredLength;
386
387/**
388 * Negates the components of a vec2
389 *
390 * @param {vec2} out the receiving vector
391 * @param {vec2} a vector to negate
392 * @returns {vec2} out
393 */
394vec2.negate = function(out, a) {
395    out[0] = -a[0];
396    out[1] = -a[1];
397    return out;
398};
399
400/**
401 * Normalize a vec2
402 *
403 * @param {vec2} out the receiving vector
404 * @param {vec2} a vector to normalize
405 * @returns {vec2} out
406 */
407vec2.normalize = function(out, a) {
408    var x = a[0],
409        y = a[1];
410    var len = x*x + y*y;
411    if (len > 0) {
412        //TODO: evaluate use of glm_invsqrt here?
413        len = 1 / Math.sqrt(len);
414        out[0] = a[0] * len;
415        out[1] = a[1] * len;
416    }
417    return out;
418};
419
420/**
421 * Calculates the dot product of two vec2's
422 *
423 * @param {vec2} a the first operand
424 * @param {vec2} b the second operand
425 * @returns {Number} dot product of a and b
426 */
427vec2.dot = function (a, b) {
428    return a[0] * b[0] + a[1] * b[1];
429};
430
431/**
432 * Computes the cross product of two vec2's
433 * Note that the cross product must by definition produce a 3D vector
434 *
435 * @param {vec3} out the receiving vector
436 * @param {vec2} a the first operand
437 * @param {vec2} b the second operand
438 * @returns {vec3} out
439 */
440vec2.cross = function(out, a, b) {
441    var z = a[0] * b[1] - a[1] * b[0];
442    out[0] = out[1] = 0;
443    out[2] = z;
444    return out;
445};
446
447/**
448 * Performs a linear interpolation between two vec2's
449 *
450 * @param {vec2} out the receiving vector
451 * @param {vec2} a the first operand
452 * @param {vec2} b the second operand
453 * @param {Number} t interpolation amount between the two inputs
454 * @returns {vec2} out
455 */
456vec2.lerp = function (out, a, b, t) {
457    var ax = a[0],
458        ay = a[1];
459    out[0] = ax + t * (b[0] - ax);
460    out[1] = ay + t * (b[1] - ay);
461    return out;
462};
463
464/**
465 * Transforms the vec2 with a mat2
466 *
467 * @param {vec2} out the receiving vector
468 * @param {vec2} a the vector to transform
469 * @param {mat2} m matrix to transform with
470 * @returns {vec2} out
471 */
472vec2.transformMat2 = function(out, a, m) {
473    var x = a[0],
474        y = a[1];
475    out[0] = m[0] * x + m[2] * y;
476    out[1] = m[1] * x + m[3] * y;
477    return out;
478};
479
480/**
481 * Transforms the vec2 with a mat2d
482 *
483 * @param {vec2} out the receiving vector
484 * @param {vec2} a the vector to transform
485 * @param {mat2d} m matrix to transform with
486 * @returns {vec2} out
487 */
488vec2.transformMat2d = function(out, a, m) {
489    var x = a[0],
490        y = a[1];
491    out[0] = m[0] * x + m[2] * y + m[4];
492    out[1] = m[1] * x + m[3] * y + m[5];
493    return out;
494};
495
496/**
497 * Transforms the vec2 with a mat3
498 * 3rd vector component is implicitly '1'
499 *
500 * @param {vec2} out the receiving vector
501 * @param {vec2} a the vector to transform
502 * @param {mat3} m matrix to transform with
503 * @returns {vec2} out
504 */
505vec2.transformMat3 = function(out, a, m) {
506    var x = a[0],
507        y = a[1];
508    out[0] = m[0] * x + m[3] * y + m[6];
509    out[1] = m[1] * x + m[4] * y + m[7];
510    return out;
511};
512
513/**
514 * Transforms the vec2 with a mat4
515 * 3rd vector component is implicitly '0'
516 * 4th vector component is implicitly '1'
517 *
518 * @param {vec2} out the receiving vector
519 * @param {vec2} a the vector to transform
520 * @param {mat4} m matrix to transform with
521 * @returns {vec2} out
522 */
523vec2.transformMat4 = function(out, a, m) {
524    var x = a[0],
525        y = a[1];
526    out[0] = m[0] * x + m[4] * y + m[12];
527    out[1] = m[1] * x + m[5] * y + m[13];
528    return out;
529};
530
531/**
532 * Perform some operation over an array of vec2s.
533 *
534 * @param {Array} a the array of vectors to iterate over
535 * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
536 * @param {Number} offset Number of elements to skip at the beginning of the array
537 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
538 * @param {Function} fn Function to call for each vector in the array
539 * @param {Object} [arg] additional argument to pass to fn
540 * @returns {Array} a
541 * @function
542 */
543vec2.forEach = (function() {
544    var vec = vec2.create();
545
546    return function(a, stride, offset, count, fn, arg) {
547        var i, l;
548        if(!stride) {
549            stride = 2;
550        }
551
552        if(!offset) {
553            offset = 0;
554        }
555
556        if(count) {
557            l = Math.min((count * stride) + offset, a.length);
558        } else {
559            l = a.length;
560        }
561
562        for(i = offset; i < l; i += stride) {
563            vec[0] = a[i]; vec[1] = a[i+1];
564            fn(vec, vec, arg);
565            a[i] = vec[0]; a[i+1] = vec[1];
566        }
567
568        return a;
569    };
570})();
571
572/**
573 * Returns a string representation of a vector
574 *
575 * @param {vec2} vec vector to represent as a string
576 * @returns {String} string representation of the vector
577 */
578vec2.str = function (a) {
579    return 'vec2(' + a[0] + ', ' + a[1] + ')';
580};
581
582if(typeof(exports) !== 'undefined') {
583    exports.vec2 = vec2;
584}
585;
586/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
587
588Redistribution and use in source and binary forms, with or without modification,
589are permitted provided that the following conditions are met:
590
591  * Redistributions of source code must retain the above copyright notice, this
592    list of conditions and the following disclaimer.
593  * Redistributions in binary form must reproduce the above copyright notice,
594    this list of conditions and the following disclaimer in the documentation
595    and/or other materials provided with the distribution.
596
597THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
598ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
599WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
600DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
601ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
602(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
603LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
604ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
605(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
606SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
607
608/**
609 * @class 3 Dimensional Vector
610 * @name vec3
611 */
612
613var vec3 = {};
614
615/**
616 * Creates a new, empty vec3
617 *
618 * @returns {vec3} a new 3D vector
619 */
620vec3.create = function() {
621    var out = new GLMAT_ARRAY_TYPE(3);
622    out[0] = 0;
623    out[1] = 0;
624    out[2] = 0;
625    return out;
626};
627
628/**
629 * Creates a new vec3 initialized with values from an existing vector
630 *
631 * @param {vec3} a vector to clone
632 * @returns {vec3} a new 3D vector
633 */
634vec3.clone = function(a) {
635    var out = new GLMAT_ARRAY_TYPE(3);
636    out[0] = a[0];
637    out[1] = a[1];
638    out[2] = a[2];
639    return out;
640};
641
642/**
643 * Creates a new vec3 initialized with the given values
644 *
645 * @param {Number} x X component
646 * @param {Number} y Y component
647 * @param {Number} z Z component
648 * @returns {vec3} a new 3D vector
649 */
650vec3.fromValues = function(x, y, z) {
651    var out = new GLMAT_ARRAY_TYPE(3);
652    out[0] = x;
653    out[1] = y;
654    out[2] = z;
655    return out;
656};
657
658/**
659 * Copy the values from one vec3 to another
660 *
661 * @param {vec3} out the receiving vector
662 * @param {vec3} a the source vector
663 * @returns {vec3} out
664 */
665vec3.copy = function(out, a) {
666    out[0] = a[0];
667    out[1] = a[1];
668    out[2] = a[2];
669    return out;
670};
671
672/**
673 * Set the components of a vec3 to the given values
674 *
675 * @param {vec3} out the receiving vector
676 * @param {Number} x X component
677 * @param {Number} y Y component
678 * @param {Number} z Z component
679 * @returns {vec3} out
680 */
681vec3.set = function(out, x, y, z) {
682    out[0] = x;
683    out[1] = y;
684    out[2] = z;
685    return out;
686};
687
688/**
689 * Adds two vec3's
690 *
691 * @param {vec3} out the receiving vector
692 * @param {vec3} a the first operand
693 * @param {vec3} b the second operand
694 * @returns {vec3} out
695 */
696vec3.add = function(out, a, b) {
697    out[0] = a[0] + b[0];
698    out[1] = a[1] + b[1];
699    out[2] = a[2] + b[2];
700    return out;
701};
702
703/**
704 * Subtracts two vec3's
705 *
706 * @param {vec3} out the receiving vector
707 * @param {vec3} a the first operand
708 * @param {vec3} b the second operand
709 * @returns {vec3} out
710 */
711vec3.subtract = function(out, a, b) {
712    out[0] = a[0] - b[0];
713    out[1] = a[1] - b[1];
714    out[2] = a[2] - b[2];
715    return out;
716};
717
718/**
719 * Alias for {@link vec3.subtract}
720 * @function
721 */
722vec3.sub = vec3.subtract;
723
724/**
725 * Multiplies two vec3's
726 *
727 * @param {vec3} out the receiving vector
728 * @param {vec3} a the first operand
729 * @param {vec3} b the second operand
730 * @returns {vec3} out
731 */
732vec3.multiply = function(out, a, b) {
733    out[0] = a[0] * b[0];
734    out[1] = a[1] * b[1];
735    out[2] = a[2] * b[2];
736    return out;
737};
738
739/**
740 * Alias for {@link vec3.multiply}
741 * @function
742 */
743vec3.mul = vec3.multiply;
744
745/**
746 * Divides two vec3's
747 *
748 * @param {vec3} out the receiving vector
749 * @param {vec3} a the first operand
750 * @param {vec3} b the second operand
751 * @returns {vec3} out
752 */
753vec3.divide = function(out, a, b) {
754    out[0] = a[0] / b[0];
755    out[1] = a[1] / b[1];
756    out[2] = a[2] / b[2];
757    return out;
758};
759
760/**
761 * Alias for {@link vec3.divide}
762 * @function
763 */
764vec3.div = vec3.divide;
765
766/**
767 * Returns the minimum of two vec3's
768 *
769 * @param {vec3} out the receiving vector
770 * @param {vec3} a the first operand
771 * @param {vec3} b the second operand
772 * @returns {vec3} out
773 */
774vec3.min = function(out, a, b) {
775    out[0] = Math.min(a[0], b[0]);
776    out[1] = Math.min(a[1], b[1]);
777    out[2] = Math.min(a[2], b[2]);
778    return out;
779};
780
781/**
782 * Returns the maximum of two vec3's
783 *
784 * @param {vec3} out the receiving vector
785 * @param {vec3} a the first operand
786 * @param {vec3} b the second operand
787 * @returns {vec3} out
788 */
789vec3.max = function(out, a, b) {
790    out[0] = Math.max(a[0], b[0]);
791    out[1] = Math.max(a[1], b[1]);
792    out[2] = Math.max(a[2], b[2]);
793    return out;
794};
795
796/**
797 * Scales a vec3 by a scalar number
798 *
799 * @param {vec3} out the receiving vector
800 * @param {vec3} a the vector to scale
801 * @param {Number} b amount to scale the vector by
802 * @returns {vec3} out
803 */
804vec3.scale = function(out, a, b) {
805    out[0] = a[0] * b;
806    out[1] = a[1] * b;
807    out[2] = a[2] * b;
808    return out;
809};
810
811/**
812 * Calculates the euclidian distance between two vec3's
813 *
814 * @param {vec3} a the first operand
815 * @param {vec3} b the second operand
816 * @returns {Number} distance between a and b
817 */
818vec3.distance = function(a, b) {
819    var x = b[0] - a[0],
820        y = b[1] - a[1],
821        z = b[2] - a[2];
822    return Math.sqrt(x*x + y*y + z*z);
823};
824
825/**
826 * Alias for {@link vec3.distance}
827 * @function
828 */
829vec3.dist = vec3.distance;
830
831/**
832 * Calculates the squared euclidian distance between two vec3's
833 *
834 * @param {vec3} a the first operand
835 * @param {vec3} b the second operand
836 * @returns {Number} squared distance between a and b
837 */
838vec3.squaredDistance = function(a, b) {
839    var x = b[0] - a[0],
840        y = b[1] - a[1],
841        z = b[2] - a[2];
842    return x*x + y*y + z*z;
843};
844
845/**
846 * Alias for {@link vec3.squaredDistance}
847 * @function
848 */
849vec3.sqrDist = vec3.squaredDistance;
850
851/**
852 * Calculates the length of a vec3
853 *
854 * @param {vec3} a vector to calculate length of
855 * @returns {Number} length of a
856 */
857vec3.length = function (a) {
858    var x = a[0],
859        y = a[1],
860        z = a[2];
861    return Math.sqrt(x*x + y*y + z*z);
862};
863
864/**
865 * Alias for {@link vec3.length}
866 * @function
867 */
868vec3.len = vec3.length;
869
870/**
871 * Calculates the squared length of a vec3
872 *
873 * @param {vec3} a vector to calculate squared length of
874 * @returns {Number} squared length of a
875 */
876vec3.squaredLength = function (a) {
877    var x = a[0],
878        y = a[1],
879        z = a[2];
880    return x*x + y*y + z*z;
881};
882
883/**
884 * Alias for {@link vec3.squaredLength}
885 * @function
886 */
887vec3.sqrLen = vec3.squaredLength;
888
889/**
890 * Negates the components of a vec3
891 *
892 * @param {vec3} out the receiving vector
893 * @param {vec3} a vector to negate
894 * @returns {vec3} out
895 */
896vec3.negate = function(out, a) {
897    out[0] = -a[0];
898    out[1] = -a[1];
899    out[2] = -a[2];
900    return out;
901};
902
903/**
904 * Normalize a vec3
905 *
906 * @param {vec3} out the receiving vector
907 * @param {vec3} a vector to normalize
908 * @returns {vec3} out
909 */
910vec3.normalize = function(out, a) {
911    var x = a[0],
912        y = a[1],
913        z = a[2];
914    var len = x*x + y*y + z*z;
915    if (len > 0) {
916        //TODO: evaluate use of glm_invsqrt here?
917        len = 1 / Math.sqrt(len);
918        out[0] = a[0] * len;
919        out[1] = a[1] * len;
920        out[2] = a[2] * len;
921    }
922    return out;
923};
924
925/**
926 * Calculates the dot product of two vec3's
927 *
928 * @param {vec3} a the first operand
929 * @param {vec3} b the second operand
930 * @returns {Number} dot product of a and b
931 */
932vec3.dot = function (a, b) {
933    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
934};
935
936/**
937 * Computes the cross product of two vec3's
938 *
939 * @param {vec3} out the receiving vector
940 * @param {vec3} a the first operand
941 * @param {vec3} b the second operand
942 * @returns {vec3} out
943 */
944vec3.cross = function(out, a, b) {
945    var ax = a[0], ay = a[1], az = a[2],
946        bx = b[0], by = b[1], bz = b[2];
947
948    out[0] = ay * bz - az * by;
949    out[1] = az * bx - ax * bz;
950    out[2] = ax * by - ay * bx;
951    return out;
952};
953
954/**
955 * Performs a linear interpolation between two vec3's
956 *
957 * @param {vec3} out the receiving vector
958 * @param {vec3} a the first operand
959 * @param {vec3} b the second operand
960 * @param {Number} t interpolation amount between the two inputs
961 * @returns {vec3} out
962 */
963vec3.lerp = function (out, a, b, t) {
964    var ax = a[0],
965        ay = a[1],
966        az = a[2];
967    out[0] = ax + t * (b[0] - ax);
968    out[1] = ay + t * (b[1] - ay);
969    out[2] = az + t * (b[2] - az);
970    return out;
971};
972
973/**
974 * Transforms the vec3 with a mat4.
975 * 4th vector component is implicitly '1'
976 *
977 * @param {vec3} out the receiving vector
978 * @param {vec3} a the vector to transform
979 * @param {mat4} m matrix to transform with
980 * @returns {vec3} out
981 */
982vec3.transformMat4 = function(out, a, m) {
983    var x = a[0], y = a[1], z = a[2];
984    out[0] = m[0] * x + m[4] * y + m[8] * z + m[12];
985    out[1] = m[1] * x + m[5] * y + m[9] * z + m[13];
986    out[2] = m[2] * x + m[6] * y + m[10] * z + m[14];
987    return out;
988};
989
990/**
991 * Transforms the vec3 with a quat
992 *
993 * @param {vec3} out the receiving vector
994 * @param {vec3} a the vector to transform
995 * @param {quat} q quaternion to transform with
996 * @returns {vec3} out
997 */
998vec3.transformQuat = function(out, a, q) {
999    var x = a[0], y = a[1], z = a[2],
1000        qx = q[0], qy = q[1], qz = q[2], qw = q[3],
1001
1002        // calculate quat * vec
1003        ix = qw * x + qy * z - qz * y,
1004        iy = qw * y + qz * x - qx * z,
1005        iz = qw * z + qx * y - qy * x,
1006        iw = -qx * x - qy * y - qz * z;
1007
1008    // calculate result * inverse quat
1009    out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
1010    out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
1011    out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
1012    return out;
1013};
1014
1015/**
1016 * Perform some operation over an array of vec3s.
1017 *
1018 * @param {Array} a the array of vectors to iterate over
1019 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
1020 * @param {Number} offset Number of elements to skip at the beginning of the array
1021 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
1022 * @param {Function} fn Function to call for each vector in the array
1023 * @param {Object} [arg] additional argument to pass to fn
1024 * @returns {Array} a
1025 * @function
1026 */
1027vec3.forEach = (function() {
1028    var vec = vec3.create();
1029
1030    return function(a, stride, offset, count, fn, arg) {
1031        var i, l;
1032        if(!stride) {
1033            stride = 3;
1034        }
1035
1036        if(!offset) {
1037            offset = 0;
1038        }
1039
1040        if(count) {
1041            l = Math.min((count * stride) + offset, a.length);
1042        } else {
1043            l = a.length;
1044        }
1045
1046        for(i = offset; i < l; i += stride) {
1047            vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2];
1048            fn(vec, vec, arg);
1049            a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2];
1050        }
1051
1052        return a;
1053    };
1054})();
1055
1056/**
1057 * Returns a string representation of a vector
1058 *
1059 * @param {vec3} vec vector to represent as a string
1060 * @returns {String} string representation of the vector
1061 */
1062vec3.str = function (a) {
1063    return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
1064};
1065
1066if(typeof(exports) !== 'undefined') {
1067    exports.vec3 = vec3;
1068}
1069;
1070/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
1071
1072Redistribution and use in source and binary forms, with or without modification,
1073are permitted provided that the following conditions are met:
1074
1075  * Redistributions of source code must retain the above copyright notice, this
1076    list of conditions and the following disclaimer.
1077  * Redistributions in binary form must reproduce the above copyright notice,
1078    this list of conditions and the following disclaimer in the documentation
1079    and/or other materials provided with the distribution.
1080
1081THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1082ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1083WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1084DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1085ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1086(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1087LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1088ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1089(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1090SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
1091
1092/**
1093 * @class 4 Dimensional Vector
1094 * @name vec4
1095 */
1096
1097var vec4 = {};
1098
1099/**
1100 * Creates a new, empty vec4
1101 *
1102 * @returns {vec4} a new 4D vector
1103 */
1104vec4.create = function() {
1105    var out = new GLMAT_ARRAY_TYPE(4);
1106    out[0] = 0;
1107    out[1] = 0;
1108    out[2] = 0;
1109    out[3] = 0;
1110    return out;
1111};
1112
1113/**
1114 * Creates a new vec4 initialized with values from an existing vector
1115 *
1116 * @param {vec4} a vector to clone
1117 * @returns {vec4} a new 4D vector
1118 */
1119vec4.clone = function(a) {
1120    var out = new GLMAT_ARRAY_TYPE(4);
1121    out[0] = a[0];
1122    out[1] = a[1];
1123    out[2] = a[2];
1124    out[3] = a[3];
1125    return out;
1126};
1127
1128/**
1129 * Creates a new vec4 initialized with the given values
1130 *
1131 * @param {Number} x X component
1132 * @param {Number} y Y component
1133 * @param {Number} z Z component
1134 * @param {Number} w W component
1135 * @returns {vec4} a new 4D vector
1136 */
1137vec4.fromValues = function(x, y, z, w) {
1138    var out = new GLMAT_ARRAY_TYPE(4);
1139    out[0] = x;
1140    out[1] = y;
1141    out[2] = z;
1142    out[3] = w;
1143    return out;
1144};
1145
1146/**
1147 * Copy the values from one vec4 to another
1148 *
1149 * @param {vec4} out the receiving vector
1150 * @param {vec4} a the source vector
1151 * @returns {vec4} out
1152 */
1153vec4.copy = function(out, a) {
1154    out[0] = a[0];
1155    out[1] = a[1];
1156    out[2] = a[2];
1157    out[3] = a[3];
1158    return out;
1159};
1160
1161/**
1162 * Set the components of a vec4 to the given values
1163 *
1164 * @param {vec4} out the receiving vector
1165 * @param {Number} x X component
1166 * @param {Number} y Y component
1167 * @param {Number} z Z component
1168 * @param {Number} w W component
1169 * @returns {vec4} out
1170 */
1171vec4.set = function(out, x, y, z, w) {
1172    out[0] = x;
1173    out[1] = y;
1174    out[2] = z;
1175    out[3] = w;
1176    return out;
1177};
1178
1179/**
1180 * Adds two vec4's
1181 *
1182 * @param {vec4} out the receiving vector
1183 * @param {vec4} a the first operand
1184 * @param {vec4} b the second operand
1185 * @returns {vec4} out
1186 */
1187vec4.add = function(out, a, b) {
1188    out[0] = a[0] + b[0];
1189    out[1] = a[1] + b[1];
1190    out[2] = a[2] + b[2];
1191    out[3] = a[3] + b[3];
1192    return out;
1193};
1194
1195/**
1196 * Subtracts two vec4's
1197 *
1198 * @param {vec4} out the receiving vector
1199 * @param {vec4} a the first operand
1200 * @param {vec4} b the second operand
1201 * @returns {vec4} out
1202 */
1203vec4.subtract = function(out, a, b) {
1204    out[0] = a[0] - b[0];
1205    out[1] = a[1] - b[1];
1206    out[2] = a[2] - b[2];
1207    out[3] = a[3] - b[3];
1208    return out;
1209};
1210
1211/**
1212 * Alias for {@link vec4.subtract}
1213 * @function
1214 */
1215vec4.sub = vec4.subtract;
1216
1217/**
1218 * Multiplies two vec4's
1219 *
1220 * @param {vec4} out the receiving vector
1221 * @param {vec4} a the first operand
1222 * @param {vec4} b the second operand
1223 * @returns {vec4} out
1224 */
1225vec4.multiply = function(out, a, b) {
1226    out[0] = a[0] * b[0];
1227    out[1] = a[1] * b[1];
1228    out[2] = a[2] * b[2];
1229    out[3] = a[3] * b[3];
1230    return out;
1231};
1232
1233/**
1234 * Alias for {@link vec4.multiply}
1235 * @function
1236 */
1237vec4.mul = vec4.multiply;
1238
1239/**
1240 * Divides two vec4's
1241 *
1242 * @param {vec4} out the receiving vector
1243 * @param {vec4} a the first operand
1244 * @param {vec4} b the second operand
1245 * @returns {vec4} out
1246 */
1247vec4.divide = function(out, a, b) {
1248    out[0] = a[0] / b[0];
1249    out[1] = a[1] / b[1];
1250    out[2] = a[2] / b[2];
1251    out[3] = a[3] / b[3];
1252    return out;
1253};
1254
1255/**
1256 * Alias for {@link vec4.divide}
1257 * @function
1258 */
1259vec4.div = vec4.divide;
1260
1261/**
1262 * Returns the minimum of two vec4's
1263 *
1264 * @param {vec4} out the receiving vector
1265 * @param {vec4} a the first operand
1266 * @param {vec4} b the second operand
1267 * @returns {vec4} out
1268 */
1269vec4.min = function(out, a, b) {
1270    out[0] = Math.min(a[0], b[0]);
1271    out[1] = Math.min(a[1], b[1]);
1272    out[2] = Math.min(a[2], b[2]);
1273    out[3] = Math.min(a[3], b[3]);
1274    return out;
1275};
1276
1277/**
1278 * Returns the maximum of two vec4's
1279 *
1280 * @param {vec4} out the receiving vector
1281 * @param {vec4} a the first operand
1282 * @param {vec4} b the second operand
1283 * @returns {vec4} out
1284 */
1285vec4.max = function(out, a, b) {
1286    out[0] = Math.max(a[0], b[0]);
1287    out[1] = Math.max(a[1], b[1]);
1288    out[2] = Math.max(a[2], b[2]);
1289    out[3] = Math.max(a[3], b[3]);
1290    return out;
1291};
1292
1293/**
1294 * Scales a vec4 by a scalar number
1295 *
1296 * @param {vec4} out the receiving vector
1297 * @param {vec4} a the vector to scale
1298 * @param {Number} b amount to scale the vector by
1299 * @returns {vec4} out
1300 */
1301vec4.scale = function(out, a, b) {
1302    out[0] = a[0] * b;
1303    out[1] = a[1] * b;
1304    out[2] = a[2] * b;
1305    out[3] = a[3] * b;
1306    return out;
1307};
1308
1309/**
1310 * Calculates the euclidian distance between two vec4's
1311 *
1312 * @param {vec4} a the first operand
1313 * @param {vec4} b the second operand
1314 * @returns {Number} distance between a and b
1315 */
1316vec4.distance = function(a, b) {
1317    var x = b[0] - a[0],
1318        y = b[1] - a[1],
1319        z = b[2] - a[2],
1320        w = b[3] - a[3];
1321    return Math.sqrt(x*x + y*y + z*z + w*w);
1322};
1323
1324/**
1325 * Alias for {@link vec4.distance}
1326 * @function
1327 */
1328vec4.dist = vec4.distance;
1329
1330/**
1331 * Calculates the squared euclidian distance between two vec4's
1332 *
1333 * @param {vec4} a the first operand
1334 * @param {vec4} b the second operand
1335 * @returns {Number} squared distance between a and b
1336 */
1337vec4.squaredDistance = function(a, b) {
1338    var x = b[0] - a[0],
1339        y = b[1] - a[1],
1340        z = b[2] - a[2],
1341        w = b[3] - a[3];
1342    return x*x + y*y + z*z + w*w;
1343};
1344
1345/**
1346 * Alias for {@link vec4.squaredDistance}
1347 * @function
1348 */
1349vec4.sqrDist = vec4.squaredDistance;
1350
1351/**
1352 * Calculates the length of a vec4
1353 *
1354 * @param {vec4} a vector to calculate length of
1355 * @returns {Number} length of a
1356 */
1357vec4.length = function (a) {
1358    var x = a[0],
1359        y = a[1],
1360        z = a[2],
1361        w = a[3];
1362    return Math.sqrt(x*x + y*y + z*z + w*w);
1363};
1364
1365/**
1366 * Alias for {@link vec4.length}
1367 * @function
1368 */
1369vec4.len = vec4.length;
1370
1371/**
1372 * Calculates the squared length of a vec4
1373 *
1374 * @param {vec4} a vector to calculate squared length of
1375 * @returns {Number} squared length of a
1376 */
1377vec4.squaredLength = function (a) {
1378    var x = a[0],
1379        y = a[1],
1380        z = a[2],
1381        w = a[3];
1382    return x*x + y*y + z*z + w*w;
1383};
1384
1385/**
1386 * Alias for {@link vec4.squaredLength}
1387 * @function
1388 */
1389vec4.sqrLen = vec4.squaredLength;
1390
1391/**
1392 * Negates the components of a vec4
1393 *
1394 * @param {vec4} out the receiving vector
1395 * @param {vec4} a vector to negate
1396 * @returns {vec4} out
1397 */
1398vec4.negate = function(out, a) {
1399    out[0] = -a[0];
1400    out[1] = -a[1];
1401    out[2] = -a[2];
1402    out[3] = -a[3];
1403    return out;
1404};
1405
1406/**
1407 * Normalize a vec4
1408 *
1409 * @param {vec4} out the receiving vector
1410 * @param {vec4} a vector to normalize
1411 * @returns {vec4} out
1412 */
1413vec4.normalize = function(out, a) {
1414    var x = a[0],
1415        y = a[1],
1416        z = a[2],
1417        w = a[3];
1418    var len = x*x + y*y + z*z + w*w;
1419    if (len > 0) {
1420        len = 1 / Math.sqrt(len);
1421        out[0] = a[0] * len;
1422        out[1] = a[1] * len;
1423        out[2] = a[2] * len;
1424        out[3] = a[3] * len;
1425    }
1426    return out;
1427};
1428
1429/**
1430 * Calculates the dot product of two vec4's
1431 *
1432 * @param {vec4} a the first operand
1433 * @param {vec4} b the second operand
1434 * @returns {Number} dot product of a and b
1435 */
1436vec4.dot = function (a, b) {
1437    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
1438};
1439
1440/**
1441 * Performs a linear interpolation between two vec4's
1442 *
1443 * @param {vec4} out the receiving vector
1444 * @param {vec4} a the first operand
1445 * @param {vec4} b the second operand
1446 * @param {Number} t interpolation amount between the two inputs
1447 * @returns {vec4} out
1448 */
1449vec4.lerp = function (out, a, b, t) {
1450    var ax = a[0],
1451        ay = a[1],
1452        az = a[2],
1453        aw = a[3];
1454    out[0] = ax + t * (b[0] - ax);
1455    out[1] = ay + t * (b[1] - ay);
1456    out[2] = az + t * (b[2] - az);
1457    out[3] = aw + t * (b[3] - aw);
1458    return out;
1459};
1460
1461/**
1462 * Transforms the vec4 with a mat4.
1463 *
1464 * @param {vec4} out the receiving vector
1465 * @param {vec4} a the vector to transform
1466 * @param {mat4} m matrix to transform with
1467 * @returns {vec4} out
1468 */
1469vec4.transformMat4 = function(out, a, m) {
1470    var x = a[0], y = a[1], z = a[2], w = a[3];
1471    out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
1472    out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
1473    out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
1474    out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
1475    return out;
1476};
1477
1478/**
1479 * Transforms the vec4 with a quat
1480 *
1481 * @param {vec4} out the receiving vector
1482 * @param {vec4} a the vector to transform
1483 * @param {quat} q quaternion to transform with
1484 * @returns {vec4} out
1485 */
1486vec4.transformQuat = function(out, a, q) {
1487    var x = a[0], y = a[1], z = a[2],
1488        qx = q[0], qy = q[1], qz = q[2], qw = q[3],
1489
1490        // calculate quat * vec
1491        ix = qw * x + qy * z - qz * y,
1492        iy = qw * y + qz * x - qx * z,
1493        iz = qw * z + qx * y - qy * x,
1494        iw = -qx * x - qy * y - qz * z;
1495
1496    // calculate result * inverse quat
1497    out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
1498    out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
1499    out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
1500    return out;
1501};
1502
1503/**
1504 * Perform some operation over an array of vec4s.
1505 *
1506 * @param {Array} a the array of vectors to iterate over
1507 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
1508 * @param {Number} offset Number of elements to skip at the beginning of the array
1509 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
1510 * @param {Function} fn Function to call for each vector in the array
1511 * @param {Object} [arg] additional argument to pass to fn
1512 * @returns {Array} a
1513 * @function
1514 */
1515vec4.forEach = (function() {
1516    var vec = vec4.create();
1517
1518    return function(a, stride, offset, count, fn, arg) {
1519        var i, l;
1520        if(!stride) {
1521            stride = 4;
1522        }
1523
1524        if(!offset) {
1525            offset = 0;
1526        }
1527
1528        if(count) {
1529            l = Math.min((count * stride) + offset, a.length);
1530        } else {
1531            l = a.length;
1532        }
1533
1534        for(i = offset; i < l; i += stride) {
1535            vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3];
1536            fn(vec, vec, arg);
1537            a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3];
1538        }
1539
1540        return a;
1541    };
1542})();
1543
1544/**
1545 * Returns a string representation of a vector
1546 *
1547 * @param {vec4} vec vector to represent as a string
1548 * @returns {String} string representation of the vector
1549 */
1550vec4.str = function (a) {
1551    return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
1552};
1553
1554if(typeof(exports) !== 'undefined') {
1555    exports.vec4 = vec4;
1556}
1557;
1558/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
1559
1560Redistribution and use in source and binary forms, with or without modification,
1561are permitted provided that the following conditions are met:
1562
1563  * Redistributions of source code must retain the above copyright notice, this
1564    list of conditions and the following disclaimer.
1565  * Redistributions in binary form must reproduce the above copyright notice,
1566    this list of conditions and the following disclaimer in the documentation
1567    and/or other materials provided with the distribution.
1568
1569THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1570ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1571WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1572DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1573ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1574(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1575LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1576ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1577(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1578SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
1579
1580/**
1581 * @class 2x2 Matrix
1582 * @name mat2
1583 */
1584
1585var mat2 = {};
1586
1587/**
1588 * Creates a new identity mat2
1589 *
1590 * @returns {mat2} a new 2x2 matrix
1591 */
1592mat2.create = function() {
1593    var out = new GLMAT_ARRAY_TYPE(4);
1594    out[0] = 1;
1595    out[1] = 0;
1596    out[2] = 0;
1597    out[3] = 1;
1598    return out;
1599};
1600
1601/**
1602 * Creates a new mat2 initialized with values from an existing matrix
1603 *
1604 * @param {mat2} a matrix to clone
1605 * @returns {mat2} a new 2x2 matrix
1606 */
1607mat2.clone = function(a) {
1608    var out = new GLMAT_ARRAY_TYPE(4);
1609    out[0] = a[0];
1610    out[1] = a[1];
1611    out[2] = a[2];
1612    out[3] = a[3];
1613    return out;
1614};
1615
1616/**
1617 * Copy the values from one mat2 to another
1618 *
1619 * @param {mat2} out the receiving matrix
1620 * @param {mat2} a the source matrix
1621 * @returns {mat2} out
1622 */
1623mat2.copy = function(out, a) {
1624    out[0] = a[0];
1625    out[1] = a[1];
1626    out[2] = a[2];
1627    out[3] = a[3];
1628    return out;
1629};
1630
1631/**
1632 * Set a mat2 to the identity matrix
1633 *
1634 * @param {mat2} out the receiving matrix
1635 * @returns {mat2} out
1636 */
1637mat2.identity = function(out) {
1638    out[0] = 1;
1639    out[1] = 0;
1640    out[2] = 0;
1641    out[3] = 1;
1642    return out;
1643};
1644
1645/**
1646 * Transpose the values of a mat2
1647 *
1648 * @param {mat2} out the receiving matrix
1649 * @param {mat2} a the source matrix
1650 * @returns {mat2} out
1651 */
1652mat2.transpose = function(out, a) {
1653    // If we are transposing ourselves we can skip a few steps but have to cache some values
1654    if (out === a) {
1655        var a1 = a[1];
1656        out[1] = a[2];
1657        out[2] = a1;
1658    } else {
1659        out[0] = a[0];
1660        out[1] = a[2];
1661        out[2] = a[1];
1662        out[3] = a[3];
1663    }
1664
1665    return out;
1666};
1667
1668/**
1669 * Inverts a mat2
1670 *
1671 * @param {mat2} out the receiving matrix
1672 * @param {mat2} a the source matrix
1673 * @returns {mat2} out
1674 */
1675mat2.invert = function(out, a) {
1676    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
1677
1678        // Calculate the determinant
1679        det = a0 * a3 - a2 * a1;
1680
1681    if (!det) {
1682        return null;
1683    }
1684    det = 1.0 / det;
1685
1686    out[0] =  a3 * det;
1687    out[1] = -a1 * det;
1688    out[2] = -a2 * det;
1689    out[3] =  a0 * det;
1690
1691    return out;
1692};
1693
1694/**
1695 * Calculates the adjugate of a mat2
1696 *
1697 * @param {mat2} out the receiving matrix
1698 * @param {mat2} a the source matrix
1699 * @returns {mat2} out
1700 */
1701mat2.adjoint = function(out, a) {
1702    // Caching this value is nessecary if out == a
1703    var a0 = a[0];
1704    out[0] =  a[3];
1705    out[1] = -a[1];
1706    out[2] = -a[2];
1707    out[3] =  a0;
1708
1709    return out;
1710};
1711
1712/**
1713 * Calculates the determinant of a mat2
1714 *
1715 * @param {mat2} a the source matrix
1716 * @returns {Number} determinant of a
1717 */
1718mat2.determinant = function (a) {
1719    return a[0] * a[3] - a[2] * a[1];
1720};
1721
1722/**
1723 * Multiplies two mat2's
1724 *
1725 * @param {mat2} out the receiving matrix
1726 * @param {mat2} a the first operand
1727 * @param {mat2} b the second operand
1728 * @returns {mat2} out
1729 */
1730mat2.multiply = function (out, a, b) {
1731    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
1732    var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
1733    out[0] = a0 * b0 + a1 * b2;
1734    out[1] = a0 * b1 + a1 * b3;
1735    out[2] = a2 * b0 + a3 * b2;
1736    out[3] = a2 * b1 + a3 * b3;
1737    return out;
1738};
1739
1740/**
1741 * Alias for {@link mat2.multiply}
1742 * @function
1743 */
1744mat2.mul = mat2.multiply;
1745
1746/**
1747 * Rotates a mat2 by the given angle
1748 *
1749 * @param {mat2} out the receiving matrix
1750 * @param {mat2} a the matrix to rotate
1751 * @param {Number} rad the angle to rotate the matrix by
1752 * @returns {mat2} out
1753 */
1754mat2.rotate = function (out, a, rad) {
1755    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
1756        s = Math.sin(rad),
1757        c = Math.cos(rad);
1758    out[0] = a0 *  c + a1 * s;
1759    out[1] = a0 * -s + a1 * c;
1760    out[2] = a2 *  c + a3 * s;
1761    out[3] = a2 * -s + a3 * c;
1762    return out;
1763};
1764
1765/**
1766 * Scales the mat2 by the dimensions in the given vec2
1767 *
1768 * @param {mat2} out the receiving matrix
1769 * @param {mat2} a the matrix to rotate
1770 * @param {vec2} v the vec2 to scale the matrix by
1771 * @returns {mat2} out
1772 **/
1773mat2.scale = function(out, a, v) {
1774    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
1775        v0 = v[0], v1 = v[1];
1776    out[0] = a0 * v0;
1777    out[1] = a1 * v1;
1778    out[2] = a2 * v0;
1779    out[3] = a3 * v1;
1780    return out;
1781};
1782
1783/**
1784 * Returns a string representation of a mat2
1785 *
1786 * @param {mat2} mat matrix to represent as a string
1787 * @returns {String} string representation of the matrix
1788 */
1789mat2.str = function (a) {
1790    return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
1791};
1792
1793if(typeof(exports) !== 'undefined') {
1794    exports.mat2 = mat2;
1795}
1796;
1797/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
1798
1799Redistribution and use in source and binary forms, with or without modification,
1800are permitted provided that the following conditions are met:
1801
1802  * Redistributions of source code must retain the above copyright notice, this
1803    list of conditions and the following disclaimer.
1804  * Redistributions in binary form must reproduce the above copyright notice,
1805    this list of conditions and the following disclaimer in the documentation
1806    and/or other materials provided with the distribution.
1807
1808THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1809ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1810WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1811DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1812ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1813(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1814LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1815ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1816(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1817SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
1818
1819/**
1820 * @class 2x3 Matrix
1821 * @name mat2d
1822 *
1823 * @description
1824 * A mat2d contains six elements defined as:
1825 * <pre>
1826 * [a, b,
1827 *  c, d,
1828 *  tx,ty]
1829 * </pre>
1830 * This is a short form for the 3x3 matrix:
1831 * <pre>
1832 * [a, b, 0
1833 *  c, d, 0
1834 *  tx,ty,1]
1835 * </pre>
1836 * The last column is ignored so the array is shorter and operations are faster.
1837 */
1838
1839var mat2d = {};
1840
1841/**
1842 * Creates a new identity mat2d
1843 *
1844 * @returns {mat2d} a new 2x3 matrix
1845 */
1846mat2d.create = function() {
1847    var out = new GLMAT_ARRAY_TYPE(6);
1848    out[0] = 1;
1849    out[1] = 0;
1850    out[2] = 0;
1851    out[3] = 1;
1852    out[4] = 0;
1853    out[5] = 0;
1854    return out;
1855};
1856
1857/**
1858 * Creates a new mat2d initialized with values from an existing matrix
1859 *
1860 * @param {mat2d} a matrix to clone
1861 * @returns {mat2d} a new 2x3 matrix
1862 */
1863mat2d.clone = function(a) {
1864    var out = new GLMAT_ARRAY_TYPE(6);
1865    out[0] = a[0];
1866    out[1] = a[1];
1867    out[2] = a[2];
1868    out[3] = a[3];
1869    out[4] = a[4];
1870    out[5] = a[5];
1871    return out;
1872};
1873
1874/**
1875 * Copy the values from one mat2d to another
1876 *
1877 * @param {mat2d} out the receiving matrix
1878 * @param {mat2d} a the source matrix
1879 * @returns {mat2d} out
1880 */
1881mat2d.copy = function(out, a) {
1882    out[0] = a[0];
1883    out[1] = a[1];
1884    out[2] = a[2];
1885    out[3] = a[3];
1886    out[4] = a[4];
1887    out[5] = a[5];
1888    return out;
1889};
1890
1891/**
1892 * Set a mat2d to the identity matrix
1893 *
1894 * @param {mat2d} out the receiving matrix
1895 * @returns {mat2d} out
1896 */
1897mat2d.identity = function(out) {
1898    out[0] = 1;
1899    out[1] = 0;
1900    out[2] = 0;
1901    out[3] = 1;
1902    out[4] = 0;
1903    out[5] = 0;
1904    return out;
1905};
1906
1907/**
1908 * Inverts a mat2d
1909 *
1910 * @param {mat2d} out the receiving matrix
1911 * @param {mat2d} a the source matrix
1912 * @returns {mat2d} out
1913 */
1914mat2d.invert = function(out, a) {
1915    var aa = a[0], ab = a[1], ac = a[2], ad = a[3],
1916        atx = a[4], aty = a[5];
1917
1918    var det = aa * ad - ab * ac;
1919    if(!det){
1920        return null;
1921    }
1922    det = 1.0 / det;
1923
1924    out[0] = ad * det;
1925    out[1] = -ab * det;
1926    out[2] = -ac * det;
1927    out[3] = aa * det;
1928    out[4] = (ac * aty - ad * atx) * det;
1929    out[5] = (ab * atx - aa * aty) * det;
1930    return out;
1931};
1932
1933/**
1934 * Calculates the determinant of a mat2d
1935 *
1936 * @param {mat2d} a the source matrix
1937 * @returns {Number} determinant of a
1938 */
1939mat2d.determinant = function (a) {
1940    return a[0] * a[3] - a[1] * a[2];
1941};
1942
1943/**
1944 * Multiplies two mat2d's
1945 *
1946 * @param {mat2d} out the receiving matrix
1947 * @param {mat2d} a the first operand
1948 * @param {mat2d} b the second operand
1949 * @returns {mat2d} out
1950 */
1951mat2d.multiply = function (out, a, b) {
1952    var aa = a[0], ab = a[1], ac = a[2], ad = a[3],
1953        atx = a[4], aty = a[5],
1954        ba = b[0], bb = b[1], bc = b[2], bd = b[3],
1955        btx = b[4], bty = b[5];
1956
1957    out[0] = aa*ba + ab*bc;
1958    out[1] = aa*bb + ab*bd;
1959    out[2] = ac*ba + ad*bc;
1960    out[3] = ac*bb + ad*bd;
1961    out[4] = ba*atx + bc*aty + btx;
1962    out[5] = bb*atx + bd*aty + bty;
1963    return out;
1964};
1965
1966/**
1967 * Alias for {@link mat2d.multiply}
1968 * @function
1969 */
1970mat2d.mul = mat2d.multiply;
1971
1972
1973/**
1974 * Rotates a mat2d by the given angle
1975 *
1976 * @param {mat2d} out the receiving matrix
1977 * @param {mat2d} a the matrix to rotate
1978 * @param {Number} rad the angle to rotate the matrix by
1979 * @returns {mat2d} out
1980 */
1981mat2d.rotate = function (out, a, rad) {
1982    var aa = a[0],
1983        ab = a[1],
1984        ac = a[2],
1985        ad = a[3],
1986        atx = a[4],
1987        aty = a[5],
1988        st = Math.sin(rad),
1989        ct = Math.cos(rad);
1990
1991    out[0] = aa*ct + ab*st;
1992    out[1] = -aa*st + ab*ct;
1993    out[2] = ac*ct + ad*st;
1994    out[3] = -ac*st + ct*ad;
1995    out[4] = ct*atx + st*aty;
1996    out[5] = ct*aty - st*atx;
1997    return out;
1998};
1999
2000/**
2001 * Scales the mat2d by the dimensions in the given vec2
2002 *
2003 * @param {mat2d} out the receiving matrix
2004 * @param {mat2d} a the matrix to translate
2005 * @param {mat2d} v the vec2 to scale the matrix by
2006 * @returns {mat2d} out
2007 **/
2008mat2d.scale = function(out, a, v) {
2009    var vx = v[0], vy = v[1];
2010    out[0] = a[0] * vx;
2011    out[1] = a[1] * vy;
2012    out[2] = a[2] * vx;
2013    out[3] = a[3] * vy;
2014    out[4] = a[4] * vx;
2015    out[5] = a[5] * vy;
2016    return out;
2017};
2018
2019/**
2020 * Translates the mat2d by the dimensions in the given vec2
2021 *
2022 * @param {mat2d} out the receiving matrix
2023 * @param {mat2d} a the matrix to translate
2024 * @param {mat2d} v the vec2 to translate the matrix by
2025 * @returns {mat2d} out
2026 **/
2027mat2d.translate = function(out, a, v) {
2028    out[0] = a[0];
2029    out[1] = a[1];
2030    out[2] = a[2];
2031    out[3] = a[3];
2032    out[4] = a[4] + v[0];
2033    out[5] = a[5] + v[1];
2034    return out;
2035};
2036
2037/**
2038 * Returns a string representation of a mat2d
2039 *
2040 * @param {mat2d} a matrix to represent as a string
2041 * @returns {String} string representation of the matrix
2042 */
2043mat2d.str = function (a) {
2044    return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
2045                    a[3] + ', ' + a[4] + ', ' + a[5] + ')';
2046};
2047
2048if(typeof(exports) !== 'undefined') {
2049    exports.mat2d = mat2d;
2050}
2051;
2052/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
2053
2054Redistribution and use in source and binary forms, with or without modification,
2055are permitted provided that the following conditions are met:
2056
2057  * Redistributions of source code must retain the above copyright notice, this
2058    list of conditions and the following disclaimer.
2059  * Redistributions in binary form must reproduce the above copyright notice,
2060    this list of conditions and the following disclaimer in the documentation
2061    and/or other materials provided with the distribution.
2062
2063THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2064ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2065WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2066DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
2067ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2068(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2069LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2070ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2071(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2072SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
2073
2074/**
2075 * @class 3x3 Matrix
2076 * @name mat3
2077 */
2078
2079var mat3 = {};
2080
2081/**
2082 * Creates a new identity mat3
2083 *
2084 * @returns {mat3} a new 3x3 matrix
2085 */
2086mat3.create = function() {
2087    var out = new GLMAT_ARRAY_TYPE(9);
2088    out[0] = 1;
2089    out[1] = 0;
2090    out[2] = 0;
2091    out[3] = 0;
2092    out[4] = 1;
2093    out[5] = 0;
2094    out[6] = 0;
2095    out[7] = 0;
2096    out[8] = 1;
2097    return out;
2098};
2099
2100/**
2101 * Copies the upper-left 3x3 values into the given mat3.
2102 *
2103 * @param {mat3} out the receiving 3x3 matrix
2104 * @param {mat4} a   the source 4x4 matrix
2105 * @returns {mat3} out
2106 */
2107mat3.fromMat4 = function(out, a) {
2108    out[0] = a[0];
2109    out[1] = a[1];
2110    out[2] = a[2];
2111    out[3] = a[4];
2112    out[4] = a[5];
2113    out[5] = a[6];
2114    out[6] = a[8];
2115    out[7] = a[9];
2116    out[8] = a[10];
2117    return out;
2118};
2119
2120/**
2121 * Creates a new mat3 initialized with values from an existing matrix
2122 *
2123 * @param {mat3} a matrix to clone
2124 * @returns {mat3} a new 3x3 matrix
2125 */
2126mat3.clone = function(a) {
2127    var out = new GLMAT_ARRAY_TYPE(9);
2128    out[0] = a[0];
2129    out[1] = a[1];
2130    out[2] = a[2];
2131    out[3] = a[3];
2132    out[4] = a[4];
2133    out[5] = a[5];
2134    out[6] = a[6];
2135    out[7] = a[7];
2136    out[8] = a[8];
2137    return out;
2138};
2139
2140/**
2141 * Copy the values from one mat3 to another
2142 *
2143 * @param {mat3} out the receiving matrix
2144 * @param {mat3} a the source matrix
2145 * @returns {mat3} out
2146 */
2147mat3.copy = function(out, a) {
2148    out[0] = a[0];
2149    out[1] = a[1];
2150    out[2] = a[2];
2151    out[3] = a[3];
2152    out[4] = a[4];
2153    out[5] = a[5];
2154    out[6] = a[6];
2155    out[7] = a[7];
2156    out[8] = a[8];
2157    return out;
2158};
2159
2160/**
2161 * Set a mat3 to the identity matrix
2162 *
2163 * @param {mat3} out the receiving matrix
2164 * @returns {mat3} out
2165 */
2166mat3.identity = function(out) {
2167    out[0] = 1;
2168    out[1] = 0;
2169    out[2] = 0;
2170    out[3] = 0;
2171    out[4] = 1;
2172    out[5] = 0;
2173    out[6] = 0;
2174    out[7] = 0;
2175    out[8] = 1;
2176    return out;
2177};
2178
2179/**
2180 * Transpose the values of a mat3
2181 *
2182 * @param {mat3} out the receiving matrix
2183 * @param {mat3} a the source matrix
2184 * @returns {mat3} out
2185 */
2186mat3.transpose = function(out, a) {
2187    // If we are transposing ourselves we can skip a few steps but have to cache some values
2188    if (out === a) {
2189        var a01 = a[1], a02 = a[2], a12 = a[5];
2190        out[1] = a[3];
2191        out[2] = a[6];
2192        out[3] = a01;
2193        out[5] = a[7];
2194        out[6] = a02;
2195        out[7] = a12;
2196    } else {
2197        out[0] = a[0];
2198        out[1] = a[3];
2199        out[2] = a[6];
2200        out[3] = a[1];
2201        out[4] = a[4];
2202        out[5] = a[7];
2203        out[6] = a[2];
2204        out[7] = a[5];
2205        out[8] = a[8];
2206    }
2207
2208    return out;
2209};
2210
2211/**
2212 * Inverts a mat3
2213 *
2214 * @param {mat3} out the receiving matrix
2215 * @param {mat3} a the source matrix
2216 * @returns {mat3} out
2217 */
2218mat3.invert = function(out, a) {
2219    var a00 = a[0], a01 = a[1], a02 = a[2],
2220        a10 = a[3], a11 = a[4], a12 = a[5],
2221        a20 = a[6], a21 = a[7], a22 = a[8],
2222
2223        b01 = a22 * a11 - a12 * a21,
2224        b11 = -a22 * a10 + a12 * a20,
2225        b21 = a21 * a10 - a11 * a20,
2226
2227        // Calculate the determinant
2228        det = a00 * b01 + a01 * b11 + a02 * b21;
2229
2230    if (!det) {
2231        return null;
2232    }
2233    det = 1.0 / det;
2234
2235    out[0] = b01 * det;
2236    out[1] = (-a22 * a01 + a02 * a21) * det;
2237    out[2] = (a12 * a01 - a02 * a11) * det;
2238    out[3] = b11 * det;
2239    out[4] = (a22 * a00 - a02 * a20) * det;
2240    out[5] = (-a12 * a00 + a02 * a10) * det;
2241    out[6] = b21 * det;
2242    out[7] = (-a21 * a00 + a01 * a20) * det;
2243    out[8] = (a11 * a00 - a01 * a10) * det;
2244    return out;
2245};
2246
2247/**
2248 * Calculates the adjugate of a mat3
2249 *
2250 * @param {mat3} out the receiving matrix
2251 * @param {mat3} a the source matrix
2252 * @returns {mat3} out
2253 */
2254mat3.adjoint = function(out, a) {
2255    var a00 = a[0], a01 = a[1], a02 = a[2],
2256        a10 = a[3], a11 = a[4], a12 = a[5],
2257        a20 = a[6], a21 = a[7], a22 = a[8];
2258
2259    out[0] = (a11 * a22 - a12 * a21);
2260    out[1] = (a02 * a21 - a01 * a22);
2261    out[2] = (a01 * a12 - a02 * a11);
2262    out[3] = (a12 * a20 - a10 * a22);
2263    out[4] = (a00 * a22 - a02 * a20);
2264    out[5] = (a02 * a10 - a00 * a12);
2265    out[6] = (a10 * a21 - a11 * a20);
2266    out[7] = (a01 * a20 - a00 * a21);
2267    out[8] = (a00 * a11 - a01 * a10);
2268    return out;
2269};
2270
2271/**
2272 * Calculates the determinant of a mat3
2273 *
2274 * @param {mat3} a the source matrix
2275 * @returns {Number} determinant of a
2276 */
2277mat3.determinant = function (a) {
2278    var a00 = a[0], a01 = a[1], a02 = a[2],
2279        a10 = a[3], a11 = a[4], a12 = a[5],
2280        a20 = a[6], a21 = a[7], a22 = a[8];
2281
2282    return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
2283};
2284
2285/**
2286 * Multiplies two mat3's
2287 *
2288 * @param {mat3} out the receiving matrix
2289 * @param {mat3} a the first operand
2290 * @param {mat3} b the second operand
2291 * @returns {mat3} out
2292 */
2293mat3.multiply = function (out, a, b) {
2294    var a00 = a[0], a01 = a[1], a02 = a[2],
2295        a10 = a[3], a11 = a[4], a12 = a[5],
2296        a20 = a[6], a21 = a[7], a22 = a[8],
2297
2298        b00 = b[0], b01 = b[1], b02 = b[2],
2299        b10 = b[3], b11 = b[4], b12 = b[5],
2300        b20 = b[6], b21 = b[7], b22 = b[8];
2301
2302    out[0] = b00 * a00 + b01 * a10 + b02 * a20;
2303    out[1] = b00 * a01 + b01 * a11 + b02 * a21;
2304    out[2] = b00 * a02 + b01 * a12 + b02 * a22;
2305
2306    out[3] = b10 * a00 + b11 * a10 + b12 * a20;
2307    out[4] = b10 * a01 + b11 * a11 + b12 * a21;
2308    out[5] = b10 * a02 + b11 * a12 + b12 * a22;
2309
2310    out[6] = b20 * a00 + b21 * a10 + b22 * a20;
2311    out[7] = b20 * a01 + b21 * a11 + b22 * a21;
2312    out[8] = b20 * a02 + b21 * a12 + b22 * a22;
2313    return out;
2314};
2315
2316/**
2317 * Alias for {@link mat3.multiply}
2318 * @function
2319 */
2320mat3.mul = mat3.multiply;
2321
2322/**
2323 * Translate a mat3 by the given vector
2324 *
2325 * @param {mat3} out the receiving matrix
2326 * @param {mat3} a the matrix to translate
2327 * @param {vec2} v vector to translate by
2328 * @returns {mat3} out
2329 */
2330mat3.translate = function(out, a, v) {
2331    var a00 = a[0], a01 = a[1], a02 = a[2],
2332        a10 = a[3], a11 = a[4], a12 = a[5],
2333        a20 = a[6], a21 = a[7], a22 = a[8],
2334        x = v[0], y = v[1];
2335
2336    out[0] = a00;
2337    out[1] = a01;
2338    out[2] = a02;
2339
2340    out[3] = a10;
2341    out[4] = a11;
2342    out[5] = a12;
2343
2344    out[6] = x * a00 + y * a10 + a20;
2345    out[7] = x * a01 + y * a11 + a21;
2346    out[8] = x * a02 + y * a12 + a22;
2347    return out;
2348};
2349
2350/**
2351 * Rotates a mat3 by the given angle
2352 *
2353 * @param {mat3} out the receiving matrix
2354 * @param {mat3} a the matrix to rotate
2355 * @param {Number} rad the angle to rotate the matrix by
2356 * @returns {mat3} out
2357 */
2358mat3.rotate = function (out, a, rad) {
2359    var a00 = a[0], a01 = a[1], a02 = a[2],
2360        a10 = a[3], a11 = a[4], a12 = a[5],
2361        a20 = a[6], a21 = a[7], a22 = a[8],
2362
2363        s = Math.sin(rad),
2364        c = Math.cos(rad);
2365
2366    out[0] = c * a00 + s * a10;
2367    out[1] = c * a01 + s * a11;
2368    out[2] = c * a02 + s * a12;
2369
2370    out[3] = c * a10 - s * a00;
2371    out[4] = c * a11 - s * a01;
2372    out[5] = c * a12 - s * a02;
2373
2374    out[6] = a20;
2375    out[7] = a21;
2376    out[8] = a22;
2377    return out;
2378};
2379
2380/**
2381 * Scales the mat3 by the dimensions in the given vec2
2382 *
2383 * @param {mat3} out the receiving matrix
2384 * @param {mat3} a the matrix to rotate
2385 * @param {vec2} v the vec2 to scale the matrix by
2386 * @returns {mat3} out
2387 **/
2388mat3.scale = function(out, a, v) {
2389    var x = v[0], y = v[2];
2390
2391    out[0] = x * a[0];
2392    out[1] = x * a[1];
2393    out[2] = x * a[2];
2394
2395    out[3] = y * a[3];
2396    out[4] = y * a[4];
2397    out[5] = y * a[5];
2398
2399    out[6] = a[6];
2400    out[7] = a[7];
2401    out[8] = a[8];
2402    return out;
2403};
2404
2405/**
2406 * Copies the values from a mat2d into a mat3
2407 *
2408 * @param {mat3} out the receiving matrix
2409 * @param {mat3} a the matrix to rotate
2410 * @param {vec2} v the vec2 to scale the matrix by
2411 * @returns {mat3} out
2412 **/
2413mat3.fromMat2d = function(out, a) {
2414    out[0] = a[0];
2415    out[1] = a[1];
2416    out[2] = 0;
2417
2418    out[3] = a[2];
2419    out[4] = a[3];
2420    out[5] = 0;
2421
2422    out[6] = a[4];
2423    out[7] = a[5];
2424    out[8] = 1;
2425    return out;
2426};
2427
2428/**
2429* Calculates a 3x3 matrix from the given quaternion
2430*
2431* @param {mat3} out mat3 receiving operation result
2432* @param {quat} q Quaternion to create matrix from
2433*
2434* @returns {mat3} out
2435*/
2436mat3.fromQuat = function (out, q) {
2437    var x = q[0], y = q[1], z = q[2], w = q[3],
2438        x2 = x + x,
2439        y2 = y + y,
2440        z2 = z + z,
2441
2442        xx = x * x2,
2443        xy = x * y2,
2444        xz = x * z2,
2445        yy = y * y2,
2446        yz = y * z2,
2447        zz = z * z2,
2448        wx = w * x2,
2449        wy = w * y2,
2450        wz = w * z2;
2451
2452    out[0] = 1 - (yy + zz);
2453    out[1] = xy + wz;
2454    out[2] = xz - wy;
2455
2456    out[3] = xy - wz;
2457    out[4] = 1 - (xx + zz);
2458    out[5] = yz + wx;
2459
2460    out[6] = xz + wy;
2461    out[7] = yz - wx;
2462    out[8] = 1 - (xx + yy);
2463
2464    return out;
2465};
2466
2467/**
2468 * Returns a string representation of a mat3
2469 *
2470 * @param {mat3} mat matrix to represent as a string
2471 * @returns {String} string representation of the matrix
2472 */
2473mat3.str = function (a) {
2474    return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
2475                    a[3] + ', ' + a[4] + ', ' + a[5] + ', ' +
2476                    a[6] + ', ' + a[7] + ', ' + a[8] + ')';
2477};
2478
2479if(typeof(exports) !== 'undefined') {
2480    exports.mat3 = mat3;
2481}
2482;
2483/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
2484
2485Redistribution and use in source and binary forms, with or without modification,
2486are permitted provided that the following conditions are met:
2487
2488  * Redistributions of source code must retain the above copyright notice, this
2489    list of conditions and the following disclaimer.
2490  * Redistributions in binary form must reproduce the above copyright notice,
2491    this list of conditions and the following disclaimer in the documentation
2492    and/or other materials provided with the distribution.
2493
2494THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2495ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2496WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2497DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
2498ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2499(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2500LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2501ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2502(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2503SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
2504
2505/**
2506 * @class 4x4 Matrix
2507 * @name mat4
2508 */
2509
2510var mat4 = {};
2511
2512/**
2513 * Creates a new identity mat4
2514 *
2515 * @returns {mat4} a new 4x4 matrix
2516 */
2517mat4.create = function() {
2518    var out = new GLMAT_ARRAY_TYPE(16);
2519    out[0] = 1;
2520    out[1] = 0;
2521    out[2] = 0;
2522    out[3] = 0;
2523    out[4] = 0;
2524    out[5] = 1;
2525    out[6] = 0;
2526    out[7] = 0;
2527    out[8] = 0;
2528    out[9] = 0;
2529    out[10] = 1;
2530    out[11] = 0;
2531    out[12] = 0;
2532    out[13] = 0;
2533    out[14] = 0;
2534    out[15] = 1;
2535    return out;
2536};
2537
2538/**
2539 * Creates a new mat4 initialized with values from an existing matrix
2540 *
2541 * @param {mat4} a matrix to clone
2542 * @returns {mat4} a new 4x4 matrix
2543 */
2544mat4.clone = function(a) {
2545    var out = new GLMAT_ARRAY_TYPE(16);
2546    out[0] = a[0];
2547    out[1] = a[1];
2548    out[2] = a[2];
2549    out[3] = a[3];
2550    out[4] = a[4];
2551    out[5] = a[5];
2552    out[6] = a[6];
2553    out[7] = a[7];
2554    out[8] = a[8];
2555    out[9] = a[9];
2556    out[10] = a[10];
2557    out[11] = a[11];
2558    out[12] = a[12];
2559    out[13] = a[13];
2560    out[14] = a[14];
2561    out[15] = a[15];
2562    return out;
2563};
2564
2565/**
2566 * Copy the values from one mat4 to another
2567 *
2568 * @param {mat4} out the receiving matrix
2569 * @param {mat4} a the source matrix
2570 * @returns {mat4} out
2571 */
2572mat4.copy = function(out, a) {
2573    out[0] = a[0];
2574    out[1] = a[1];
2575    out[2] = a[2];
2576    out[3] = a[3];
2577    out[4] = a[4];
2578    out[5] = a[5];
2579    out[6] = a[6];
2580    out[7] = a[7];
2581    out[8] = a[8];
2582    out[9] = a[9];
2583    out[10] = a[10];
2584    out[11] = a[11];
2585    out[12] = a[12];
2586    out[13] = a[13];
2587    out[14] = a[14];
2588    out[15] = a[15];
2589    return out;
2590};
2591
2592/**
2593 * Set a mat4 to the identity matrix
2594 *
2595 * @param {mat4} out the receiving matrix
2596 * @returns {mat4} out
2597 */
2598mat4.identity = function(out) {
2599    out[0] = 1;
2600    out[1] = 0;
2601    out[2] = 0;
2602    out[3] = 0;
2603    out[4] = 0;
2604    out[5] = 1;
2605    out[6] = 0;
2606    out[7] = 0;
2607    out[8] = 0;
2608    out[9] = 0;
2609    out[10] = 1;
2610    out[11] = 0;
2611    out[12] = 0;
2612    out[13] = 0;
2613    out[14] = 0;
2614    out[15] = 1;
2615    return out;
2616};
2617
2618/**
2619 * Transpose the values of a mat4
2620 *
2621 * @param {mat4} out the receiving matrix
2622 * @param {mat4} a the source matrix
2623 * @returns {mat4} out
2624 */
2625mat4.transpose = function(out, a) {
2626    // If we are transposing ourselves we can skip a few steps but have to cache some values
2627    if (out === a) {
2628        var a01 = a[1], a02 = a[2], a03 = a[3],
2629            a12 = a[6], a13 = a[7],
2630            a23 = a[11];
2631
2632        out[1] = a[4];
2633        out[2] = a[8];
2634        out[3] = a[12];
2635        out[4] = a01;
2636        out[6] = a[9];
2637        out[7] = a[13];
2638        out[8] = a02;
2639        out[9] = a12;
2640        out[11] = a[14];
2641        out[12] = a03;
2642        out[13] = a13;
2643        out[14] = a23;
2644    } else {
2645        out[0] = a[0];
2646        out[1] = a[4];
2647        out[2] = a[8];
2648        out[3] = a[12];
2649        out[4] = a[1];
2650        out[5] = a[5];
2651        out[6] = a[9];
2652        out[7] = a[13];
2653        out[8] = a[2];
2654        out[9] = a[6];
2655        out[10] = a[10];
2656        out[11] = a[14];
2657        out[12] = a[3];
2658        out[13] = a[7];
2659        out[14] = a[11];
2660        out[15] = a[15];
2661    }
2662
2663    return out;
2664};
2665
2666/**
2667 * Inverts a mat4
2668 *
2669 * @param {mat4} out the receiving matrix
2670 * @param {mat4} a the source matrix
2671 * @returns {mat4} out
2672 */
2673mat4.invert = function(out, a) {
2674    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
2675        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
2676        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
2677        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
2678
2679        b00 = a00 * a11 - a01 * a10,
2680        b01 = a00 * a12 - a02 * a10,
2681        b02 = a00 * a13 - a03 * a10,
2682        b03 = a01 * a12 - a02 * a11,
2683        b04 = a01 * a13 - a03 * a11,
2684        b05 = a02 * a13 - a03 * a12,
2685        b06 = a20 * a31 - a21 * a30,
2686        b07 = a20 * a32 - a22 * a30,
2687        b08 = a20 * a33 - a23 * a30,
2688        b09 = a21 * a32 - a22 * a31,
2689        b10 = a21 * a33 - a23 * a31,
2690        b11 = a22 * a33 - a23 * a32,
2691
2692        // Calculate the determinant
2693        det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
2694
2695    if (!det) {
2696        return null;
2697    }
2698    det = 1.0 / det;
2699
2700    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
2701    out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
2702    out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
2703    out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
2704    out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
2705    out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
2706    out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
2707    out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
2708    out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
2709    out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
2710    out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
2711    out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
2712    out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
2713    out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
2714    out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
2715    out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
2716
2717    return out;
2718};
2719
2720/**
2721 * Calculates the adjugate of a mat4
2722 *
2723 * @param {mat4} out the receiving matrix
2724 * @param {mat4} a the source matrix
2725 * @returns {mat4} out
2726 */
2727mat4.adjoint = function(out, a) {
2728    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
2729        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
2730        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
2731        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
2732
2733    out[0]  =  (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
2734    out[1]  = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
2735    out[2]  =  (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
2736    out[3]  = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
2737    out[4]  = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
2738    out[5]  =  (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
2739    out[6]  = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
2740    out[7]  =  (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
2741    out[8]  =  (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
2742    out[9]  = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
2743    out[10] =  (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
2744    out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
2745    out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
2746    out[13] =  (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
2747    out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
2748    out[15] =  (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
2749    return out;
2750};
2751
2752/**
2753 * Calculates the determinant of a mat4
2754 *
2755 * @param {mat4} a the source matrix
2756 * @returns {Number} determinant of a
2757 */
2758mat4.determinant = function (a) {
2759    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
2760        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
2761        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
2762        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
2763
2764        b00 = a00 * a11 - a01 * a10,
2765        b01 = a00 * a12 - a02 * a10,
2766        b02 = a00 * a13 - a03 * a10,
2767        b03 = a01 * a12 - a02 * a11,
2768        b04 = a01 * a13 - a03 * a11,
2769        b05 = a02 * a13 - a03 * a12,
2770        b06 = a20 * a31 - a21 * a30,
2771        b07 = a20 * a32 - a22 * a30,
2772        b08 = a20 * a33 - a23 * a30,
2773        b09 = a21 * a32 - a22 * a31,
2774        b10 = a21 * a33 - a23 * a31,
2775        b11 = a22 * a33 - a23 * a32;
2776
2777    // Calculate the determinant
2778    return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
2779};
2780
2781/**
2782 * Multiplies two mat4's
2783 *
2784 * @param {mat4} out the receiving matrix
2785 * @param {mat4} a the first operand
2786 * @param {mat4} b the second operand
2787 * @returns {mat4} out
2788 */
2789mat4.multiply = function (out, a, b) {
2790    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
2791        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
2792        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
2793        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
2794
2795    // Cache only the current line of the second matrix
2796    var b0  = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
2797    out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
2798    out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
2799    out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
2800    out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
2801
2802    b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
2803    out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
2804    out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
2805    out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
2806    out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
2807
2808    b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
2809    out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
2810    out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
2811    out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
2812    out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
2813
2814    b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
2815    out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
2816    out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
2817    out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
2818    out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
2819    return out;
2820};
2821
2822/**
2823 * Alias for {@link mat4.multiply}
2824 * @function
2825 */
2826mat4.mul = mat4.multiply;
2827
2828/**
2829 * Translate a mat4 by the given vector
2830 *
2831 * @param {mat4} out the receiving matrix
2832 * @param {mat4} a the matrix to translate
2833 * @param {vec3} v vector to translate by
2834 * @returns {mat4} out
2835 */
2836mat4.translate = function (out, a, v) {
2837    var x = v[0], y = v[1], z = v[2],
2838        a00, a01, a02, a03,
2839        a10, a11, a12, a13,
2840        a20, a21, a22, a23;
2841
2842    if (a === out) {
2843        out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
2844        out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
2845        out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
2846        out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
2847    } else {
2848        a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
2849        a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
2850        a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
2851
2852        out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
2853        out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
2854        out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
2855
2856        out[12] = a00 * x + a10 * y + a20 * z + a[12];
2857        out[13] = a01 * x + a11 * y + a21 * z + a[13];
2858        out[14] = a02 * x + a12 * y + a22 * z + a[14];
2859        out[15] = a03 * x + a13 * y + a23 * z + a[15];
2860    }
2861
2862    return out;
2863};
2864
2865/**
2866 * Scales the mat4 by the dimensions in the given vec3
2867 *
2868 * @param {mat4} out the receiving matrix
2869 * @param {mat4} a the matrix to scale
2870 * @param {vec3} v the vec3 to scale the matrix by
2871 * @returns {mat4} out
2872 **/
2873mat4.scale = function(out, a, v) {
2874    var x = v[0], y = v[1], z = v[2];
2875
2876    out[0] = a[0] * x;
2877    out[1] = a[1] * x;
2878    out[2] = a[2] * x;
2879    out[3] = a[3] * x;
2880    out[4] = a[4] * y;
2881    out[5] = a[5] * y;
2882    out[6] = a[6] * y;
2883    out[7] = a[7] * y;
2884    out[8] = a[8] * z;
2885    out[9] = a[9] * z;
2886    out[10] = a[10] * z;
2887    out[11] = a[11] * z;
2888    out[12] = a[12];
2889    out[13] = a[13];
2890    out[14] = a[14];
2891    out[15] = a[15];
2892    return out;
2893};
2894
2895/**
2896 * Rotates a mat4 by the given angle
2897 *
2898 * @param {mat4} out the receiving matrix
2899 * @param {mat4} a the matrix to rotate
2900 * @param {Number} rad the angle to rotate the matrix by
2901 * @param {vec3} axis the axis to rotate around
2902 * @returns {mat4} out
2903 */
2904mat4.rotate = function (out, a, rad, axis) {
2905    var x = axis[0], y = axis[1], z = axis[2],
2906        len = Math.sqrt(x * x + y * y + z * z),
2907        s, c, t,
2908        a00, a01, a02, a03,
2909        a10, a11, a12, a13,
2910        a20, a21, a22, a23,
2911        b00, b01, b02,
2912        b10, b11, b12,
2913        b20, b21, b22;
2914
2915    if (Math.abs(len) < GLMAT_EPSILON) { return null; }
2916
2917    len = 1 / len;
2918    x *= len;
2919    y *= len;
2920    z *= len;
2921
2922    s = Math.sin(rad);
2923    c = Math.cos(rad);
2924    t = 1 - c;
2925
2926    a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
2927    a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
2928    a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
2929
2930    // Construct the elements of the rotation matrix
2931    b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
2932    b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
2933    b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
2934
2935    // Perform rotation-specific matrix multiplication
2936    out[0] = a00 * b00 + a10 * b01 + a20 * b02;
2937    out[1] = a01 * b00 + a11 * b01 + a21 * b02;
2938    out[2] = a02 * b00 + a12 * b01 + a22 * b02;
2939    out[3] = a03 * b00 + a13 * b01 + a23 * b02;
2940    out[4] = a00 * b10 + a10 * b11 + a20 * b12;
2941    out[5] = a01 * b10 + a11 * b11 + a21 * b12;
2942    out[6] = a02 * b10 + a12 * b11 + a22 * b12;
2943    out[7] = a03 * b10 + a13 * b11 + a23 * b12;
2944    out[8] = a00 * b20 + a10 * b21 + a20 * b22;
2945    out[9] = a01 * b20 + a11 * b21 + a21 * b22;
2946    out[10] = a02 * b20 + a12 * b21 + a22 * b22;
2947    out[11] = a03 * b20 + a13 * b21 + a23 * b22;
2948
2949    if (a !== out) { // If the source and destination differ, copy the unchanged last row
2950        out[12] = a[12];
2951        out[13] = a[13];
2952        out[14] = a[14];
2953        out[15] = a[15];
2954    }
2955    return out;
2956};
2957
2958/**
2959 * Rotates a matrix by the given angle around the X axis
2960 *
2961 * @param {mat4} out the receiving matrix
2962 * @param {mat4} a the matrix to rotate
2963 * @param {Number} rad the angle to rotate the matrix by
2964 * @returns {mat4} out
2965 */
2966mat4.rotateX = function (out, a, rad) {
2967    var s = Math.sin(rad),
2968        c = Math.cos(rad),
2969        a10 = a[4],
2970        a11 = a[5],
2971        a12 = a[6],
2972        a13 = a[7],
2973        a20 = a[8],
2974        a21 = a[9],
2975        a22 = a[10],
2976        a23 = a[11];
2977
2978    if (a !== out) { // If the source and destination differ, copy the unchanged rows
2979        out[0]  = a[0];
2980        out[1]  = a[1];
2981        out[2]  = a[2];
2982        out[3]  = a[3];
2983        out[12] = a[12];
2984        out[13] = a[13];
2985        out[14] = a[14];
2986        out[15] = a[15];
2987    }
2988
2989    // Perform axis-specific matrix multiplication
2990    out[4] = a10 * c + a20 * s;
2991    out[5] = a11 * c + a21 * s;
2992    out[6] = a12 * c + a22 * s;
2993    out[7] = a13 * c + a23 * s;
2994    out[8] = a20 * c - a10 * s;
2995    out[9] = a21 * c - a11 * s;
2996    out[10] = a22 * c - a12 * s;
2997    out[11] = a23 * c - a13 * s;
2998    return out;
2999};
3000
3001/**
3002 * Rotates a matrix by the given angle around the Y axis
3003 *
3004 * @param {mat4} out the receiving matrix
3005 * @param {mat4} a the matrix to rotate
3006 * @param {Number} rad the angle to rotate the matrix by
3007 * @returns {mat4} out
3008 */
3009mat4.rotateY = function (out, a, rad) {
3010    var s = Math.sin(rad),
3011        c = Math.cos(rad),
3012        a00 = a[0],
3013        a01 = a[1],
3014        a02 = a[2],
3015        a03 = a[3],
3016        a20 = a[8],
3017        a21 = a[9],
3018        a22 = a[10],
3019        a23 = a[11];
3020
3021    if (a !== out) { // If the source and destination differ, copy the unchanged rows
3022        out[4]  = a[4];
3023        out[5]  = a[5];
3024        out[6]  = a[6];
3025        out[7]  = a[7];
3026        out[12] = a[12];
3027        out[13] = a[13];
3028        out[14] = a[14];
3029        out[15] = a[15];
3030    }
3031
3032    // Perform axis-specific matrix multiplication
3033    out[0] = a00 * c - a20 * s;
3034    out[1] = a01 * c - a21 * s;
3035    out[2] = a02 * c - a22 * s;
3036    out[3] = a03 * c - a23 * s;
3037    out[8] = a00 * s + a20 * c;
3038    out[9] = a01 * s + a21 * c;
3039    out[10] = a02 * s + a22 * c;
3040    out[11] = a03 * s + a23 * c;
3041    return out;
3042};
3043
3044/**
3045 * Rotates a matrix by the given angle around the Z axis
3046 *
3047 * @param {mat4} out the receiving matrix
3048 * @param {mat4} a the matrix to rotate
3049 * @param {Number} rad the angle to rotate the matrix by
3050 * @returns {mat4} out
3051 */
3052mat4.rotateZ = function (out, a, rad) {
3053    var s = Math.sin(rad),
3054        c = Math.cos(rad),
3055        a00 = a[0],
3056        a01 = a[1],
3057        a02 = a[2],
3058        a03 = a[3],
3059        a10 = a[4],
3060        a11 = a[5],
3061        a12 = a[6],
3062        a13 = a[7];
3063
3064    if (a !== out) { // If the source and destination differ, copy the unchanged last row
3065        out[8]  = a[8];
3066        out[9]  = a[9];
3067        out[10] = a[10];
3068        out[11] = a[11];
3069        out[12] = a[12];
3070        out[13] = a[13];
3071        out[14] = a[14];
3072        out[15] = a[15];
3073    }
3074
3075    // Perform axis-specific matrix multiplication
3076    out[0] = a00 * c + a10 * s;
3077    out[1] = a01 * c + a11 * s;
3078    out[2] = a02 * c + a12 * s;
3079    out[3] = a03 * c + a13 * s;
3080    out[4] = a10 * c - a00 * s;
3081    out[5] = a11 * c - a01 * s;
3082    out[6] = a12 * c - a02 * s;
3083    out[7] = a13 * c - a03 * s;
3084    return out;
3085};
3086
3087/**
3088 * Creates a matrix from a quaternion rotation and vector translation
3089 * This is equivalent to (but much faster than):
3090 *
3091 *     mat4.identity(dest);
3092 *     mat4.translate(dest, vec);
3093 *     var quatMat = mat4.create();
3094 *     quat4.toMat4(quat, quatMat);
3095 *     mat4.multiply(dest, quatMat);
3096 *
3097 * @param {mat4} out mat4 receiving operation result
3098 * @param {quat4} q Rotation quaternion
3099 * @param {vec3} v Translation vector
3100 * @returns {mat4} out
3101 */
3102mat4.fromRotationTranslation = function (out, q, v) {
3103    // Quaternion math
3104    var x = q[0], y = q[1], z = q[2], w = q[3],
3105        x2 = x + x,
3106        y2 = y + y,
3107        z2 = z + z,
3108
3109        xx = x * x2,
3110        xy = x * y2,
3111        xz = x * z2,
3112        yy = y * y2,
3113        yz = y * z2,
3114        zz = z * z2,
3115        wx = w * x2,
3116        wy = w * y2,
3117        wz = w * z2;
3118
3119    out[0] = 1 - (yy + zz);
3120    out[1] = xy + wz;
3121    out[2] = xz - wy;
3122    out[3] = 0;
3123    out[4] = xy - wz;
3124    out[5] = 1 - (xx + zz);
3125    out[6] = yz + wx;
3126    out[7] = 0;
3127    out[8] = xz + wy;
3128    out[9] = yz - wx;
3129    out[10] = 1 - (xx + yy);
3130    out[11] = 0;
3131    out[12] = v[0];
3132    out[13] = v[1];
3133    out[14] = v[2];
3134    out[15] = 1;
3135
3136    return out;
3137};
3138
3139/**
3140* Calculates a 4x4 matrix from the given quaternion
3141*
3142* @param {mat4} out mat4 receiving operation result
3143* @param {quat} q Quaternion to create matrix from
3144*
3145* @returns {mat4} out
3146*/
3147mat4.fromQuat = function (out, q) {
3148    var x = q[0], y = q[1], z = q[2], w = q[3],
3149        x2 = x + x,
3150        y2 = y + y,
3151        z2 = z + z,
3152
3153        xx = x * x2,
3154        xy = x * y2,
3155        xz = x * z2,
3156        yy = y * y2,
3157        yz = y * z2,
3158        zz = z * z2,
3159        wx = w * x2,
3160        wy = w * y2,
3161        wz = w * z2;
3162
3163    out[0] = 1 - (yy + zz);
3164    out[1] = xy + wz;
3165    out[2] = xz - wy;
3166    out[3] = 0;
3167
3168    out[4] = xy - wz;
3169    out[5] = 1 - (xx + zz);
3170    out[6] = yz + wx;
3171    out[7] = 0;
3172
3173    out[8] = xz + wy;
3174    out[9] = yz - wx;
3175    out[10] = 1 - (xx + yy);
3176    out[11] = 0;
3177
3178    out[12] = 0;
3179    out[13] = 0;
3180    out[14] = 0;
3181    out[15] = 1;
3182
3183    return out;
3184};
3185
3186/**
3187 * Generates a frustum matrix with the given bounds
3188 *
3189 * @param {mat4} out mat4 frustum matrix will be written into
3190 * @param {Number} left Left bound of the frustum
3191 * @param {Number} right Right bound of the frustum
3192 * @param {Number} bottom Bottom bound of the frustum
3193 * @param {Number} top Top bound of the frustum
3194 * @param {Number} near Near bound of the frustum
3195 * @param {Number} far Far bound of the frustum
3196 * @returns {mat4} out
3197 */
3198mat4.frustum = function (out, left, right, bottom, top, near, far) {
3199    var rl = 1 / (right - left),
3200        tb = 1 / (top - bottom),
3201        nf = 1 / (near - far);
3202    out[0] = (near * 2) * rl;
3203    out[1] = 0;
3204    out[2] = 0;
3205    out[3] = 0;
3206    out[4] = 0;
3207    out[5] = (near * 2) * tb;
3208    out[6] = 0;
3209    out[7] = 0;
3210    out[8] = (right + left) * rl;
3211    out[9] = (top + bottom) * tb;
3212    out[10] = (far + near) * nf;
3213    out[11] = -1;
3214    out[12] = 0;
3215    out[13] = 0;
3216    out[14] = (far * near * 2) * nf;
3217    out[15] = 0;
3218    return out;
3219};
3220
3221/**
3222 * Generates a perspective projection matrix with the given bounds
3223 *
3224 * @param {mat4} out mat4 frustum matrix will be written into
3225 * @param {number} fovy Vertical field of view in radians
3226 * @param {number} aspect Aspect ratio. typically viewport width/height
3227 * @param {number} near Near bound of the frustum
3228 * @param {number} far Far bound of the frustum
3229 * @returns {mat4} out
3230 */
3231mat4.perspective = function (out, fovy, aspect, near, far) {
3232    var f = 1.0 / Math.tan(fovy / 2),
3233        nf = 1 / (near - far);
3234    out[0] = f / aspect;
3235    out[1] = 0;
3236    out[2] = 0;
3237    out[3] = 0;
3238    out[4] = 0;
3239    out[5] = f;
3240    out[6] = 0;
3241    out[7] = 0;
3242    out[8] = 0;
3243    out[9] = 0;
3244    out[10] = (far + near) * nf;
3245    out[11] = -1;
3246    out[12] = 0;
3247    out[13] = 0;
3248    out[14] = (2 * far * near) * nf;
3249    out[15] = 0;
3250    return out;
3251};
3252
3253/**
3254 * Generates a orthogonal projection matrix with the given bounds
3255 *
3256 * @param {mat4} out mat4 frustum matrix will be written into
3257 * @param {number} left Left bound of the frustum
3258 * @param {number} right Right bound of the frustum
3259 * @param {number} bottom Bottom bound of the frustum
3260 * @param {number} top Top bound of the frustum
3261 * @param {number} near Near bound of the frustum
3262 * @param {number} far Far bound of the frustum
3263 * @returns {mat4} out
3264 */
3265mat4.ortho = function (out, left, right, bottom, top, near, far) {
3266    var lr = 1 / (left - right),
3267        bt = 1 / (bottom - top),
3268        nf = 1 / (near - far);
3269    out[0] = -2 * lr;
3270    out[1] = 0;
3271    out[2] = 0;
3272    out[3] = 0;
3273    out[4] = 0;
3274    out[5] = -2 * bt;
3275    out[6] = 0;
3276    out[7] = 0;
3277    out[8] = 0;
3278    out[9] = 0;
3279    out[10] = 2 * nf;
3280    out[11] = 0;
3281    out[12] = (left + right) * lr;
3282    out[13] = (top + bottom) * bt;
3283    out[14] = (far + near) * nf;
3284    out[15] = 1;
3285    return out;
3286};
3287
3288/**
3289 * Generates a look-at matrix with the given eye position, focal point, and up axis
3290 *
3291 * @param {mat4} out mat4 frustum matrix will be written into
3292 * @param {vec3} eye Position of the viewer
3293 * @param {vec3} center Point the viewer is looking at
3294 * @param {vec3} up vec3 pointing up
3295 * @returns {mat4} out
3296 */
3297mat4.lookAt = function (out, eye, center, up) {
3298    var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
3299        eyex = eye[0],
3300        eyey = eye[1],
3301        eyez = eye[2],
3302        upx = up[0],
3303        upy = up[1],
3304        upz = up[2],
3305        centerx = center[0],
3306        centery = center[1],
3307        centerz = center[2];
3308
3309    if (Math.abs(eyex - centerx) < GLMAT_EPSILON &&
3310        Math.abs(eyey - centery) < GLMAT_EPSILON &&
3311        Math.abs(eyez - centerz) < GLMAT_EPSILON) {
3312        return mat4.identity(out);
3313    }
3314
3315    z0 = eyex - centerx;
3316    z1 = eyey - centery;
3317    z2 = eyez - centerz;
3318
3319    len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
3320    z0 *= len;
3321    z1 *= len;
3322    z2 *= len;
3323
3324    x0 = upy * z2 - upz * z1;
3325    x1 = upz * z0 - upx * z2;
3326    x2 = upx * z1 - upy * z0;
3327    len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
3328    if (!len) {
3329        x0 = 0;
3330        x1 = 0;
3331        x2 = 0;
3332    } else {
3333        len = 1 / len;
3334        x0 *= len;
3335        x1 *= len;
3336        x2 *= len;
3337    }
3338
3339    y0 = z1 * x2 - z2 * x1;
3340    y1 = z2 * x0 - z0 * x2;
3341    y2 = z0 * x1 - z1 * x0;
3342
3343    len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
3344    if (!len) {
3345        y0 = 0;
3346        y1 = 0;
3347        y2 = 0;
3348    } else {
3349        len = 1 / len;
3350        y0 *= len;
3351        y1 *= len;
3352        y2 *= len;
3353    }
3354
3355    out[0] = x0;
3356    out[1] = y0;
3357    out[2] = z0;
3358    out[3] = 0;
3359    out[4] = x1;
3360    out[5] = y1;
3361    out[6] = z1;
3362    out[7] = 0;
3363    out[8] = x2;
3364    out[9] = y2;
3365    out[10] = z2;
3366    out[11] = 0;
3367    out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
3368    out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
3369    out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
3370    out[15] = 1;
3371
3372    return out;
3373};
3374
3375/**
3376 * Returns a string representation of a mat4
3377 *
3378 * @param {mat4} mat matrix to represent as a string
3379 * @returns {String} string representation of the matrix
3380 */
3381mat4.str = function (a) {
3382    return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
3383                    a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
3384                    a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' +
3385                    a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
3386};
3387
3388if(typeof(exports) !== 'undefined') {
3389    exports.mat4 = mat4;
3390}
3391;
3392/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
3393
3394Redistribution and use in source and binary forms, with or without modification,
3395are permitted provided that the following conditions are met:
3396
3397  * Redistributions of source code must retain the above copyright notice, this
3398    list of conditions and the following disclaimer.
3399  * Redistributions in binary form must reproduce the above copyright notice,
3400    this list of conditions and the following disclaimer in the documentation
3401    and/or other materials provided with the distribution.
3402
3403THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3404ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3405WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3406DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
3407ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3408(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3409LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3410ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3411(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3412SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
3413
3414/**
3415 * @class Quaternion
3416 * @name quat
3417 */
3418
3419var quat = {};
3420
3421/**
3422 * Creates a new identity quat
3423 *
3424 * @returns {quat} a new quaternion
3425 */
3426quat.create = function() {
3427    var out = new GLMAT_ARRAY_TYPE(4);
3428    out[0] = 0;
3429    out[1] = 0;
3430    out[2] = 0;
3431    out[3] = 1;
3432    return out;
3433};
3434
3435/**
3436 * Creates a new quat initialized with values from an existing quaternion
3437 *
3438 * @param {quat} a quaternion to clone
3439 * @returns {quat} a new quaternion
3440 * @function
3441 */
3442quat.clone = vec4.clone;
3443
3444/**
3445 * Creates a new quat initialized with the given values
3446 *
3447 * @param {Number} x X component
3448 * @param {Number} y Y component
3449 * @param {Number} z Z component
3450 * @param {Number} w W component
3451 * @returns {quat} a new quaternion
3452 * @function
3453 */
3454quat.fromValues = vec4.fromValues;
3455
3456/**
3457 * Copy the values from one quat to another
3458 *
3459 * @param {quat} out the receiving quaternion
3460 * @param {quat} a the source quaternion
3461 * @returns {quat} out
3462 * @function
3463 */
3464quat.copy = vec4.copy;
3465
3466/**
3467 * Set the components of a quat to the given values
3468 *
3469 * @param {quat} out the receiving quaternion
3470 * @param {Number} x X component
3471 * @param {Number} y Y component
3472 * @param {Number} z Z component
3473 * @param {Number} w W component
3474 * @returns {quat} out
3475 * @function
3476 */
3477quat.set = vec4.set;
3478
3479/**
3480 * Set a quat to the identity quaternion
3481 *
3482 * @param {quat} out the receiving quaternion
3483 * @returns {quat} out
3484 */
3485quat.identity = function(out) {
3486    out[0] = 0;
3487    out[1] = 0;
3488    out[2] = 0;
3489    out[3] = 1;
3490    return out;
3491};
3492
3493/**
3494 * Sets a quat from the given angle and rotation axis,
3495 * then returns it.
3496 *
3497 * @param {quat} out the receiving quaternion
3498 * @param {vec3} axis the axis around which to rotate
3499 * @param {Number} rad the angle in radians
3500 * @returns {quat} out
3501 **/
3502quat.setAxisAngle = function(out, axis, rad) {
3503    rad = rad * 0.5;
3504    var s = Math.sin(rad);
3505    out[0] = s * axis[0];
3506    out[1] = s * axis[1];
3507    out[2] = s * axis[2];
3508    out[3] = Math.cos(rad);
3509    return out;
3510};
3511
3512/**
3513 * Adds two quat's
3514 *
3515 * @param {quat} out the receiving quaternion
3516 * @param {quat} a the first operand
3517 * @param {quat} b the second operand
3518 * @returns {quat} out
3519 * @function
3520 */
3521quat.add = vec4.add;
3522
3523/**
3524 * Multiplies two quat's
3525 *
3526 * @param {quat} out the receiving quaternion
3527 * @param {quat} a the first operand
3528 * @param {quat} b the second operand
3529 * @returns {quat} out
3530 */
3531quat.multiply = function(out, a, b) {
3532    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
3533        bx = b[0], by = b[1], bz = b[2], bw = b[3];
3534
3535    out[0] = ax * bw + aw * bx + ay * bz - az * by;
3536    out[1] = ay * bw + aw * by + az * bx - ax * bz;
3537    out[2] = az * bw + aw * bz + ax * by - ay * bx;
3538    out[3] = aw * bw - ax * bx - ay * by - az * bz;
3539    return out;
3540};
3541
3542/**
3543 * Alias for {@link quat.multiply}
3544 * @function
3545 */
3546quat.mul = quat.multiply;
3547
3548/**
3549 * Scales a quat by a scalar number
3550 *
3551 * @param {quat} out the receiving vector
3552 * @param {quat} a the vector to scale
3553 * @param {Number} b amount to scale the vector by
3554 * @returns {quat} out
3555 * @function
3556 */
3557quat.scale = vec4.scale;
3558
3559/**
3560 * Rotates a quaternion by the given angle around the X axis
3561 *
3562 * @param {quat} out quat receiving operation result
3563 * @param {quat} a quat to rotate
3564 * @param {number} rad angle (in radians) to rotate
3565 * @returns {quat} out
3566 */
3567quat.rotateX = function (out, a, rad) {
3568    rad *= 0.5;
3569
3570    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
3571        bx = Math.sin(rad), bw = Math.cos(rad);
3572
3573    out[0] = ax * bw + aw * bx;
3574    out[1] = ay * bw + az * bx;
3575    out[2] = az * bw - ay * bx;
3576    out[3] = aw * bw - ax * bx;
3577    return out;
3578};
3579
3580/**
3581 * Rotates a quaternion by the given angle around the Y axis
3582 *
3583 * @param {quat} out quat receiving operation result
3584 * @param {quat} a quat to rotate
3585 * @param {number} rad angle (in radians) to rotate
3586 * @returns {quat} out
3587 */
3588quat.rotateY = function (out, a, rad) {
3589    rad *= 0.5;
3590
3591    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
3592        by = Math.sin(rad), bw = Math.cos(rad);
3593
3594    out[0] = ax * bw - az * by;
3595    out[1] = ay * bw + aw * by;
3596    out[2] = az * bw + ax * by;
3597    out[3] = aw * bw - ay * by;
3598    return out;
3599};
3600
3601/**
3602 * Rotates a quaternion by the given angle around the Z axis
3603 *
3604 * @param {quat} out quat receiving operation result
3605 * @param {quat} a quat to rotate
3606 * @param {number} rad angle (in radians) to rotate
3607 * @returns {quat} out
3608 */
3609quat.rotateZ = function (out, a, rad) {
3610    rad *= 0.5;
3611
3612    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
3613        bz = Math.sin(rad), bw = Math.cos(rad);
3614
3615    out[0] = ax * bw + ay * bz;
3616    out[1] = ay * bw - ax * bz;
3617    out[2] = az * bw + aw * bz;
3618    out[3] = aw * bw - az * bz;
3619    return out;
3620};
3621
3622/**
3623 * Calculates the W component of a quat from the X, Y, and Z components.
3624 * Assumes that quaternion is 1 unit in length.
3625 * Any existing W component will be ignored.
3626 *
3627 * @param {quat} out the receiving quaternion
3628 * @param {quat} a quat to calculate W component of
3629 * @returns {quat} out
3630 */
3631quat.calculateW = function (out, a) {
3632    var x = a[0], y = a[1], z = a[2];
3633
3634    out[0] = x;
3635    out[1] = y;
3636    out[2] = z;
3637    out[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
3638    return out;
3639};
3640
3641/**
3642 * Calculates the dot product of two quat's
3643 *
3644 * @param {quat} a the first operand
3645 * @param {quat} b the second operand
3646 * @returns {Number} dot product of a and b
3647 * @function
3648 */
3649quat.dot = vec4.dot;
3650
3651/**
3652 * Performs a linear interpolation between two quat's
3653 *
3654 * @param {quat} out the receiving quaternion
3655 * @param {quat} a the first operand
3656 * @param {quat} b the second operand
3657 * @param {Number} t interpolation amount between the two inputs
3658 * @returns {quat} out
3659 * @function
3660 */
3661quat.lerp = vec4.lerp;
3662
3663/**
3664 * Performs a spherical linear interpolation between two quat
3665 *
3666 * @param {quat} out the receiving quaternion
3667 * @param {quat} a the first operand
3668 * @param {quat} b the second operand
3669 * @param {Number} t interpolation amount between the two inputs
3670 * @returns {quat} out
3671 */
3672quat.slerp = function (out, a, b, t) {
3673    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
3674        bx = b[0], by = b[1], bz = b[2], bw = b[3];
3675
3676    var cosHalfTheta = ax * bx + ay * by + az * bz + aw * bw,
3677        halfTheta,
3678        sinHalfTheta,
3679        ratioA,
3680        ratioB;
3681
3682    if (Math.abs(cosHalfTheta) >= 1.0) {
3683        if (out !== a) {
3684            out[0] = ax;
3685            out[1] = ay;
3686            out[2] = az;
3687            out[3] = aw;
3688        }
3689        return out;
3690    }
3691
3692    halfTheta = Math.acos(cosHalfTheta);
3693    sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta);
3694
3695    if (Math.abs(sinHalfTheta) < 0.001) {
3696        out[0] = (ax * 0.5 + bx * 0.5);
3697        out[1] = (ay * 0.5 + by * 0.5);
3698        out[2] = (az * 0.5 + bz * 0.5);
3699        out[3] = (aw * 0.5 + bw * 0.5);
3700        return out;
3701    }
3702
3703    ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta;
3704    ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
3705
3706    out[0] = (ax * ratioA + bx * ratioB);
3707    out[1] = (ay * ratioA + by * ratioB);
3708    out[2] = (az * ratioA + bz * ratioB);
3709    out[3] = (aw * ratioA + bw * ratioB);
3710
3711    return out;
3712};
3713
3714/**
3715 * Calculates the inverse of a quat
3716 *
3717 * @param {quat} out the receiving quaternion
3718 * @param {quat} a quat to calculate inverse of
3719 * @returns {quat} out
3720 */
3721quat.invert = function(out, a) {
3722    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
3723        dot = a0*a0 + a1*a1 + a2*a2 + a3*a3,
3724        invDot = dot ? 1.0/dot : 0;
3725
3726    // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
3727
3728    out[0] = -a0*invDot;
3729    out[1] = -a1*invDot;
3730    out[2] = -a2*invDot;
3731    out[3] = a3*invDot;
3732    return out;
3733};
3734
3735/**
3736 * Calculates the conjugate of a quat
3737 * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
3738 *
3739 * @param {quat} out the receiving quaternion
3740 * @param {quat} a quat to calculate conjugate of
3741 * @returns {quat} out
3742 */
3743quat.conjugate = function (out, a) {
3744    out[0] = -a[0];
3745    out[1] = -a[1];
3746    out[2] = -a[2];
3747    out[3] = a[3];
3748    return out;
3749};
3750
3751/**
3752 * Calculates the length of a quat
3753 *
3754 * @param {quat} a vector to calculate length of
3755 * @returns {Number} length of a
3756 * @function
3757 */
3758quat.length = vec4.length;
3759
3760/**
3761 * Alias for {@link quat.length}
3762 * @function
3763 */
3764quat.len = quat.length;
3765
3766/**
3767 * Calculates the squared length of a quat
3768 *
3769 * @param {quat} a vector to calculate squared length of
3770 * @returns {Number} squared length of a
3771 * @function
3772 */
3773quat.squaredLength = vec4.squaredLength;
3774
3775/**
3776 * Alias for {@link quat.squaredLength}
3777 * @function
3778 */
3779quat.sqrLen = quat.squaredLength;
3780
3781/**
3782 * Normalize a quat
3783 *
3784 * @param {quat} out the receiving quaternion
3785 * @param {quat} a quaternion to normalize
3786 * @returns {quat} out
3787 * @function
3788 */
3789quat.normalize = vec4.normalize;
3790
3791/**
3792 * Creates a quaternion from the given 3x3 rotation matrix.
3793 *
3794 * @param {quat} out the receiving quaternion
3795 * @param {mat3} m rotation matrix
3796 * @returns {quat} out
3797 * @function
3798 */
3799quat.fromMat3 = (function() {
3800    var s_iNext = [1,2,0];
3801    return function(out, m) {
3802        // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
3803        // article "Quaternion Calculus and Fast Animation".
3804        var fTrace = m[0] + m[4] + m[8];
3805        var fRoot;
3806
3807        if ( fTrace > 0.0 ) {
3808            // |w| > 1/2, may as well choose w > 1/2
3809            fRoot = Math.sqrt(fTrace + 1.0);  // 2w
3810            out[3] = 0.5 * fRoot;
3811            fRoot = 0.5/fRoot;  // 1/(4w)
3812            out[0] = (m[7]-m[5])*fRoot;
3813            out[1] = (m[2]-m[6])*fRoot;
3814            out[2] = (m[3]-m[1])*fRoot;
3815        } else {
3816            // |w| <= 1/2
3817            var i = 0;
3818            if ( m[4] > m[0] )
3819              i = 1;
3820            if ( m[8] > m[i*3+i] )
3821              i = 2;
3822            var j = s_iNext[i];
3823            var k = s_iNext[j];
3824
3825            fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0);
3826            out[i] = 0.5 * fRoot;
3827            fRoot = 0.5 / fRoot;
3828            out[3] = (m[k*3+j] - m[j*3+k]) * fRoot;
3829            out[j] = (m[j*3+i] + m[i*3+j]) * fRoot;
3830            out[k] = (m[k*3+i] + m[i*3+k]) * fRoot;
3831        }
3832
3833        return out;
3834    };
3835})();
3836
3837/**
3838 * Returns a string representation of a quatenion
3839 *
3840 * @param {quat} vec vector to represent as a string
3841 * @returns {String} string representation of the vector
3842 */
3843quat.str = function (a) {
3844    return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
3845};
3846
3847if(typeof(exports) !== 'undefined') {
3848    exports.quat = quat;
3849}
3850;
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864  })(shim.exports);
3865})();
3866