Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / third_party / gl-matrix / dist / gl-matrix.js
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
10 Redistribution and use in source and binary forms, with or without modification,
11 are 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
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 ANY 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
28 SOFTWARE, 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
54 Redistribution and use in source and binary forms, with or without modification,
55 are 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
63 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
64 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
66 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
67 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
70 ANY 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
72 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
73
74
75 if(!GLMAT_EPSILON) {
76     var GLMAT_EPSILON = 0.000001;
77 }
78
79 if(!GLMAT_ARRAY_TYPE) {
80     var GLMAT_ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
81 }
82
83 /**
84  * @class Common utilities
85  * @name glMatrix
86  */
87 var 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  */
94 glMatrix.setMatrixArrayType = function(type) {
95     GLMAT_ARRAY_TYPE = type;
96 }
97
98 if(typeof(exports) !== 'undefined') {
99     exports.glMatrix = glMatrix;
100 }
101 ;
102 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
103
104 Redistribution and use in source and binary forms, with or without modification,
105 are 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
113 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
114 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
115 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
116 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
117 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
120 ANY 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
122 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
123
124 /**
125  * @class 2 Dimensional Vector
126  * @name vec2
127  */
128
129 var vec2 = {};
130
131 /**
132  * Creates a new, empty vec2
133  *
134  * @returns {vec2} a new 2D vector
135  */
136 vec2.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  */
149 vec2.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  */
163 vec2.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  */
177 vec2.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  */
191 vec2.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  */
205 vec2.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  */
219 vec2.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  */
229 vec2.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  */
239 vec2.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  */
249 vec2.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  */
259 vec2.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  */
269 vec2.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  */
279 vec2.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  */
293 vec2.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  */
307 vec2.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  */
320 vec2.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  */
330 vec2.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  */
339 vec2.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  */
349 vec2.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  */
357 vec2.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  */
367 vec2.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  */
375 vec2.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  */
385 vec2.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  */
394 vec2.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  */
407 vec2.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  */
427 vec2.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  */
440 vec2.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  */
456 vec2.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  */
472 vec2.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  */
488 vec2.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  */
505 vec2.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  */
523 vec2.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  */
543 vec2.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  */
578 vec2.str = function (a) {
579     return 'vec2(' + a[0] + ', ' + a[1] + ')';
580 };
581
582 if(typeof(exports) !== 'undefined') {
583     exports.vec2 = vec2;
584 }
585 ;
586 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
587
588 Redistribution and use in source and binary forms, with or without modification,
589 are 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
597 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
598 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
599 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
600 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
601 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
602 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
603 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
604 ANY 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
606 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
607
608 /**
609  * @class 3 Dimensional Vector
610  * @name vec3
611  */
612
613 var vec3 = {};
614
615 /**
616  * Creates a new, empty vec3
617  *
618  * @returns {vec3} a new 3D vector
619  */
620 vec3.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  */
634 vec3.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  */
650 vec3.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  */
665 vec3.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  */
681 vec3.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  */
696 vec3.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  */
711 vec3.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  */
722 vec3.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  */
732 vec3.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  */
743 vec3.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  */
753 vec3.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  */
764 vec3.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  */
774 vec3.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  */
789 vec3.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  */
804 vec3.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  */
818 vec3.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  */
829 vec3.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  */
838 vec3.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  */
849 vec3.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  */
857 vec3.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  */
868 vec3.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  */
876 vec3.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  */
887 vec3.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  */
896 vec3.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  */
910 vec3.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  */
932 vec3.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  */
944 vec3.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  */
963 vec3.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  */
982 vec3.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  */
998 vec3.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  */
1027 vec3.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  */
1062 vec3.str = function (a) {
1063     return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
1064 };
1065
1066 if(typeof(exports) !== 'undefined') {
1067     exports.vec3 = vec3;
1068 }
1069 ;
1070 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
1071
1072 Redistribution and use in source and binary forms, with or without modification,
1073 are 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
1081 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1082 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1083 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
1084 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1085 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1086 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1087 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1088 ANY 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
1090 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
1091
1092 /**
1093  * @class 4 Dimensional Vector
1094  * @name vec4
1095  */
1096
1097 var vec4 = {};
1098
1099 /**
1100  * Creates a new, empty vec4
1101  *
1102  * @returns {vec4} a new 4D vector
1103  */
1104 vec4.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  */
1119 vec4.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  */
1137 vec4.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  */
1153 vec4.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  */
1171 vec4.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  */
1187 vec4.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  */
1203 vec4.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  */
1215 vec4.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  */
1225 vec4.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  */
1237 vec4.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  */
1247 vec4.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  */
1259 vec4.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  */
1269 vec4.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  */
1285 vec4.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  */
1301 vec4.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  */
1316 vec4.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  */
1328 vec4.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  */
1337 vec4.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  */
1349 vec4.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  */
1357 vec4.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  */
1369 vec4.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  */
1377 vec4.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  */
1389 vec4.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  */
1398 vec4.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  */
1413 vec4.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  */
1436 vec4.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  */
1449 vec4.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  */
1469 vec4.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  */
1486 vec4.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  */
1515 vec4.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  */
1550 vec4.str = function (a) {
1551     return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
1552 };
1553
1554 if(typeof(exports) !== 'undefined') {
1555     exports.vec4 = vec4;
1556 }
1557 ;
1558 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
1559
1560 Redistribution and use in source and binary forms, with or without modification,
1561 are 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
1569 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1570 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1571 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
1572 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1573 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1574 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1575 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1576 ANY 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
1578 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
1579
1580 /**
1581  * @class 2x2 Matrix
1582  * @name mat2
1583  */
1584
1585 var mat2 = {};
1586
1587 /**
1588  * Creates a new identity mat2
1589  *
1590  * @returns {mat2} a new 2x2 matrix
1591  */
1592 mat2.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  */
1607 mat2.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  */
1623 mat2.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  */
1637 mat2.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  */
1652 mat2.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  */
1675 mat2.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  */
1701 mat2.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  */
1718 mat2.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  */
1730 mat2.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  */
1744 mat2.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  */
1754 mat2.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  **/
1773 mat2.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  */
1789 mat2.str = function (a) {
1790     return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
1791 };
1792
1793 if(typeof(exports) !== 'undefined') {
1794     exports.mat2 = mat2;
1795 }
1796 ;
1797 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
1798
1799 Redistribution and use in source and binary forms, with or without modification,
1800 are 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
1808 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1809 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1810 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
1811 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1812 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1813 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1814 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1815 ANY 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
1817 SOFTWARE, 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
1839 var mat2d = {};
1840
1841 /**
1842  * Creates a new identity mat2d
1843  *
1844  * @returns {mat2d} a new 2x3 matrix
1845  */
1846 mat2d.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  */
1863 mat2d.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  */
1881 mat2d.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  */
1897 mat2d.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  */
1914 mat2d.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  */
1939 mat2d.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  */
1951 mat2d.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  */
1970 mat2d.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  */
1981 mat2d.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  **/
2008 mat2d.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  **/
2027 mat2d.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  */
2043 mat2d.str = function (a) {
2044     return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + 
2045                     a[3] + ', ' + a[4] + ', ' + a[5] + ')';
2046 };
2047
2048 if(typeof(exports) !== 'undefined') {
2049     exports.mat2d = mat2d;
2050 }
2051 ;
2052 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
2053
2054 Redistribution and use in source and binary forms, with or without modification,
2055 are 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
2063 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2064 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2065 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
2066 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
2067 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2068 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2069 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2070 ANY 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
2072 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
2073
2074 /**
2075  * @class 3x3 Matrix
2076  * @name mat3
2077  */
2078
2079 var mat3 = {};
2080
2081 /**
2082  * Creates a new identity mat3
2083  *
2084  * @returns {mat3} a new 3x3 matrix
2085  */
2086 mat3.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  */
2107 mat3.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  */
2126 mat3.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  */
2147 mat3.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  */
2166 mat3.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  */
2186 mat3.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  */
2218 mat3.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  */
2254 mat3.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  */
2277 mat3.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  */
2293 mat3.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  */
2320 mat3.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  */
2330 mat3.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  */
2358 mat3.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  **/
2388 mat3.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  **/
2413 mat3.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 */
2436 mat3.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  */
2473 mat3.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
2479 if(typeof(exports) !== 'undefined') {
2480     exports.mat3 = mat3;
2481 }
2482 ;
2483 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
2484
2485 Redistribution and use in source and binary forms, with or without modification,
2486 are 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
2494 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2495 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2496 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
2497 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
2498 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2499 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2500 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2501 ANY 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
2503 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
2504
2505 /**
2506  * @class 4x4 Matrix
2507  * @name mat4
2508  */
2509
2510 var mat4 = {};
2511
2512 /**
2513  * Creates a new identity mat4
2514  *
2515  * @returns {mat4} a new 4x4 matrix
2516  */
2517 mat4.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  */
2544 mat4.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  */
2572 mat4.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  */
2598 mat4.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  */
2625 mat4.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  */
2673 mat4.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  */
2727 mat4.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  */
2758 mat4.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  */
2789 mat4.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  */
2826 mat4.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  */
2836 mat4.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  **/
2873 mat4.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  */
2904 mat4.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  */
2966 mat4.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  */
3009 mat4.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  */
3052 mat4.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  */
3102 mat4.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 */
3147 mat4.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  */
3198 mat4.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  */
3231 mat4.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  */
3265 mat4.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  */
3297 mat4.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  */
3381 mat4.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
3388 if(typeof(exports) !== 'undefined') {
3389     exports.mat4 = mat4;
3390 }
3391 ;
3392 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
3393
3394 Redistribution and use in source and binary forms, with or without modification,
3395 are 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
3403 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3404 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3405 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
3406 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
3407 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3408 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3409 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3410 ANY 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
3412 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
3413
3414 /**
3415  * @class Quaternion
3416  * @name quat
3417  */
3418
3419 var quat = {};
3420
3421 /**
3422  * Creates a new identity quat
3423  *
3424  * @returns {quat} a new quaternion
3425  */
3426 quat.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  */
3442 quat.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  */
3454 quat.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  */
3464 quat.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  */
3477 quat.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  */
3485 quat.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  **/
3502 quat.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  */
3521 quat.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  */
3531 quat.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  */
3546 quat.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  */
3557 quat.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  */
3567 quat.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  */
3588 quat.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  */
3609 quat.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  */
3631 quat.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  */
3649 quat.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  */
3661 quat.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  */
3672 quat.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  */
3721 quat.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  */
3743 quat.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  */
3758 quat.length = vec4.length;
3759
3760 /**
3761  * Alias for {@link quat.length}
3762  * @function
3763  */
3764 quat.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  */
3773 quat.squaredLength = vec4.squaredLength;
3774
3775 /**
3776  * Alias for {@link quat.squaredLength}
3777  * @function
3778  */
3779 quat.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  */
3789 quat.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  */
3799 quat.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  */
3843 quat.str = function (a) {
3844     return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
3845 };
3846
3847 if(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 })();