1 /*
  2 SpiderGL Computer Graphics Library
  3 Copyright (c) 2010, Marco Di Benedetto - Visual Computing Lab, ISTI - CNR
  4 All rights reserved.
  5 
  6 Redistribution and use in source and binary forms, with or without
  7 modification, are permitted provided that the following conditions are met:
  8     * Redistributions of source code must retain the above copyright
  9       notice, this list of conditions and the following disclaimer.
 10     * Redistributions in binary form must reproduce the above copyright
 11       notice, this list of conditions and the following disclaimer in the
 12       documentation and/or other materials provided with the distribution.
 13     * Neither the name of SpiderGL nor the
 14       names of its contributors may be used to endorse or promote products
 15       derived from this software without specific prior written permission.
 16 
 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20 DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 */
 28 
 29 /**
 30  * @fileOverview Math
 31  */
 32 
 33 /**
 34  * The SpiderGL.Math namespace.
 35  *
 36  * @namespace The SpiderGL.Math namespace.
 37  */
 38 SpiderGL.Math = { };
 39 
 40 // constants
 41 /*---------------------------------------------------------*/
 42 
 43 /**
 44  * Scale factor for degrees to radians conversion.
 45  * It is equal to PI / 180.
 46  *
 47  * @constant
 48  *
 49  * @type number
 50  */
 51 SpiderGL.Math.DEG_TO_RAD = (Math.PI / 180.0);
 52 
 53 /**
 54  * Alias for Math.E.
 55  *
 56  * @constant
 57  *
 58  * @type number
 59  */
 60 SpiderGL.Math.E = Math.E;
 61 
 62 /**
 63  * Alias for Math.LN2.
 64  *
 65  * @constant
 66  *
 67  * @type number
 68  */
 69 SpiderGL.Math.LN2 = Math.LN2;
 70 
 71 /**
 72  * Alias for Math.LN10.
 73  *
 74  * @constant
 75  *
 76  * @type number
 77  */
 78 SpiderGL.Math.LN10 = Math.LN10;
 79 
 80 /**
 81  * Alias for Math.LOG2E.
 82  *
 83  * @constant
 84  *
 85  * @type number
 86  */
 87 SpiderGL.Math.LOG2E = Math.LOG2E;
 88 
 89 /**
 90  * Alias for Math.LOG10E.
 91  *
 92  * @constant
 93  *
 94  * @type number
 95  */
 96 SpiderGL.Math.LOG10E = Math.LOG10E;
 97 
 98 /**
 99  * Alias for Math.PI.
100  *
101  * @constant
102  *
103  * @type number
104  */
105 SpiderGL.Math.PI = Math.PI;
106 
107 /**
108  * Scale factor for radians to degrees conversion.
109  * It is equal to 180 / PI.
110  *
111  * @constant
112  *
113  * @type number
114  */
115 SpiderGL.Math.RAD_TO_DEG = (180.0 / Math.PI);
116 
117 /**
118  * Alias for Math.SQRT2.
119  *
120  * @constant
121  *
122  * @type number
123  */
124 SpiderGL.Math.SQRT2 = Math.SQRT2;
125 
126 
127 /**
128  * Alias for Number.MAX_VALUE.
129  *
130  * @constant
131  *
132  * @type number
133  */
134 SpiderGL.Math.MAX_VALUE = Number.MAX_VALUE;
135 
136 /**
137  * Alias for Number.MIN_VALUE.
138  *
139  * @constant
140  *
141  * @type number
142  */
143 SpiderGL.Math.MIN_VALUE = Number.MIN_VALUE;
144 
145 /**
146  * Alias for SpiderGL.Math.MAX_VALUE.
147  *
148  * @constant
149  *
150  * @type number
151  */
152 SpiderGL.Math.MAX_NUMBER = SpiderGL.Math.MAX_VALUE;
153 
154 /**
155  * Alias for -SpiderGL.Math.MAX_VALUE.
156  *
157  * @constant
158  *
159  * @type number
160  */
161 SpiderGL.Math.MIN_NUMBER = -SpiderGL.Math.MAX_VALUE;
162 
163 /**
164  * Alias for Number.NaN.
165  *
166  * @constant
167  *
168  * @type number
169  */
170 SpiderGL.Math.NAN = Number.NaN;
171 
172 /**
173  * Alias for global Infinity.
174  *
175  * @constant
176  *
177  * @type number
178  */
179 SpiderGL.Math.INFINITY = Infinity;
180 
181 /*---------------------------------------------------------*/
182 
183 
184 
185 // functions on scalars
186 /*---------------------------------------------------------*/
187 
188 /**
189  * Alias for Math.abs.
190  *
191  * @param {number} x A number.
192  *
193  * @returns {number} The absolute value of x.
194  */
195 SpiderGL.Math.abs = function (x) {
196 	return Math.abs(x);
197 }
198 
199 /**
200  * Alias for Math.acos.
201  *
202  * @param {number} x The input cosine.
203  *
204  * @returns {number} The arccosine of x, in radians.
205  */
206 SpiderGL.Math.acos = function (x) {
207 	return Math.acos(x);
208 }
209 
210 /**
211  * Alias for Math.asin.
212  *
213  * @param {number} x The input sine.
214  *
215  * @returns {number} The arcsine of x, in radians.
216  */
217 SpiderGL.Math.asin = function (x) {
218 	return Math.asin(x);
219 }
220 
221 /**
222  * Alias for Math.atan2.
223  *
224  * @param {number} x The input number.
225  *
226  * @returns {number} The arctangent of x as a numeric value between -PI/2 and PI/2 radians.
227  */
228 SpiderGL.Math.atan = function (x) {
229 	return Math.atan(x);
230 }
231 
232 /**
233  * Alias for Math.atan2.
234  *
235  * @param {number} y A number.
236  * @param {number} x A number.
237  *
238  * @returns {number} The the arctangent of the quotient of its arguments as a numeric value between PI and -PI.
239  */
240 SpiderGL.Math.atan2 = function (y, x) {
241 	return Math.atan2(y, x);
242 }
243 
244 /**
245  * Alias for Math.ceil.
246  *
247  * @param {number} x The input number.
248  *
249  * @returns {number} x rounded upwards to the nearest integer.
250  */
251 SpiderGL.Math.ceil = function (x) {
252 	return Math.ceil(x);
253 }
254 
255 /**
256  * Clamps a number over a range.
257  *
258  * @param {number} x The number to clamp.
259  * @param {number} min The lower bound.
260  * @param {number} max The upper bound.
261  *
262  * @returns {number} min if x < min, max if x > max, x otherwise.
263  */
264 SpiderGL.Math.clamp = function (x, min, max) {
265 	return ((x <= min) ? (min) : ((x >= max) ? (max) : (x)));
266 }
267 
268 /**
269  * Alias for Math.cos.
270  *
271  * @param {number} x The input angle, in radians.
272  *
273  * @returns {number} The cosine of x.
274  */
275 SpiderGL.Math.cos = function (x) {
276 	return Math.cos(x);
277 }
278 
279 /**
280  * Converts degrees to radians.
281  *
282  * @param {number} x The input angle, in degrees.
283  *
284  * @returns {number} x in radians.
285  */
286 SpiderGL.Math.degToRad = function (x) {
287 	return (x * SpiderGL.Math.DEG_TO_RAD);
288 }
289 
290 /**
291  * Alias for Math.exp.
292  *
293  * @param {number} x The input number.
294  *
295  * @returns {number} E raised to x.
296  */
297 SpiderGL.Math.exp = function (x) {
298 	return Math.exp(x);
299 }
300 
301 /**
302  * Alias for Math.floor.
303  *
304  * @param {number} x The input number.
305  *
306  * @returns {number} x rounded downwards to the nearest integer.
307  */
308 SpiderGL.Math.floor = function (x) {
309 	return Math.floor(x);
310 }
311 
312 /**
313  * Linear interpolation between two numbers.
314  *
315  * @param {number} x The start interpolation bound.
316  * @param {number} y The stop interpolation bound.
317  * @param {number} t The interpolation factor, between 0 and 1..
318  *
319  * @returns {number} The interpolated value (1-t)*x + t*y.
320  */
321 SpiderGL.Math.lerp = function (x, y, t) {
322 	return x + t * (y - x);
323 }
324 
325 /**
326  * Alias for Math.log.
327  * Same as {@link SpiderGL.Math.log}.
328  *
329  * @param {number} x The input number.
330  *
331  * @returns {number} The natural logarithm (base E) of x.
332  */
333 SpiderGL.Math.ln = function (x) {
334 	return Math.log(x);
335 }
336 
337 /**
338  * Alias for Math.log.
339  *
340  * @param {number} x The input number.
341  *
342  * @returns {number} The natural logarithm (base E) of x.
343  */
344 SpiderGL.Math.log = function (x) {
345 	return Math.log(x);
346 }
347 
348 /**
349  * Logarithm base 2.
350  *
351  * @param {number} x The input number.
352  *
353  * @returns {number} The base 2 logarithm of x.
354  */
355 SpiderGL.Math.log2 = function (x) {
356 	return (SpiderGL.Math.log(x) / SpiderGL.Math.LN2);
357 }
358 
359 /**
360  * Logarithm base 10.
361  *
362  * @param {number} x The input number.
363  *
364  * @returns {number} The base 10 logarithm of x.
365  */
366 SpiderGL.Math.log10 = function (x) {
367 	return (SpiderGL.Math.log(x) / SpiderGL.Math.LN10);
368 }
369 
370 /**
371  * Alias for Math.max.
372  *
373  * @param {number} args Variable number of arguments
374  *
375  * @returns {number} The number with the highest value.
376  *
377  * @example
378  * var x = SpiderGL.Math.max(3, 1.56, 2.1); // x == 3
379  */
380 SpiderGL.Math.max = function (args) {
381 	return Math.max.apply(Math, arguments);
382 }
383 
384 /**
385  * Alias for Math.min.
386  *
387  * @param {number} args Variable number of arguments
388  *
389  * @returns {number} The number with the lowest value.
390  *
391  * @example
392  * var x = SpiderGL.Math.min(3, 1.56, 2.1); // x == 1.56
393  */
394 SpiderGL.Math.min = function (args) {
395 	return Math.min.apply(Math, arguments);
396 }
397 
398 /**
399  * Alias for Math.pow.
400  *
401  * @param {number} x The base number.
402  * @param {number} x The exponent number.
403  *
404  * @returns {number} The value of x to the power of y.
405  */
406 SpiderGL.Math.pow = function (x, y) {
407 	return Math.pow(x, y);
408 }
409 
410 /**
411  * Converts radians to degrees.
412  *
413  * @param {number} x The input angle, in radians.
414  *
415  * @returns {number} x in degrees.
416  */
417 SpiderGL.Math.radToDeg = function (x) {
418 	return (x * SpiderGL.Math.RAD_TO_DEG);
419 }
420 
421 /**
422  * Alias for Math.random.
423  *
424  * @returns {number} A random number between 0.0 and 1.0, inclusive.
425  */
426 SpiderGL.Math.random = function () {
427 	return Math.random();
428 }
429 
430 /**
431  * Alias for SpiderGL.Math.random.
432  *
433  * @returns {number} A random number between 0.0 and 1.0, inclusive.
434  */
435 SpiderGL.Math.random01 = function () {
436 	return SpiderGL.Math.random();
437 }
438 
439 /**
440  * Generates a random number between -1.0 and 1.0.
441  *
442  * @returns {number} A random number between -1.0 and 1.0, inclusive.
443  */
444 SpiderGL.Math.random11 = function () {
445 	return (SpiderGL.Math.random() * 2 - 1);
446 }
447 
448 /**
449  * Generates a random number between a and b.
450  *
451  * @param {number} min The range low end-point.
452  * @param {number} max The range high end-point.
453  *
454  * @returns {number} A random number between min and max, inclusive.
455  */
456 SpiderGL.Math.randomRange = function (min, max) {
457 	return (min + SpiderGL.Math.random() * (max - min));
458 }
459 
460 /**
461  * Alias for Math.round.
462  *
463  * @param {number} x The input number.
464  *
465  * @returns {number} x rounded to the nearest integer.
466  *
467  * @example
468  * var a = SpiderGL.Math.round(    3); // a ==  3
469  * var b = SpiderGL.Math.round(   -4); // b == -4
470  * var c = SpiderGL.Math.round( 7.21); // c ==  7
471  * var d = SpiderGL.Math.round( 7.56); // d ==  8
472  * var e = SpiderGL.Math.round(-7.56); // e == -8
473  * var f = SpiderGL.Math.round(-7.21); // f == -7
474  */
475 SpiderGL.Math.round = function (x) {
476 	return Math.sqrt(x);
477 }
478 
479 /**
480  * Alias for Math.sin.
481  *
482  * @param {number} x The input angle, in radians.
483  *
484  * @returns {number} The sine of x.
485  */
486 SpiderGL.Math.sin = function (x) {
487 	return Math.sin(x);
488 }
489 
490 /**
491  * Alias for Math.sqrt.
492  *
493  * @param {number} x The input number.
494  *
495  * @returns {number} The square root of x.
496  */
497 SpiderGL.Math.sqrt = function (x) {
498 	return Math.sqrt(x);
499 }
500 
501 /**
502  * Alias for Math.tan.
503  *
504  * @param {number} x The input angle, in radians.
505  *
506  * @returns {number} The tangent of x.
507  */
508 SpiderGL.Math.tan = function (x) {
509 	return Math.tan(x);
510 }
511 
512 /*---------------------------------------------------------*/
513 
514 
515 
516 // 2-dimensional vector
517 /*---------------------------------------------------------*/
518 
519 /**
520  * The SpiderGL.Math.Vec2 namespace.
521  * The provided functions operate on 2-dimensional vectors, represented as standard JavaScript arrays of length 2.
522  * In general, vectors are considered as column vectors.
523  *
524  * @namespace The SpiderGL.Math.Vec2 namespace defines operations on 2-dimensional vectors.
525  */
526 SpiderGL.Math.Vec2 = { };
527 
528 /**
529  * Duplicates the input 2-dimensional vector.
530  *
531  * @param {array} v The input vector.
532  *
533  * @returns {array} A new 2-dimensional array r, where r[i] = v[i] (same as v.slice(0, 2)).
534  */
535 SpiderGL.Math.Vec2.dup = function (v) {
536 	return v.slice(0, 2);
537 }
538 
539 /**
540  * Creates a 2-dimensional vector initialized with a scalar.
541  *
542  * @param {number} s The input scalar.
543  *
544  * @returns {array} A new 2-dimensional array r, where r[i] = s.
545  */
546 SpiderGL.Math.Vec2.scalar = function (s) {
547 	return [s, s];
548 }
549 
550 /**
551  * Creates a 2-dimensional vector initialized with zero.
552  *
553  * @returns {array} A new 2-dimensional array r, where r[i] = 0.
554  */
555 SpiderGL.Math.Vec2.zero = function () {
556 	return [0, 0];
557 }
558 
559 /**
560  * Creates a 2-dimensional vector initialized with one.
561  *
562  * @returns {array} A new 2-dimensional array r, where r[i] = 1.0.
563  */
564 SpiderGL.Math.Vec2.one = function () {
565 	return [1, 1];
566 }
567 
568 /**
569  * Creates a 2-dimensional vector initialized with SpiderGL.Math.MAX_NUMBER.
570  *
571  * @returns {array} A new 2-dimensional array r, where r[i] = SpiderGL.Math.MAX_NUMBER.
572  */
573 SpiderGL.Math.Vec2.maxNumber = function () {
574 	return [SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER];
575 }
576 
577 /**
578  * Creates a 2-dimensional vector initialized with SpiderGL.Math.MIN_NUMBER.
579  *
580  * @returns {array} A new 2-dimensional array r, where r[i] = SpiderGL.Math.MIN_NUMBER.
581  */
582 SpiderGL.Math.Vec2.minNumber = function () {
583 	return [SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER];
584 }
585 
586 /**
587  * Creates a 3-dimensional vector from a 2-dimensional vector.
588  *
589  * @param {array} v The input vector.
590  * @param {number} [z=0.0] The 3th component.
591  *
592  * @returns {array} A new 3-dimensional array r equal to v extended with z as 3rd component.
593  */
594 SpiderGL.Math.Vec2.to3 = function (v, z) {
595 	return [v[0], v[1], (z != undefined) ? z : 0];
596 }
597 
598 /**
599  * Creates a 4-dimensional vector from a 2-dimensional vector.
600  *
601  * @param {array} v The input vector.
602  * @param {number} [z=0.0] The 3th component.
603  * @param {number} [w=1.0] The 4th component.
604  *
605  * @returns {array} A new 4-dimensional array r equal to v extended with z as 3rd component and w as 4th component.
606  */
607 SpiderGL.Math.Vec2.to4 = function (v, z, w) {
608 	return [v[0], v[1], v[2], (z != undefined) ? z : 0, (w != undefined) ? w : 1];
609 }
610 
611 /**
612  * Component-wise negation of a 2-dimensional vector.
613  *
614  * @param {array} v The input vector.
615  *
616  * @returns {array} A new 2-dimensionals vector r, where r[i] = -v[i].
617  */
618 SpiderGL.Math.Vec2.neg = function (v) {
619 	return [-v[0], -v[1]];
620 }
621 
622 /**
623  * Component-wise addition of two 2-dimensional vectors.
624  *
625  * @param {array} u The first addition operand.
626  * @param {array} v The second addition operand.
627  *
628  * @returns {array} A new 2-dimensionals vector r, where r[i] = u[i] + v[i].
629  */
630 SpiderGL.Math.Vec2.add = function (u, v) {
631 	return [u[0]+v[0], u[1]+v[1]];
632 }
633 
634 /**
635  * Component-wise addition of a 2-dimensional vector and a scalar.
636  *
637  * @param {array} v The vector addition operand.
638  * @param {number} s The scalar addition operand.
639  *
640  * @returns {array} A new 2-dimensionals vector r, where r[i] = v[i] + s.
641  */
642 SpiderGL.Math.Vec2.adds = function (v, s) {
643 	return [v[0]+s, v[1]+s];
644 }
645 
646 /**
647  * Component-wise subtraction of two 2-dimensional vectors.
648  *
649  * @param {array} u The first subtraction operand.
650  * @param {array} v The second subtraction operand.
651  *
652  * @returns {array} A new 2-dimensionals vector r, where r[i] = u[i] - v[i].
653  */
654 SpiderGL.Math.Vec2.sub = function (u, v) {
655 	return [u[0]-v[0], u[1]-v[1]];
656 }
657 
658 /**
659  * Component-wise subtraction of a 2-dimensional vector and a scalar.
660  *
661  * @param {array} v The vector subtraction operand.
662  * @param {number} s The scalar subtraction operand.
663  *
664  * @returns {array} A new 2-dimensionals vector r, where r[i] = v[i] - s.
665  */
666 SpiderGL.Math.Vec2.subs = function (v, s) {
667 	return [v[0]-s, v[1]-s];
668 }
669 
670 /**
671  * Component-wise subtraction of a scalar and a 2-dimensional.
672  *
673  * @param {number} s The scalar subtraction operand.
674  * @param {array} v The vector subtraction operand.
675  *
676  * @returns {array} A new 2-dimensionals vector r, where r[i] = s - v[i].
677  */
678 SpiderGL.Math.Vec2.ssub = function (s, v) {
679 	return [s-v[0], s-v[1]];
680 }
681 
682 /**
683  * Component-wise multiplication of two 2-dimensional vectors.
684  *
685  * @param {array} u The first multiplication operand.
686  * @param {array} v The second multiplication operand.
687  *
688  * @returns {array} A new 2-dimensionals vector r, where r[i] = u[i] * v[i].
689  */
690 SpiderGL.Math.Vec2.mul = function (u, v) {
691 	return [u[0]*v[0], u[1]*v[1]];
692 }
693 
694 /**
695  * Component-wise multiplication of a 2-dimensional vector and a scalar.
696  *
697  * @param {array} v The vector multiplication operand.
698  * @param {number} s The scalar multiplication operand.
699  *
700  * @returns {array} A new 2-dimensionals vector r, where r[i] = v[i] * s.
701  */
702 SpiderGL.Math.Vec2.muls = function (v, s) {
703 	return [v[0]*s, v[1]*s];
704 }
705 
706 /**
707  * Component-wise division of two 2-dimensional vectors.
708  *
709  * @param {array} u The numerator vector.
710  * @param {array} v The denominator vector.
711  *
712  * @returns {array} A new 2-dimensionals vector r, where r[i] = u[i] / v[i].
713  */
714 SpiderGL.Math.Vec2.div = function (u, v) {
715 	return [u[0]/v[0], u[1]/v[1]];
716 }
717 
718 /**
719  * Component-wise division of a 2-dimensional vector by a scalar.
720  *
721  * @param {array} v The numerator vector.
722  * @param {number} s The scalar denominator.
723  *
724  * @returns {array} A new 2-dimensionals vector r, where r[i] = v[i] / s.
725  */
726 SpiderGL.Math.Vec2.divs = function (v, s) {
727 	return [v[0]/s, v[1]/s];
728 }
729 
730 /**
731  * Component-wise division of a scalar by a 2-dimensional vector.
732  *
733  * @param {number} s The denominator scalar.
734  * @param {array} v The numerator vector.
735  *
736  * @returns {array} A new 2-dimensionals vector r, where r[i] = s / v[i].
737  */
738 SpiderGL.Math.Vec2.sdiv = function (s, v) {
739 	return [s/v[0], s/v[1]];
740 }
741 
742 /**
743  * Component-wise reciprocal of a 2-dimensional vector.
744  *
745  * @param {array} v The input (denominator) vector.
746  *
747  * @returns {array} A new 2-dimensionals vector r, where r[i] = 1.0 / v[i].
748  */
749 SpiderGL.Math.Vec2.rcp = function (v) {
750 	return [1.0/v[0], 1.0/v[1]];
751 }
752 
753 /**
754  * Dot product of two 2-dimensional vectors.
755  *
756  * @param {array} u The first vector operand.
757  * @param {array} v The second vector operand.
758  *
759  * @returns {number} The dot product of u and v.
760  */
761 SpiderGL.Math.Vec2.dot = function (u, v) {
762 	return (u[0]*v[0] + u[1]*v[1]);
763 }
764 
765 /**
766  * Cross product of two 2-dimensional vectors.
767  *
768  * @param {array} u The first vector operand.
769  * @param {array} v The second vector operand.
770  *
771  * @returns {array} A new 2-dimensional array equal to the cross product of u and v.
772  */
773 SpiderGL.Math.Vec2.cross = function (u, v) {
774 	return (u[0]*v[1] - u[1]*v[0]);
775 }
776 
777 /**
778  * Perp operation.
779  * Returns a 2-dimensional vector which is orthogonal to the input vector and lies in the right halfspace.
780  *
781  * @param {array} v The input vector.
782  *
783  * @returns {array} A new 2-dimensional array r, where r = [v[1], -v[0]].
784  */
785 SpiderGL.Math.Vec2.perp = function (v) {
786 	return [v[1], -v[0]];
787 }
788 
789 /**
790  * Squared length of a 2-dimensional vector.
791  *
792  * @param {array} v The input vector.
793  *
794  * @returns {number} The squared length of v, same as the dot product of v with itself.
795  */
796 SpiderGL.Math.Vec2.sqLength = function (v) {
797 	return SpiderGL.Math.Vec2.dot(v, v);
798 }
799 
800 /**
801  * Length of a 2-dimensional vector.
802  *
803  * @param {array} v The input vector.
804  *
805  * @returns {number} The length of v.
806  */
807 SpiderGL.Math.Vec2.length = function (v) {
808 	return SpiderGL.Math.sqrt(SpiderGL.Math.Vec2.sqLength(v));
809 }
810 
811 /**
812  * Creates a normalized 2-dimensional vector.
813  *
814  * @param {array} v The input vector.
815  *
816  * @returns {array} A new 2-dimensional array r representing the normalized v, where r[i] = v[i] / {@link SpiderGL.Math.Vec2.length}(v).
817  */
818 SpiderGL.Math.Vec2.normalize = function (v) {
819 	var f = 1.0 / SpiderGL.Math.Vec2.length(v);
820 	return SpiderGL.Math.Vec2.muls(v, f);
821 }
822 
823 /**
824  * Component-wise absolute value of a 2-dimensional vector.
825  *
826  * @param {array} v The input vector.
827  *
828  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.abs}(v[i]).
829  */
830 SpiderGL.Math.Vec2.abs = function (v) {
831 	return [SpiderGL.Math.abs(v[0]), SpiderGL.Math.abs(v[1])];
832 }
833 
834 /**
835  * Component-wise arccosine of a 2-dimensional vector.
836  *
837  * @param {array} v The input vector.
838  *
839  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.acos}(v[i]), in radians.
840  */
841 SpiderGL.Math.Vec2.acos = function (v) {
842 	return [SpiderGL.Math.acos(v[0]), SpiderGL.Math.acos(v[1])];
843 }
844 
845 /**
846  * Component-wise arcsine of a 2-dimensional vector.
847  *
848  * @param {array} v The input vector.
849  *
850  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.asin}(v[i]), in radians.
851  */
852 SpiderGL.Math.Vec2.asin = function (v) {
853 	return [SpiderGL.Math.asin(v[0]), SpiderGL.Math.asin(v[1])];
854 }
855 
856 /**
857  * Component-wise arctangent of a 2-dimensional vector.
858  *
859  * @param {array} v The input vector.
860  *
861  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.atan}(v[i]), between -PI/2 and PI/2 radians.
862  */
863 SpiderGL.Math.Vec2.atan = function (v) {
864 	return [SpiderGL.Math.atan(v[0]), SpiderGL.Math.atan(v[1])];
865 }
866 
867 /**
868  * Component-wise arctangent of the quotient of two 2-dimensional vectors.
869  *
870  * @param {array} y The numerator vector.
871  * @param {array} x The denominator vector.
872  *
873  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.atan2}(y[i], x[i]), between PI and -PI radians.
874  */
875 SpiderGL.Math.Vec2.atan2 = function (y, x) {
876 	return [SpiderGL.Math.atan2(y[0], x[0]), SpiderGL.Math.atan2(y[1], x[1])];
877 }
878 
879 /**
880  * Component-wise ceil of a 2-dimensional vector.
881  *
882  * @param {array} v The input vector.
883  *
884  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.ceil}(v[i]).
885  */
886 SpiderGL.Math.Vec2.ceil = function (v) {
887 	return [SpiderGL.Math.ceil(v[0]), SpiderGL.Math.ceil(v[1])];
888 }
889 
890 /**
891  * Component-wise clamp of a 2-dimensional vector with vector bounds.
892  *
893  * @param {array} v The input vector.
894  * @param {array} min The lower 2-dimensional bound.
895  * @param {array} max The upper 2-dimensional bound.
896  *
897  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.clamp}(v[i], min[i], max[i]).
898  */
899 SpiderGL.Math.Vec2.clamp = function (v, min, max) {
900 	return [SpiderGL.Math.clamp(v[0], min[0], max[0]), SpiderGL.Math.clamp(v[1], min[1], max[1])];
901 }
902 
903 /**
904  * Component-wise cosine of a 2-dimensional vector.
905  *
906  * @param {array} v The input vector, in radians.
907  *
908  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.cos}(v[i]).
909  */
910 SpiderGL.Math.Vec2.cos = function (v) {
911 	return [SpiderGL.Math.cos(v[0]), SpiderGL.Math.cos(v[1])];
912 }
913 
914 /**
915  * Component-wise conversion of a 2-dimensional vector from degrees to radians.
916  *
917  * @param {array} v The input vector, in radians.
918  *
919  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.degToRad}(v[i]).
920  */
921 SpiderGL.Math.Vec2.degToRad = function (v) {
922 	return [SpiderGL.Math.degToRad(v[0]), SpiderGL.Math.degToRad(v[1])];
923 }
924 
925 /**
926  * Component-wise exponential of a 2-dimensional vector.
927  *
928  * @param {array} v The input vector.
929  *
930  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.exp}(v[i]).
931  */
932 SpiderGL.Math.Vec2.exp = function (v) {
933 	return [SpiderGL.Math.exp(v[0]), SpiderGL.Math.exp(v[1])];
934 }
935 
936 /**
937  * Component-wise floor of a 2-dimensional vector.
938  *
939  * @param {array} v The input vector.
940  *
941  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.floor}(v[i]).
942  */
943 SpiderGL.Math.Vec2.floor = function (v) {
944 	return [SpiderGL.Math.floor(v[0]), SpiderGL.Math.floor(v[1])];
945 }
946 
947 /**
948  * Linear interpolation between two 2-dimensional vectors.
949  *
950  * @param {array} u The start interpolation bound.
951  * @param {array} v The stop interpolation bound.
952  * @param {number} t The interpolation factor, between 0 and 1.
953  *
954  * @returns {array} A new 2-dimensional array r, where r[i] = (1-t)*u[i] + t*v[i].
955  */
956 SpiderGL.Math.Vec2.lerp = function (u, v, t) {
957 	return [
958 		SpiderGL.Math.lerp(u[0], v[0], t),
959 		SpiderGL.Math.lerp(u[1], v[1], t)
960 	];
961 }
962 
963 /**
964  * Component-wise natural (base E) logarithm of a 2-dimensional vector.
965  * Same as {@link SpiderGL.Math.Vec2.log}.
966  *
967  * @param {array} v The input vector.
968  *
969  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.ln}(v[i]).
970  */
971 SpiderGL.Math.Vec2.ln = function (v) {
972 	return [SpiderGL.Math.ln(v[0]), SpiderGL.Math.ln(v[1])];
973 }
974 
975 /**
976  * Component-wise natural (base E) logarithm of a 2-dimensional vector.
977  *
978  * @param {array} v The input vector.
979  *
980  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.log}(v[i]).
981  */
982 SpiderGL.Math.Vec2.log = function (v) {
983 	return [SpiderGL.Math.log(v[0]), SpiderGL.Math.log(v[1])];
984 }
985 
986 /**
987  * Component-wise base 2 logarithm of a 2-dimensional vector.
988  *
989  * @param {array} v The input vector.
990  *
991  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.log2}(v[i]).
992  */
993 SpiderGL.Math.Vec2.log2 = function (v) {
994 	return [SpiderGL.Math.log2(v[0]), SpiderGL.Math.log2(v[1])];
995 }
996 
997 /**
998  * Component-wise base 10 logarithm of a 2-dimensional vector.
999  *
1000  * @param {array} v The input vector.
1001  *
1002  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.log10}(v[i]).
1003  */
1004 SpiderGL.Math.Vec2.log10 = function (v) {
1005 	return [SpiderGL.Math.log10(v[0]), SpiderGL.Math.log10(v[1])];
1006 }
1007 
1008 /**
1009  * Component-wise maximum of two 2-dimensional vectors.
1010  *
1011  * @param {array} u The first vector.
1012  * @param {array} v The second vector.
1013  *
1014  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.max}(u[i], v[i]).
1015  */
1016 SpiderGL.Math.Vec2.max = function (u, v) {
1017 	return [SpiderGL.Math.max(u[0], v[0]), SpiderGL.Math.max(u[1], v[1])];
1018 }
1019 
1020 /**
1021  * Component-wise minimum of two 2-dimensional vectors.
1022  *
1023  * @param {array} u The first vector.
1024  * @param {array} v The second vector.
1025  *
1026  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.min}(u[i], v[i]).
1027  */
1028 SpiderGL.Math.Vec2.min = function (u, v) {
1029 	return [SpiderGL.Math.min(u[0], v[0]), SpiderGL.Math.min(u[1], v[1])];
1030 }
1031 
1032 /**
1033  * Component-wise power of two 2-dimensional vectors.
1034  *
1035  * @param {array} u The base vector.
1036  * @param {array} v The exponent vector.
1037  *
1038  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.pow}(u[i], v[i]).
1039  */
1040 SpiderGL.Math.Vec2.pow = function (u, v) {
1041 	return [SpiderGL.Math.pow(u[0], v[0]), SpiderGL.Math.pow(u[1], v[1])];
1042 }
1043 
1044 /**
1045  * Component-wise conversion of a 2-dimensional vector from radians to degrees.
1046  *
1047  * @param {array} v The input vector, in degrees.
1048  *
1049  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.pow}(v[i]).
1050  */
1051 SpiderGL.Math.Vec2.radToDeg = function (v) {
1052 	return [SpiderGL.Math.radToDeg(v[0]), SpiderGL.Math.radToDeg(v[1])];
1053 }
1054 
1055 /**
1056  * Creates a random 2-dimensional vector between 0 and 1.
1057  *
1058  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.random}().
1059  */
1060 SpiderGL.Math.Vec2.random = function () {
1061 	return [SpiderGL.Math.random(), SpiderGL.Math.random()];
1062 }
1063 
1064 /**
1065  * Creates a random 2-dimensional vector between 0 and 1.
1066  * Same as {@link SpiderGL.Math.Vec2.random}.
1067  *
1068  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.random01}().
1069  */
1070 SpiderGL.Math.Vec2.random01 = function () {
1071 	return [SpiderGL.Math.random01(), SpiderGL.Math.random01()];
1072 }
1073 
1074 /**
1075  * Creates a random 2-dimensional vector between -1 and 1.
1076  *
1077  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.random11}().
1078  */
1079 SpiderGL.Math.Vec2.random11 = function () {
1080 	return [SpiderGL.Math.random11(), SpiderGL.Math.random11()];
1081 }
1082 
1083 /**
1084  * Creates a random 2-dimensional vector inside a range.
1085  *
1086  * @param {array} min The range vector lower bound.
1087  * @param {array} max The range vector upper bound.
1088  *
1089  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.randomRange}(min[i], max[i]).
1090  */
1091 SpiderGL.Math.Vec2.randomRange = function (min, max) {
1092 	return [SpiderGL.Math.randomRange(min[0], max[0]), SpiderGL.Math.randomRange(min[1], max[1])];
1093 }
1094 
1095 /**
1096  * Component-wise round of a 2-dimensional vector.
1097  *
1098  * @param {array} v The input vector.
1099  *
1100  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.round}(v[i]).
1101  */
1102 SpiderGL.Math.Vec2.round = function (v) {
1103 	return [SpiderGL.Math.round(v[0]), SpiderGL.Math.round(v[1])];
1104 }
1105 
1106 /**
1107  * Component-wise sine of a 2-dimensional vector.
1108  *
1109  * @param {array} v The input vector, in radians.
1110  *
1111  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.sin}(v[i]).
1112  */
1113 SpiderGL.Math.Vec2.sin = function (v) {
1114 	return [SpiderGL.Math.sin(v[0]), SpiderGL.Math.sin(v[1])];
1115 }
1116 
1117 /**
1118  * Component-wise square root of a 2-dimensional vector.
1119  *
1120  * @param {array} v The input vector.
1121  *
1122  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.sqrt}(v[i]).
1123  */
1124 SpiderGL.Math.Vec2.sqrt = function (v) {
1125 	return [SpiderGL.Math.sqrt(v[0]), SpiderGL.Math.sqrt(v[1])];
1126 }
1127 
1128 /**
1129  * Component-wise tangent root of a 2-dimensional vector.
1130  *
1131  * @param {array} v The input vector, in radians.
1132  *
1133  * @returns {array} A new 2-dimensional array r, where r[i] = {@link SpiderGL.Math.tan}(v[i]).
1134  */
1135 SpiderGL.Math.Vec2.tan = function (v) {
1136 	return [SpiderGL.Math.tan(v[0]), SpiderGL.Math.tan(v[1])];
1137 }
1138 
1139 /**
1140  * In-place component-wise copy of two 2-dimensional vectors.
1141  *
1142  * @param {array} u The destination vector.
1143  * @param {array} v The source vector.
1144  *
1145  * @returns {array} The destination vector u, where u[i] = v[i].
1146  */
1147 SpiderGL.Math.Vec2.copy$ = function (u, v) {
1148 	u[0] = v[0];
1149 	u[1] = v[1];
1150 	return u;
1151 }
1152 
1153 /**
1154  * In-place component-wise negation of a 2-dimensional vector.
1155  *
1156  * @param {array} v The input vector.
1157  *
1158  * @returns {array} The input vector v, where v[i] = -v[i].
1159  */
1160 SpiderGL.Math.Vec2.neg$ = function (v) {
1161 	v[0] = -v[0];
1162 	v[1] = -v[1];
1163 	return v;
1164 }
1165 
1166 /**
1167  * In-place component-wise addition of two 2-dimensional vectors.
1168  *
1169  * @param {array} u The first addition operand.
1170  * @param {array} v The second addition operand
1171  *
1172  * @returns {array} The input vector u, where u[i] = u[i] + v[i].
1173  */
1174 SpiderGL.Math.Vec2.add$ = function (u, v) {
1175 	u[0] += v[0];
1176 	u[1] += v[1];
1177 	return u;
1178 }
1179 
1180 /**
1181  * In-place component-wise addition of a 2-dimensional vector and a scalar.
1182  *
1183  * @param {array} v The vector addition operand.
1184  * @param {number} s The scalar addition operand
1185  *
1186  * @returns {array} The input vector v, where v[i] = v[i] + s.
1187  */
1188 SpiderGL.Math.Vec2.adds$ = function (v, s) {
1189 	v[0] += s;
1190 	v[1] += s;
1191 	return v;
1192 }
1193 
1194 /**
1195  * In-place component-wise subtraction of two 2-dimensional vectors.
1196  *
1197  * @param {array} u The first addition operand.
1198  * @param {array} v The second addition operand
1199  *
1200  * @returns {array} The input vector u, where u[i] = u[i] - v[i].
1201  */
1202 SpiderGL.Math.Vec2.sub$ = function (u, v) {
1203 	u[0] -= v[0];
1204 	u[1] -= v[1];
1205 	return u;
1206 }
1207 
1208 /**
1209  * In-place component-wise subtraction of a 2-dimensional vector and a scalar.
1210  *
1211  * @param {array} v The vector subtraction operand.
1212  * @param {number} s The scalar subtraction operand
1213  *
1214  * @returns {array} The input vector v, where v[i] = v[i] - s.
1215  */
1216 SpiderGL.Math.Vec2.subs$ = function (v, s) {
1217 	v[0] -= s;
1218 	v[1] -= s;
1219 	return v;
1220 }
1221 
1222 /**
1223  * In-place component-wise subtraction of a scalar and a 2-dimensional vector.
1224  *
1225  * @param {number} s The scalar subtraction operand
1226  * @param {array} v The vector subtraction operand.
1227  *
1228  * @returns {array} The input vector v, where v[i] = s - v[i].
1229  */
1230 SpiderGL.Math.Vec2.ssub$ = function (s, v) {
1231 	v[0] = s - v[0];
1232 	v[1] = s - v[1];
1233 	return v;
1234 }
1235 
1236 /**
1237  * In-place component-wise multiplication of two 2-dimensional vectors.
1238  *
1239  * @param {array} u The first multiplication operand.
1240  * @param {array} v The second multiplication operand
1241  *
1242  * @returns {array} The input vector u, where u[i] = u[i] * v[i].
1243  */
1244 SpiderGL.Math.Vec2.mul$ = function (u, v) {
1245 	u[0] *= v[0];
1246 	u[1] *= v[1];
1247 	return u;
1248 }
1249 
1250 /**
1251  * In-place component-wise multiplication of a 2-dimensional vector and a scalar.
1252  *
1253  * @param {array} v The first multiplication operand.
1254  * @param {number} s The second multiplication operand
1255  *
1256  * @returns {array} The input vector v, where v[i] = v[i] * s.
1257  */
1258 SpiderGL.Math.Vec2.muls$ = function (v, s) {
1259 	v[0] *= s;
1260 	v[1] *= s;
1261 	return v;
1262 }
1263 
1264 /**
1265  * In-place component-wise division of two 2-dimensional vectors.
1266  *
1267  * @param {array} u The numerator vector.
1268  * @param {array} v The denominator vector.
1269  *
1270  * @returns {array} The input vector u, where u[i] = u[i] / v[i].
1271  */
1272 SpiderGL.Math.Vec2.div$ = function (u, v) {
1273 	u[0] /= v[0];
1274 	u[1] /= v[1];
1275 	return u;
1276 }
1277 
1278 /**
1279  * In-place component-wise division of a 2-dimensional vector by a scalar.
1280  *
1281  * @param {array} v The numerator vector.
1282  * @param {number} s The scalar denominator.
1283  *
1284  * @returns {array} The input vector v, where v[i] = v[i] / s.
1285  */
1286 SpiderGL.Math.Vec2.divs$ = function (v, s) {
1287 	v[0] /= s;
1288 	v[1] /= s;
1289 	return v;
1290 }
1291 
1292 /**
1293  * In-place component-wise division of a scalar by a 2-dimensional.
1294  *
1295  * @param {number} s The scalar numerator.
1296  * @param {array} v The denominator vector.
1297  *
1298  * @returns {array} The input vector v, where v[i] = s / v[i].
1299  */
1300 SpiderGL.Math.Vec2.sdiv$ = function (v, s) {
1301 	v[0] = s / v[0];
1302 	v[1] = s / v[1];
1303 	return v;
1304 }
1305 
1306 /**
1307  * In-place perp operation.
1308  * Returns a 2-dimensional vector which is orthogonal to the input vector and lies in the right halfspace.
1309  *
1310  * @param {array} v The input vector.
1311  *
1312  * @returns {array} The input vector v, where v = [v[1], -v[0]].
1313  */
1314 SpiderGL.Math.Vec2.perp$ = function (v) {
1315 	var v0 = v[0];
1316 	v[0] = v[1];
1317 	v[1] = -v0;
1318 	return v;
1319 }
1320 
1321 /**
1322  * In-place 2-dimensional vector normalization.
1323  *
1324  * @param {array} v The input vector.
1325  *
1326  * @returns {array} The input vector v, where v[i] = v[i] / {@link SpiderGL.Math.Vec2.length}(v).
1327  */
1328 SpiderGL.Math.Vec2.normalize$ = function (v) {
1329 	var f = 1.0 / SpiderGL.Math.Vec2.length(v);
1330 	return SpiderGL.Math.Vec2.muls$(v, f);
1331 }
1332 
1333 /*---------------------------------------------------------*/
1334 
1335 
1336 
1337 // 3-dimensional vector
1338 /*---------------------------------------------------------*/
1339 
1340 /**
1341  * The SpiderGL.Math.Vec3 namespace.
1342  * The provided functions operate on 3-dimensional vectors, represented as standard JavaScript arrays of length 3.
1343  * In general, vectors are considered as column vectors.
1344  *
1345  * @namespace The SpiderGL.Math.Vec3 namespace defines operations on 3-dimensional vectors.
1346  */
1347 SpiderGL.Math.Vec3 = { };
1348 
1349 /**
1350  * Duplicates the input 3-dimensional vector.
1351  *
1352  * @param {array} v The input vector.
1353  *
1354  * @returns {array} A new 3-dimensional array r, where r[i] = v[i] (same as v.slice(0, 3)).
1355  */
1356 SpiderGL.Math.Vec3.dup = function (v) {
1357 	return v.slice(0, 3);
1358 }
1359 
1360 /**
1361  * Creates a 3-dimensional vector initialized with a scalar.
1362  *
1363  * @param {number} s The input scalar.
1364  *
1365  * @returns {array} A new 3-dimensional array r, where r[i] = s.
1366  */
1367 SpiderGL.Math.Vec3.scalar = function (s) {
1368 	return [s, s, s];
1369 }
1370 
1371 /**
1372  * Creates a 3-dimensional vector initialized with zero.
1373  *
1374  * @returns {array} A new 3-dimensional array r, where r[i] = 0.
1375  */
1376 SpiderGL.Math.Vec3.zero = function () {
1377 	return [0, 0, 0];
1378 }
1379 
1380 /**
1381  * Creates a 3-dimensional vector initialized with one.
1382  *
1383  * @returns {array} A new 3-dimensional array r, where r[i] = 1.0.
1384  */
1385 SpiderGL.Math.Vec3.one = function () {
1386 	return [1, 1, 1];
1387 }
1388 
1389 /**
1390  * Creates a 3-dimensional vector initialized with SpiderGL.Math.MAX_NUMBER.
1391  *
1392  * @returns {array} A new 3-dimensional array r, where r[i] = SpiderGL.Math.MAX_NUMBER.
1393  */
1394 SpiderGL.Math.Vec3.maxNumber = function () {
1395 	return [SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER];
1396 }
1397 
1398 /**
1399  * Creates a 3-dimensional vector initialized with SpiderGL.Math.MIN_NUMBER.
1400  *
1401  * @returns {array} A new 3-dimensional array r, where r[i] = SpiderGL.Math.MIN_NUMBER.
1402  */
1403 SpiderGL.Math.Vec3.minNumber = function () {
1404 	return [SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER];
1405 }
1406 
1407 /**
1408  * Creates a 2-dimensional vector from a 3-dimensional vector.
1409  *
1410  * @param {array} v The input vector.
1411  *
1412  * @returns {array} A new 2-dimensional array r equal to v with the 3rd component dropped.
1413  */
1414 SpiderGL.Math.Vec3.to2 = function (v) {
1415 	return [v[0], v[1]];
1416 }
1417 
1418 /**
1419  * Creates a 4-dimensional vector from a 3-dimensional vector.
1420  *
1421  * @param {array} v The input vector.
1422  * @param {number} [w=1.0] The 4th component.
1423  *
1424  * @returns {array} A new 4-dimensional array r equal to v extended with w as 4th component.
1425  */
1426 SpiderGL.Math.Vec3.to4 = function (v, w) {
1427 	return [v[0], v[1], v[2], (w != undefined) ? w : 1];
1428 }
1429 
1430 /**
1431  * Component-wise negation of a 3-dimensional vector.
1432  *
1433  * @param {array} v The input vector.
1434  *
1435  * @returns {array} A new 3-dimensionals vector r, where r[i] = -v[i].
1436  */
1437 SpiderGL.Math.Vec3.neg = function (v) {
1438 	return [-v[0], -v[1], -v[2]];
1439 }
1440 
1441 /**
1442  * Component-wise addition of two 3-dimensional vectors.
1443  *
1444  * @param {array} u The first addition operand.
1445  * @param {array} v The second addition operand.
1446  *
1447  * @returns {array} A new 3-dimensionals vector r, where r[i] = u[i] + v[i].
1448  */
1449 SpiderGL.Math.Vec3.add = function (u, v) {
1450 	return [u[0]+v[0], u[1]+v[1], u[2]+v[2]];
1451 }
1452 
1453 /**
1454  * Component-wise addition of a 3-dimensional vector and a scalar.
1455  *
1456  * @param {array} v The vector addition operand.
1457  * @param {number} s The scalar addition operand.
1458  *
1459  * @returns {array} A new 3-dimensionals vector r, where r[i] = v[i] + s.
1460  */
1461 SpiderGL.Math.Vec3.adds = function (v, s) {
1462 	return [v[0]+s, v[1]+s, v[2]+s];
1463 }
1464 
1465 /**
1466  * Component-wise subtraction of two 3-dimensional vectors.
1467  *
1468  * @param {array} u The first subtraction operand.
1469  * @param {array} v The second subtraction operand.
1470  *
1471  * @returns {array} A new 3-dimensionals vector r, where r[i] = u[i] - v[i].
1472  */
1473 SpiderGL.Math.Vec3.sub = function (u, v) {
1474 	return [u[0]-v[0], u[1]-v[1], u[2]-v[2]];
1475 }
1476 
1477 /**
1478  * Component-wise subtraction of a 3-dimensional vector and a scalar.
1479  *
1480  * @param {array} v The vector subtraction operand.
1481  * @param {number} s The scalar subtraction operand.
1482  *
1483  * @returns {array} A new 3-dimensionals vector r, where r[i] = v[i] - s.
1484  */
1485 SpiderGL.Math.Vec3.subs = function (v, s) {
1486 	return [v[0]-s, v[1]-s, v[2]-s];
1487 }
1488 
1489 /**
1490  * Component-wise subtraction of a scalar and a 3-dimensional.
1491  *
1492  * @param {number} s The scalar subtraction operand.
1493  * @param {array} v The vector subtraction operand.
1494  *
1495  * @returns {array} A new 3-dimensionals vector r, where r[i] = s - v[i].
1496  */
1497 SpiderGL.Math.Vec3.ssub = function (s, v) {
1498 	return [s-v[0], s-v[1], s-v[2]];
1499 }
1500 
1501 /**
1502  * Component-wise multiplication of two 3-dimensional vectors.
1503  *
1504  * @param {array} u The first multiplication operand.
1505  * @param {array} v The second multiplication operand.
1506  *
1507  * @returns {array} A new 3-dimensionals vector r, where r[i] = u[i] * v[i].
1508  */
1509 SpiderGL.Math.Vec3.mul = function (u, v) {
1510 	return [u[0]*v[0], u[1]*v[1], u[2]*v[2]];
1511 }
1512 
1513 /**
1514  * Component-wise multiplication of a 3-dimensional vector and a scalar.
1515  *
1516  * @param {array} v The vector multiplication operand.
1517  * @param {number} s The scalar multiplication operand.
1518  *
1519  * @returns {array} A new 3-dimensionals vector r, where r[i] = v[i] * s.
1520  */
1521 SpiderGL.Math.Vec3.muls = function (v, s) {
1522 	return [v[0]*s, v[1]*s, v[2]*s];
1523 }
1524 
1525 /**
1526  * Component-wise division of two 3-dimensional vectors.
1527  *
1528  * @param {array} u The numerator vector.
1529  * @param {array} v The denominator vector.
1530  *
1531  * @returns {array} A new 3-dimensionals vector r, where r[i] = u[i] / v[i].
1532  */
1533 SpiderGL.Math.Vec3.div = function (u, v) {
1534 	return [u[0]/v[0], u[1]/v[1], u[2]/v[2]];
1535 }
1536 
1537 /**
1538  * Component-wise division of a 3-dimensional vector by a scalar.
1539  *
1540  * @param {array} v The numerator vector.
1541  * @param {number} s The scalar denominator.
1542  *
1543  * @returns {array} A new 3-dimensionals vector r, where r[i] = v[i] / s.
1544  */
1545 SpiderGL.Math.Vec3.divs = function (v, s) {
1546 	return [v[0]/s, v[1]/s, v[2]/s];
1547 }
1548 
1549 /**
1550  * Component-wise division of a scalar by a 3-dimensional vector.
1551  *
1552  * @param {number} s The denominator scalar.
1553  * @param {array} v The numerator vector.
1554  *
1555  * @returns {array} A new 3-dimensionals vector r, where r[i] = s / v[i].
1556  */
1557 SpiderGL.Math.Vec3.sdiv = function (s, v) {
1558 	return [s/v[0], s/v[1], s/v[2]];
1559 }
1560 
1561 /**
1562  * Component-wise reciprocal of a 3-dimensional vector.
1563  *
1564  * @param {array} v The input (denominator) vector.
1565  *
1566  * @returns {array} A new 3-dimensionals vector r, where r[i] = 1.0 / v[i].
1567  */
1568 SpiderGL.Math.Vec3.rcp = function (v) {
1569 	return [1.0/v[0], 1.0/v[1], 1.0/v[2]];
1570 }
1571 
1572 /**
1573  * Dot product of two 3-dimensional vectors.
1574  *
1575  * @param {array} u The first vector operand.
1576  * @param {array} v The second vector operand.
1577  *
1578  * @returns {number} The dot product of u and v.
1579  */
1580 SpiderGL.Math.Vec3.dot = function (u, v) {
1581 	return (u[0]*v[0] + u[1]*v[1] + u[2]*v[2]);
1582 }
1583 
1584 /**
1585  * Cross product of two 3-dimensional vectors.
1586  *
1587  * @param {array} u The first vector operand.
1588  * @param {array} v The second vector operand.
1589  *
1590  * @returns {array} A new 3-dimensional array equal to the cross product of u and v.
1591  */
1592 SpiderGL.Math.Vec3.cross = function (u, v) {
1593 	return [u[1]*v[2] - u[2]*v[1], u[2]*v[0] - u[0]*v[2], u[0]*v[1] - u[1]*v[0]];
1594 }
1595 
1596 /**
1597  * Squared length of a 3-dimensional vector.
1598  *
1599  * @param {array} v The input vector.
1600  *
1601  * @returns {number} The squared length of v, same as the dot product of v with itself.
1602  */
1603 SpiderGL.Math.Vec3.sqLength = function (v) {
1604 	return SpiderGL.Math.Vec3.dot(v, v);
1605 }
1606 
1607 /**
1608  * Length of a 3-dimensional vector.
1609  *
1610  * @param {array} v The input vector.
1611  *
1612  * @returns {number} The length of v.
1613  */
1614 SpiderGL.Math.Vec3.length = function (v) {
1615 	return SpiderGL.Math.sqrt(SpiderGL.Math.Vec3.sqLength(v));
1616 }
1617 
1618 /**
1619  * Creates a normalized 3-dimensional vector.
1620  *
1621  * @param {array} v The input vector.
1622  *
1623  * @returns {array} A new 3-dimensional array r representing the normalized v, where r[i] = v[i] / {@link SpiderGL.Math.Vec3.length}(v).
1624  */
1625 SpiderGL.Math.Vec3.normalize = function (v) {
1626 	var f = 1.0 / SpiderGL.Math.Vec3.length(v);
1627 	return SpiderGL.Math.Vec3.muls(v, f);
1628 }
1629 
1630 /**
1631  * Component-wise absolute value of a 3-dimensional vector.
1632  *
1633  * @param {array} v The input vector.
1634  *
1635  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.abs}(v[i]).
1636  */
1637 SpiderGL.Math.Vec3.abs = function (v) {
1638 	return [SpiderGL.Math.abs(v[0]), SpiderGL.Math.abs(v[1]), SpiderGL.Math.abs(v[2])];
1639 }
1640 
1641 /**
1642  * Component-wise arccosine of a 3-dimensional vector.
1643  *
1644  * @param {array} v The input vector.
1645  *
1646  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.acos}(v[i]), in radians.
1647  */
1648 SpiderGL.Math.Vec3.acos = function (v) {
1649 	return [SpiderGL.Math.acos(v[0]), SpiderGL.Math.acos(v[1]), SpiderGL.Math.acos(v[2])];
1650 }
1651 
1652 /**
1653  * Component-wise arcsine of a 3-dimensional vector.
1654  *
1655  * @param {array} v The input vector.
1656  *
1657  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.asin}(v[i]), in radians.
1658  */
1659 SpiderGL.Math.Vec3.asin = function (v) {
1660 	return [SpiderGL.Math.asin(v[0]), SpiderGL.Math.asin(v[1]), SpiderGL.Math.asin(v[2])];
1661 }
1662 
1663 /**
1664  * Component-wise arctangent of a 3-dimensional vector.
1665  *
1666  * @param {array} v The input vector.
1667  *
1668  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.atan}(v[i]), between -PI/2 and PI/2 radians.
1669  */
1670 SpiderGL.Math.Vec3.atan = function (v) {
1671 	return [SpiderGL.Math.atan(v[0]), SpiderGL.Math.atan(v[1]), SpiderGL.Math.atan(v[2])];
1672 }
1673 
1674 /**
1675  * Component-wise arctangent of the quotient of two 3-dimensional vectors.
1676  *
1677  * @param {array} y The numerator vector.
1678  * @param {array} x The denominator vector.
1679  *
1680  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.atan2}(y[i], x[i]), between PI and -PI radians.
1681  */
1682 SpiderGL.Math.Vec3.atan2 = function (y, x) {
1683 	return [SpiderGL.Math.atan2(y[0], x[0]), SpiderGL.Math.atan2(y[1], x[1]), SpiderGL.Math.atan2(y[2], x[2])];
1684 }
1685 
1686 /**
1687  * Component-wise ceil of a 3-dimensional vector.
1688  *
1689  * @param {array} v The input vector.
1690  *
1691  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.ceil}(v[i]).
1692  */
1693 SpiderGL.Math.Vec3.ceil = function (v) {
1694 	return [SpiderGL.Math.ceil(v[0]), SpiderGL.Math.ceil(v[1]), SpiderGL.Math.ceil(v[2])];
1695 }
1696 
1697 /**
1698  * Component-wise clamp of a 3-dimensional vector with vector bounds.
1699  *
1700  * @param {array} v The input vector.
1701  * @param {array} min The lower 3-dimensional bound.
1702  * @param {array} max The upper 3-dimensional bound.
1703  *
1704  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.clamp}(v[i], min[i], max[i]).
1705  */
1706 SpiderGL.Math.Vec3.clamp = function (v, min, max) {
1707 	return [SpiderGL.Math.clamp(v[0], min[0], max[0]), SpiderGL.Math.clamp(v[1], min[1], max[1]), SpiderGL.Math.clamp(v[2], min[2], max[2])];
1708 }
1709 
1710 /**
1711  * Component-wise cosine of a 3-dimensional vector.
1712  *
1713  * @param {array} v The input vector, in radians.
1714  *
1715  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.cos}(v[i]).
1716  */
1717 SpiderGL.Math.Vec3.cos = function (v) {
1718 	return [SpiderGL.Math.cos(v[0]), SpiderGL.Math.cos(v[1]), SpiderGL.Math.cos(v[2])];
1719 }
1720 
1721 /**
1722  * Component-wise conversion of a 3-dimensional vector from degrees to radians.
1723  *
1724  * @param {array} v The input vector, in radians.
1725  *
1726  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.degToRad}(v[i]).
1727  */
1728 SpiderGL.Math.Vec3.degToRad = function (v) {
1729 	return [SpiderGL.Math.degToRad(v[0]), SpiderGL.Math.degToRad(v[1]), SpiderGL.Math.degToRad(v[2])];
1730 }
1731 
1732 /**
1733  * Component-wise exponential of a 3-dimensional vector.
1734  *
1735  * @param {array} v The input vector.
1736  *
1737  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.exp}(v[i]).
1738  */
1739 SpiderGL.Math.Vec3.exp = function (v) {
1740 	return [SpiderGL.Math.exp(v[0]), SpiderGL.Math.exp(v[1]), SpiderGL.Math.exp(v[2])];
1741 }
1742 
1743 /**
1744  * Component-wise floor of a 3-dimensional vector.
1745  *
1746  * @param {array} v The input vector.
1747  *
1748  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.floor}(v[i]).
1749  */
1750 SpiderGL.Math.Vec3.floor = function (v) {
1751 	return [SpiderGL.Math.floor(v[0]), SpiderGL.Math.floor(v[1]), SpiderGL.Math.floor(v[2])];
1752 }
1753 
1754 /**
1755  * Linear interpolation between two 3-dimensional vectors.
1756  *
1757  * @param {array} u The start interpolation bound.
1758  * @param {array} v The stop interpolation bound.
1759  * @param {number} t The interpolation factor, between 0 and 1.
1760  *
1761  * @returns {array} A new 3-dimensional array r, where r[i] = (1-t)*u[i] + t*v[i].
1762  */
1763 SpiderGL.Math.Vec3.lerp = function (u, v, t) {
1764 	return [
1765 		SpiderGL.Math.lerp(u[0], v[0], t),
1766 		SpiderGL.Math.lerp(u[1], v[1], t),
1767 		SpiderGL.Math.lerp(u[2], v[2], t)
1768 	];
1769 }
1770 
1771 /**
1772  * Component-wise natural (base E) logarithm of a 3-dimensional vector.
1773  * Same as {@link SpiderGL.Math.Vec3.log}.
1774  *
1775  * @param {array} v The input vector.
1776  *
1777  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.ln}(v[i]).
1778  */
1779 SpiderGL.Math.Vec3.ln = function (v) {
1780 	return [SpiderGL.Math.ln(v[0]), SpiderGL.Math.ln(v[1]), SpiderGL.Math.ln(v[2])];
1781 }
1782 
1783 /**
1784  * Component-wise natural (base E) logarithm of a 3-dimensional vector.
1785  *
1786  * @param {array} v The input vector.
1787  *
1788  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.log}(v[i]).
1789  */
1790 SpiderGL.Math.Vec3.log = function (v) {
1791 	return [SpiderGL.Math.log(v[0]), SpiderGL.Math.log(v[1]), SpiderGL.Math.log(v[2])];
1792 }
1793 
1794 /**
1795  * Component-wise base 2 logarithm of a 3-dimensional vector.
1796  *
1797  * @param {array} v The input vector.
1798  *
1799  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.log2}(v[i]).
1800  */
1801 SpiderGL.Math.Vec3.log2 = function (v) {
1802 	return [SpiderGL.Math.log2(v[0]), SpiderGL.Math.log2(v[1]), SpiderGL.Math.log2(v[2])];
1803 }
1804 
1805 /**
1806  * Component-wise base 10 logarithm of a 3-dimensional vector.
1807  *
1808  * @param {array} v The input vector.
1809  *
1810  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.log10}(v[i]).
1811  */
1812 SpiderGL.Math.Vec3.log10 = function (v) {
1813 	return [SpiderGL.Math.log10(v[0]), SpiderGL.Math.log10(v[1]), SpiderGL.Math.log10(v[2])];
1814 }
1815 
1816 /**
1817  * Component-wise maximum of two 3-dimensional vectors.
1818  *
1819  * @param {array} u The first vector.
1820  * @param {array} v The second vector.
1821  *
1822  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.max}(u[i], v[i]).
1823  */
1824 SpiderGL.Math.Vec3.max = function (u, v) {
1825 	return [SpiderGL.Math.max(u[0], v[0]), SpiderGL.Math.max(u[1], v[1]), SpiderGL.Math.max(u[2], v[2])];
1826 }
1827 
1828 /**
1829  * Component-wise minimum of two 3-dimensional vectors.
1830  *
1831  * @param {array} u The first vector.
1832  * @param {array} v The second vector.
1833  *
1834  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.min}(u[i], v[i]).
1835  */
1836 SpiderGL.Math.Vec3.min = function (u, v) {
1837 	return [SpiderGL.Math.min(u[0], v[0]), SpiderGL.Math.min(u[1], v[1]), SpiderGL.Math.min(u[2], v[2])];
1838 }
1839 
1840 /**
1841  * Component-wise power of two 3-dimensional vectors.
1842  *
1843  * @param {array} u The base vector.
1844  * @param {array} v The exponent vector.
1845  *
1846  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.pow}(u[i], v[i]).
1847  */
1848 SpiderGL.Math.Vec3.pow = function (u, v) {
1849 	return [SpiderGL.Math.pow(u[0], v[0]), SpiderGL.Math.pow(u[1], v[1]), SpiderGL.Math.pow(u[2], v[2])];
1850 }
1851 
1852 /**
1853  * Component-wise conversion of a 3-dimensional vector from radians to degrees.
1854  *
1855  * @param {array} v The input vector, in degrees.
1856  *
1857  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.pow}(v[i]).
1858  */
1859 SpiderGL.Math.Vec3.radToDeg = function (v) {
1860 	return [SpiderGL.Math.radToDeg(v[0]), SpiderGL.Math.radToDeg(v[1]), SpiderGL.Math.radToDeg(v[2])];
1861 }
1862 
1863 /**
1864  * Creates a random 3-dimensional vector between 0 and 1.
1865  *
1866  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.random}().
1867  */
1868 SpiderGL.Math.Vec3.random = function () {
1869 	return [SpiderGL.Math.random(), SpiderGL.Math.random(), SpiderGL.Math.random()];
1870 }
1871 
1872 /**
1873  * Creates a random 3-dimensional vector between 0 and 1.
1874  * Same as {@link SpiderGL.Math.Vec3.random}.
1875  *
1876  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.random01}().
1877  */
1878 SpiderGL.Math.Vec3.random01 = function () {
1879 	return [SpiderGL.Math.random01(), SpiderGL.Math.random01(), SpiderGL.Math.random01()];
1880 }
1881 
1882 /**
1883  * Creates a random 3-dimensional vector between -1 and 1.
1884  *
1885  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.random11}().
1886  */
1887 SpiderGL.Math.Vec3.random11 = function () {
1888 	return [SpiderGL.Math.random11(), SpiderGL.Math.random11(), SpiderGL.Math.random11()];
1889 }
1890 
1891 /**
1892  * Creates a random 3-dimensional vector inside a range.
1893  *
1894  * @param {array} min The range vector lower bound.
1895  * @param {array} max The range vector upper bound.
1896  *
1897  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.randomRange}(min[i], max[i]).
1898  */
1899 SpiderGL.Math.Vec3.randomRange = function (min, max) {
1900 	return [SpiderGL.Math.randomRange(min[0], max[0]), SpiderGL.Math.randomRange(min[1], max[1]), SpiderGL.Math.randomRange(min[2], max[2])];
1901 }
1902 
1903 /**
1904  * Component-wise round of a 3-dimensional vector.
1905  *
1906  * @param {array} v The input vector.
1907  *
1908  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.round}(v[i]).
1909  */
1910 SpiderGL.Math.Vec3.round = function (v) {
1911 	return [SpiderGL.Math.round(v[0]), SpiderGL.Math.round(v[1]), SpiderGL.Math.round(v[2])];
1912 }
1913 
1914 /**
1915  * Component-wise sine of a 3-dimensional vector.
1916  *
1917  * @param {array} v The input vector, in radians.
1918  *
1919  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.sin}(v[i]).
1920  */
1921 SpiderGL.Math.Vec3.sin = function (v) {
1922 	return [SpiderGL.Math.sin(v[0]), SpiderGL.Math.sin(v[1]), SpiderGL.Math.sin(v[2])];
1923 }
1924 
1925 /**
1926  * Component-wise square root of a 3-dimensional vector.
1927  *
1928  * @param {array} v The input vector.
1929  *
1930  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.sqrt}(v[i]).
1931  */
1932 SpiderGL.Math.Vec3.sqrt = function (v) {
1933 	return [SpiderGL.Math.sqrt(v[0]), SpiderGL.Math.sqrt(v[1]), SpiderGL.Math.sqrt(v[2])];
1934 }
1935 
1936 /**
1937  * Component-wise tangent root of a 3-dimensional vector.
1938  *
1939  * @param {array} v The input vector, in radians.
1940  *
1941  * @returns {array} A new 3-dimensional array r, where r[i] = {@link SpiderGL.Math.tan}(v[i]).
1942  */
1943 SpiderGL.Math.Vec3.tan = function (v) {
1944 	return [SpiderGL.Math.tan(v[0]), SpiderGL.Math.tan(v[1]), SpiderGL.Math.tan(v[2])];
1945 }
1946 
1947 /**
1948  * In-place component-wise copy of two 3-dimensional vectors.
1949  *
1950  * @param {array} u The destination vector.
1951  * @param {array} v The source vector.
1952  *
1953  * @returns {array} The destination vector u, where u[i] = v[i].
1954  */
1955 SpiderGL.Math.Vec3.copy$ = function (u, v) {
1956 	u[0] = v[0];
1957 	u[1] = v[1];
1958 	u[2] = v[2];
1959 	return u;
1960 }
1961 
1962 /**
1963  * In-place component-wise negation of a 3-dimensional vector.
1964  *
1965  * @param {array} v The input vector.
1966  *
1967  * @returns {array} The input vector v, where v[i] = -v[i].
1968  */
1969 SpiderGL.Math.Vec3.neg$ = function (v) {
1970 	v[0] = -v[0];
1971 	v[1] = -v[1];
1972 	v[2] = -v[2];
1973 	return v;
1974 }
1975 
1976 /**
1977  * In-place component-wise addition of two 3-dimensional vectors.
1978  *
1979  * @param {array} u The first addition operand.
1980  * @param {array} v The second addition operand
1981  *
1982  * @returns {array} The input vector u, where u[i] = u[i] + v[i].
1983  */
1984 SpiderGL.Math.Vec3.add$ = function (u, v) {
1985 	u[0] += v[0];
1986 	u[1] += v[1];
1987 	u[2] += v[2];
1988 	return u;
1989 }
1990 
1991 /**
1992  * In-place component-wise addition of a 3-dimensional vector and a scalar.
1993  *
1994  * @param {array} v The vector addition operand.
1995  * @param {number} s The scalar addition operand
1996  *
1997  * @returns {array} The input vector v, where v[i] = v[i] + s.
1998  */
1999 SpiderGL.Math.Vec3.adds$ = function (v, s) {
2000 	v[0] += s;
2001 	v[1] += s;
2002 	v[2] += s;
2003 	return v;
2004 }
2005 
2006 /**
2007  * In-place component-wise subtraction of two 3-dimensional vectors.
2008  *
2009  * @param {array} u The first addition operand.
2010  * @param {array} v The second addition operand
2011  *
2012  * @returns {array} The input vector u, where u[i] = u[i] - v[i].
2013  */
2014 SpiderGL.Math.Vec3.sub$ = function (u, v) {
2015 	u[0] -= v[0];
2016 	u[1] -= v[1];
2017 	u[2] -= v[2];
2018 	return u;
2019 }
2020 
2021 /**
2022  * In-place component-wise subtraction of a 3-dimensional vector and a scalar.
2023  *
2024  * @param {array} v The vector subtraction operand.
2025  * @param {number} s The scalar subtraction operand
2026  *
2027  * @returns {array} The input vector v, where v[i] = v[i] - s.
2028  */
2029 SpiderGL.Math.Vec3.subs$ = function (v, s) {
2030 	v[0] -= s;
2031 	v[1] -= s;
2032 	v[2] -= s;
2033 	return v;
2034 }
2035 
2036 /**
2037  * In-place component-wise subtraction of a scalar and a 3-dimensional vector.
2038  *
2039  * @param {number} s The scalar subtraction operand
2040  * @param {array} v The vector subtraction operand.
2041  *
2042  * @returns {array} The input vector v, where v[i] = s - v[i].
2043  */
2044 SpiderGL.Math.Vec3.ssub$ = function (s, v) {
2045 	v[0] = s - v[0];
2046 	v[1] = s - v[1];
2047 	v[2] = s - v[2];
2048 	return v;
2049 }
2050 
2051 /**
2052  * In-place component-wise multiplication of two 3-dimensional vectors.
2053  *
2054  * @param {array} u The first multiplication operand.
2055  * @param {array} v The second multiplication operand
2056  *
2057  * @returns {array} The input vector u, where u[i] = u[i] * v[i].
2058  */
2059 SpiderGL.Math.Vec3.mul$ = function (u, v) {
2060 	u[0] *= v[0];
2061 	u[1] *= v[1];
2062 	u[2] *= v[2];
2063 	return u;
2064 }
2065 
2066 /**
2067  * In-place component-wise multiplication of a 3-dimensional vector and a scalar.
2068  *
2069  * @param {array} v The first multiplication operand.
2070  * @param {number} s The second multiplication operand
2071  *
2072  * @returns {array} The input vector v, where v[i] = v[i] * s.
2073  */
2074 SpiderGL.Math.Vec3.muls$ = function (v, s) {
2075 	v[0] *= s;
2076 	v[1] *= s;
2077 	v[2] *= s;
2078 	return v;
2079 }
2080 
2081 /**
2082  * In-place component-wise division of two 3-dimensional vectors.
2083  *
2084  * @param {array} u The numerator vector.
2085  * @param {array} v The denominator vector.
2086  *
2087  * @returns {array} The input vector u, where u[i] = u[i] / v[i].
2088  */
2089 SpiderGL.Math.Vec3.div$ = function (u, v) {
2090 	u[0] /= v[0];
2091 	u[1] /= v[1];
2092 	u[2] /= v[2];
2093 	return u;
2094 }
2095 
2096 /**
2097  * In-place component-wise division of a 3-dimensional vector by a scalar.
2098  *
2099  * @param {array} v The numerator vector.
2100  * @param {number} s The scalar denominator.
2101  *
2102  * @returns {array} The input vector v, where v[i] = v[i] / s.
2103  */
2104 SpiderGL.Math.Vec3.divs$ = function (v, s) {
2105 	v[0] /= s;
2106 	v[1] /= s;
2107 	v[2] /= s;
2108 	return v;
2109 }
2110 
2111 /**
2112  * In-place component-wise division of a scalar by a 3-dimensional.
2113  *
2114  * @param {number} s The scalar numerator.
2115  * @param {array} v The denominator vector.
2116  *
2117  * @returns {array} The input vector v, where v[i] = s / v[i].
2118  */
2119 SpiderGL.Math.Vec3.sdiv$ = function (v, s) {
2120 	v[0] = s / v[0];
2121 	v[1] = s / v[1];
2122 	v[2] = s / v[2];
2123 	return v;
2124 }
2125 
2126 /**
2127  * In-place 3-dimensional vector normalization.
2128  *
2129  * @param {array} v The input vector.
2130  *
2131  * @returns {array} The input vector v, where v[i] = v[i] / {@link SpiderGL.Math.Vec3.length}(v)
2132  */
2133 SpiderGL.Math.Vec3.normalize$ = function (v) {
2134 	var f = 1.0 / SpiderGL.Math.Vec3.length(v);
2135 	return SpiderGL.Math.Vec3.muls$(v, f);
2136 }
2137 
2138 /*---------------------------------------------------------*/
2139 
2140 
2141 
2142 // 4-dimensional vector
2143 /*---------------------------------------------------------*/
2144 
2145 /**
2146  * The SpiderGL.Math.Vec4 namespace.
2147  * The provided functions operate on 4-dimensional vectors, represented as standard JavaScript arrays of length 4.
2148  * In general, vectors are considered as column vectors.
2149  *
2150  * @namespace The SpiderGL.Math.Vec4 namespace defines operations on 4-dimensional vectors.
2151  */
2152 SpiderGL.Math.Vec4 = { };
2153 
2154 /**
2155  * Duplicates the input 4-dimensional vector.
2156  *
2157  * @param {array} v The input vector.
2158  *
2159  * @returns {array} A new 4-dimensional array r, where r[i] = v[i] (same as v.slice(0, 4)).
2160  */
2161 SpiderGL.Math.Vec4.dup = function (v) {
2162 	return v.slice(0, 4);
2163 }
2164 
2165 /**
2166  * Creates a 4-dimensional vector initialized with a scalar.
2167  *
2168  * @param {number} s The input scalar.
2169  *
2170  * @returns {array} A new 4-dimensional array r, where r[i] = s.
2171  */
2172 SpiderGL.Math.Vec4.scalar = function (s) {
2173 	return [s, s, s, s];
2174 }
2175 
2176 /**
2177  * Creates a 4-dimensional vector initialized with zero.
2178  *
2179  * @returns {array} A new 4-dimensional array r, where r[i] = 0.
2180  */
2181 SpiderGL.Math.Vec4.zero = function () {
2182 	return [0, 0, 0, 0];
2183 }
2184 
2185 /**
2186  * Creates a 4-dimensional vector initialized with one.
2187  *
2188  * @returns {array} A new 4-dimensional array r, where r[i] = 1.0.
2189  */
2190 SpiderGL.Math.Vec4.one = function () {
2191 	return [1, 1, 1, 1];
2192 }
2193 
2194 /**
2195  * Creates a 4-dimensional vector initialized with SpiderGL.Math.MAX_NUMBER.
2196  *
2197  * @returns {array} A new 4-dimensional array r, where r[i] = SpiderGL.Math.MAX_NUMBER.
2198  */
2199 SpiderGL.Math.Vec4.maxNumber = function () {
2200 	return [SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER, SpiderGL.Math.MAX_NUMBER];
2201 }
2202 
2203 /**
2204  * Creates a 4-dimensional vector initialized with SpiderGL.Math.MIN_NUMBER.
2205  *
2206  * @returns {array} A new 4-dimensional array r, where r[i] = SpiderGL.Math.MIN_NUMBER.
2207  */
2208 SpiderGL.Math.Vec4.minNumber = function () {
2209 	return [SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER, SpiderGL.Math.MIN_NUMBER];
2210 }
2211 
2212 /**
2213  * Creates a 2-dimensional vector from a 4-dimensional vector.
2214  *
2215  * @param {array} v The input vector.
2216  *
2217  * @returns {array} A new 2-dimensional array r equal to v with the 3rd and 4th components dropped.
2218  */
2219 SpiderGL.Math.Vec4.to2 = function (v) {
2220 	return [v[0], v[1]];
2221 }
2222 
2223 /**
2224  * Creates a 3-dimensional vector from a 4-dimensional vector.
2225  *
2226  * @param {array} v The input vector.
2227  *
2228  * @returns {array} A new 3-dimensional array r equal to v with the 4th component dropped.
2229  */
2230 SpiderGL.Math.Vec4.to3 = function (v) {
2231 	return [v[0], v[1], v[2]];
2232 }
2233 
2234 /**
2235  * Component-wise negation of a 4-dimensional vector.
2236  *
2237  * @param {array} v The input vector.
2238  *
2239  * @returns {array} A new 4-dimensionals vector r, where r[i] = -v[i].
2240  */
2241 SpiderGL.Math.Vec4.neg = function (v) {
2242 	return [-v[0], -v[1], -v[2], -v[3]];
2243 }
2244 
2245 /**
2246  * Component-wise addition of two 4-dimensional vectors.
2247  *
2248  * @param {array} u The first addition operand.
2249  * @param {array} v The second addition operand.
2250  *
2251  * @returns {array} A new 4-dimensionals vector r, where r[i] = u[i] + v[i].
2252  */
2253 SpiderGL.Math.Vec4.add = function (u, v) {
2254 	return [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]];
2255 }
2256 
2257 /**
2258  * Component-wise addition of a 4-dimensional vector and a scalar.
2259  *
2260  * @param {array} v The vector addition operand.
2261  * @param {number} s The scalar addition operand.
2262  *
2263  * @returns {array} A new 4-dimensionals vector r, where r[i] = v[i] + s.
2264  */
2265 SpiderGL.Math.Vec4.adds = function (v, s) {
2266 	return [v[0]+s, v[1]+s, v[2]+s, v[3]+s];
2267 }
2268 
2269 /**
2270  * Component-wise subtraction of two 4-dimensional vectors.
2271  *
2272  * @param {array} u The first subtraction operand.
2273  * @param {array} v The second subtraction operand.
2274  *
2275  * @returns {array} A new 4-dimensionals vector r, where r[i] = u[i] - v[i].
2276  */
2277 SpiderGL.Math.Vec4.sub = function (u, v) {
2278 	return [u[0]-v[0], u[1]-v[1], u[2]-v[2], u[3]-v[3]];
2279 }
2280 
2281 /**
2282  * Component-wise subtraction of a 4-dimensional vector and a scalar.
2283  *
2284  * @param {array} v The vector subtraction operand.
2285  * @param {number} s The scalar subtraction operand.
2286  *
2287  * @returns {array} A new 4-dimensionals vector r, where r[i] = v[i] - s.
2288  */
2289 SpiderGL.Math.Vec4.subs = function (v, s) {
2290 	return [v[0]-s, v[1]-s, v[2]-s, v[3]-s];
2291 }
2292 
2293 /**
2294  * Component-wise subtraction of a scalar and a 4-dimensional.
2295  *
2296  * @param {number} s The scalar subtraction operand.
2297  * @param {array} v The vector subtraction operand.
2298  *
2299  * @returns {array} A new 4-dimensionals vector r, where r[i] = s - v[i].
2300  */
2301 SpiderGL.Math.Vec4.ssub = function (s, v) {
2302 	return [s-v[0], s-v[1], s-v[2], s-v[3]];
2303 }
2304 
2305 /**
2306  * Component-wise multiplication of two 4-dimensional vectors.
2307  *
2308  * @param {array} u The first multiplication operand.
2309  * @param {array} v The second multiplication operand.
2310  *
2311  * @returns {array} A new 4-dimensionals vector r, where r[i] = u[i] * v[i].
2312  */
2313 SpiderGL.Math.Vec4.mul = function (u, v) {
2314 	return [u[0]*v[0], u[1]*v[1], u[2]*v[2], u[3]*v[3]];
2315 }
2316 
2317 /**
2318  * Component-wise multiplication of a 4-dimensional vector and a scalar.
2319  *
2320  * @param {array} v The vector multiplication operand.
2321  * @param {number} s The scalar multiplication operand.
2322  *
2323  * @returns {array} A new 4-dimensionals vector r, where r[i] = v[i] * s.
2324  */
2325 SpiderGL.Math.Vec4.muls = function (v, s) {
2326 	return [v[0]*s, v[1]*s, v[2]*s, v[3]*s];
2327 }
2328 
2329 /**
2330  * Component-wise division of two 4-dimensional vectors.
2331  *
2332  * @param {array} u The numerator vector.
2333  * @param {array} v The denominator vector.
2334  *
2335  * @returns {array} A new 4-dimensionals vector r, where r[i] = u[i] / v[i].
2336  */
2337 SpiderGL.Math.Vec4.div = function (u, v) {
2338 	return [u[0]/v[0], u[1]/v[1], u[2]/v[2], u[3]/v[3]];
2339 }
2340 
2341 /**
2342  * Component-wise division of a 4-dimensional vector by a scalar.
2343  *
2344  * @param {array} v The numerator vector.
2345  * @param {number} s The scalar denominator.
2346  *
2347  * @returns {array} A new 4-dimensionals vector r, where r[i] = v[i] / s.
2348  */
2349 SpiderGL.Math.Vec4.divs = function (v, s) {
2350 	return [v[0]/s, v[1]/s, v[2]/s, v[3]/s];
2351 }
2352 
2353 /**
2354  * Component-wise division of a scalar by a 4-dimensional vector.
2355  *
2356  * @param {number} s The denominator scalar.
2357  * @param {array} v The numerator vector.
2358  *
2359  * @returns {array} A new 4-dimensionals vector r, where r[i] = s / v[i].
2360  */
2361 SpiderGL.Math.Vec4.sdiv = function (s, v) {
2362 	return [s/v[0], s/v[1], s/v[2], s/v[3]];
2363 }
2364 
2365 /**
2366  * Component-wise reciprocal of a 4-dimensional vector.
2367  *
2368  * @param {array} v The input (denominator) vector.
2369  *
2370  * @returns {array} A new 4-dimensionals vector r, where r[i] = 1.0 / v[i].
2371  */
2372 SpiderGL.Math.Vec4.rcp = function (v) {
2373 	return [1.0/v[0], 1.0/v[1], 1.0/v[2], 1.0/v[3]];
2374 }
2375 
2376 /**
2377  * Dot product of two 4-dimensional vectors.
2378  *
2379  * @param {array} u The first vector operand.
2380  * @param {array} v The second vector operand.
2381  *
2382  * @returns {number} The dot product of u and v.
2383  */
2384 SpiderGL.Math.Vec4.dot = function (u, v) {
2385 	return (u[0]*v[0] + u[1]*v[1] + u[2]*v[2] + u[3]*v[3]);
2386 }
2387 
2388 /**
2389  * Cross product of three 4-dimensional vectors.
2390  *
2391  * @param {array} u The first vector operand.
2392  * @param {array} v The second vector operand.
2393  * @param {array} w The third vector operand.
2394  *
2395  * @returns {array} A new 4-dimensional array equal to the cross product of u, v and w.
2396  */
2397 SpiderGL.Math.Vec4.cross = function (u, v, w) {
2398 	var a = v[0]*w[1] - v[1]*w[0];
2399 	var b = v[0]*w[2] - v[2]*w[0];
2400 	var c = v[0]*w[3] - v[3]*w[0];
2401 	var d = v[1]*w[2] - v[2]*w[1];
2402 	var e = v[1]*w[3] - v[3]*w[1];
2403 	var f = v[2]*w[3] - v[3]*w[2];
2404 
2405 	return [
2406 		u[1]*f - u[2]*e + u[3]*d,
2407 		u[0]*f + u[2]*c - u[3]*b,
2408 		u[0]*e - u[1]*c + u[3]*a,
2409 		u[0]*d + u[1]*b - u[2]*a
2410 	];
2411 }
2412 
2413 /**
2414  * Squared length of a 4-dimensional vector.
2415  *
2416  * @param {array} v The input vector.
2417  *
2418  * @returns {number} The squared length of v, same as the dot product of v with itself.
2419  */
2420 SpiderGL.Math.Vec4.sqLength = function (v) {
2421 	return SpiderGL.Math.Vec4.dot(v, v);
2422 }
2423 
2424 /**
2425  * Length of a 4-dimensional vector.
2426  *
2427  * @param {array} v The input vector.
2428  *
2429  * @returns {number} The length of v.
2430  */
2431 SpiderGL.Math.Vec4.length = function (v) {
2432 	return SpiderGL.Math.sqrt(SpiderGL.Math.Vec4.sqLength(v));
2433 }
2434 
2435 /**
2436  * Creates a normalized 4-dimensional vector.
2437  *
2438  * @param {array} v The input vector.
2439  *
2440  * @returns {array} A new 4-dimensional array r representing the normalized v, where r[i] = v[i] / {@link SpiderGL.Math.Vec4.length}(v).
2441  */
2442 SpiderGL.Math.Vec4.normalize = function (v) {
2443 	var f = 1.0 / SpiderGL.Math.Vec4.length(v);
2444 	return SpiderGL.Math.Vec4.muls(v, f);
2445 }
2446 
2447 /**
2448  * Projects a homogeneous 4-dimensional vector.
2449  *
2450  * @param {array} v The input vector.
2451  *
2452  * @returns {array} A new 4-dimensional array r, where r[i] = v[i] / v[3].
2453  */
2454 SpiderGL.Math.Vec4.project = function (v) {
2455 	var f = 1.0 / v[3];
2456 	return [v[0]*f, v[1]*f, v[2]*f, 1.0];
2457 }
2458 
2459 /**
2460  * Component-wise absolute value of a 4-dimensional vector.
2461  *
2462  * @param {array} v The input vector.
2463  *
2464  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.abs}(v[i]).
2465  */
2466 SpiderGL.Math.Vec4.abs = function (v) {
2467 	return [SpiderGL.Math.abs(v[0]), SpiderGL.Math.abs(v[1]), SpiderGL.Math.abs(v[2]), SpiderGL.Math.abs(v[3])];
2468 }
2469 
2470 /**
2471  * Component-wise arccosine of a 4-dimensional vector.
2472  *
2473  * @param {array} v The input vector.
2474  *
2475  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.acos}(v[i]), in radians.
2476  */
2477 SpiderGL.Math.Vec4.acos = function (v) {
2478 	return [SpiderGL.Math.acos(v[0]), SpiderGL.Math.acos(v[1]), SpiderGL.Math.acos(v[2]), SpiderGL.Math.acos(v[3])];
2479 }
2480 
2481 /**
2482  * Component-wise arcsine of a 4-dimensional vector.
2483  *
2484  * @param {array} v The input vector.
2485  *
2486  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.asin}(v[i]), in radians.
2487  */
2488 SpiderGL.Math.Vec4.asin = function (v) {
2489 	return [SpiderGL.Math.asin(v[0]), SpiderGL.Math.asin(v[1]), SpiderGL.Math.asin(v[2]), SpiderGL.Math.asin(v[3])];
2490 }
2491 
2492 /**
2493  * Component-wise arctangent of a 4-dimensional vector.
2494  *
2495  * @param {array} v The input vector.
2496  *
2497  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.atan}(v[i]), between -PI/2 and PI/2 radians.
2498  */
2499 SpiderGL.Math.Vec4.atan = function (v) {
2500 	return [SpiderGL.Math.atan(v[0]), SpiderGL.Math.atan(v[1]), SpiderGL.Math.atan(v[2]), SpiderGL.Math.atan(v[3])];
2501 }
2502 
2503 /**
2504  * Component-wise arctangent of the quotient of two 4-dimensional vectors.
2505  *
2506  * @param {array} y The numerator vector.
2507  * @param {array} x The denominator vector.
2508  *
2509  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.atan2}(y[i], x[i]), between PI and -PI radians.
2510  */
2511 SpiderGL.Math.Vec4.atan2 = function (y, x) {
2512 	return [SpiderGL.Math.atan2(y[0], x[0]), SpiderGL.Math.atan2(y[1], x[1]), SpiderGL.Math.atan2(y[2], x[2]), SpiderGL.Math.atan2(y[3], x[3])];
2513 }
2514 
2515 /**
2516  * Component-wise ceil of a 4-dimensional vector.
2517  *
2518  * @param {array} v The input vector.
2519  *
2520  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.ceil}(v[i]).
2521  */
2522 SpiderGL.Math.Vec4.ceil = function (v) {
2523 	return [SpiderGL.Math.ceil(v[0]), SpiderGL.Math.ceil(v[1]), SpiderGL.Math.ceil(v[2]), SpiderGL.Math.ceil(v[3])];
2524 }
2525 
2526 /**
2527  * Component-wise clamp of a 4-dimensional vector with vector bounds.
2528  *
2529  * @param {array} v The input vector.
2530  * @param {array} min The lower 4-dimensional bound.
2531  * @param {array} max The upper 4-dimensional bound.
2532  *
2533  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.clamp}(v[i], min[i], max[i]).
2534  */
2535 SpiderGL.Math.Vec4.clamp = function (v, min, max) {
2536 	return [SpiderGL.Math.clamp(v[0], min[0], max[0]), SpiderGL.Math.clamp(v[1], min[1], max[1]), SpiderGL.Math.clamp(v[2], min[2], max[2]), SpiderGL.Math.clamp(v[3], min[3], max[3])];
2537 }
2538 
2539 /**
2540  * Component-wise cosine of a 4-dimensional vector.
2541  *
2542  * @param {array} v The input vector, in radians.
2543  *
2544  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.cos}(v[i]).
2545  */
2546 SpiderGL.Math.Vec4.cos = function (v) {
2547 	return [SpiderGL.Math.cos(v[0]), SpiderGL.Math.cos(v[1]), SpiderGL.Math.cos(v[2]), SpiderGL.Math.cos(v[3])];
2548 }
2549 
2550 /**
2551  * Component-wise conversion of a 4-dimensional vector from degrees to radians.
2552  *
2553  * @param {array} v The input vector, in radians.
2554  *
2555  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.degToRad}(v[i]).
2556  */
2557 SpiderGL.Math.Vec4.degToRad = function (v) {
2558 	return [SpiderGL.Math.degToRad(v[0]), SpiderGL.Math.degToRad(v[1]), SpiderGL.Math.degToRad(v[2]), SpiderGL.Math.degToRad(v[3])];
2559 }
2560 
2561 /**
2562  * Component-wise exponential of a 4-dimensional vector.
2563  *
2564  * @param {array} v The input vector.
2565  *
2566  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.exp}(v[i]).
2567  */
2568 SpiderGL.Math.Vec4.exp = function (v) {
2569 	return [SpiderGL.Math.exp(v[0]), SpiderGL.Math.exp(v[1]), SpiderGL.Math.exp(v[2]), SpiderGL.Math.exp(v[3])];
2570 }
2571 
2572 /**
2573  * Component-wise floor of a 4-dimensional vector.
2574  *
2575  * @param {array} v The input vector.
2576  *
2577  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.floor}(v[i]).
2578  */
2579 SpiderGL.Math.Vec4.floor = function (v) {
2580 	return [SpiderGL.Math.floor(v[0]), SpiderGL.Math.floor(v[1]), SpiderGL.Math.floor(v[2]), SpiderGL.Math.floor(v[3])];
2581 }
2582 
2583 /**
2584  * Linear interpolation between two 4-dimensional vectors.
2585  *
2586  * @param {array} u The start interpolation bound.
2587  * @param {array} v The stop interpolation bound.
2588  * @param {number} t The interpolation factor, between 0 and 1.
2589  *
2590  * @returns {array} A new 4-dimensional array r, where r[i] = (1-t)*u[i] + t*v[i].
2591  */
2592 SpiderGL.Math.Vec4.lerp = function (u, v, t) {
2593 	return [
2594 		SpiderGL.Math.lerp(u[0], v[0], t),
2595 		SpiderGL.Math.lerp(u[1], v[1], t),
2596 		SpiderGL.Math.lerp(u[2], v[2], t),
2597 		SpiderGL.Math.lerp(u[3], v[3], t)
2598 	];
2599 }
2600 
2601 /**
2602  * Component-wise natural (base E) logarithm of a 4-dimensional vector.
2603  * Same as {@link SpiderGL.Math.Vec4.log}.
2604  *
2605  * @param {array} v The input vector.
2606  *
2607  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.ln}(v[i]).
2608  */
2609 SpiderGL.Math.Vec4.ln = function (v) {
2610 	return [SpiderGL.Math.ln(v[0]), SpiderGL.Math.ln(v[1]), SpiderGL.Math.ln(v[2]), SpiderGL.Math.ln(v[3])];
2611 }
2612 
2613 /**
2614  * Component-wise natural (base E) logarithm of a 4-dimensional vector.
2615  *
2616  * @param {array} v The input vector.
2617  *
2618  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.log}(v[i]).
2619  */
2620 SpiderGL.Math.Vec4.log = function (v) {
2621 	return [SpiderGL.Math.log(v[0]), SpiderGL.Math.log(v[1]), SpiderGL.Math.log(v[2]), SpiderGL.Math.log(v[3])];
2622 }
2623 
2624 /**
2625  * Component-wise base 2 logarithm of a 4-dimensional vector.
2626  *
2627  * @param {array} v The input vector.
2628  *
2629  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.log2}(v[i]).
2630  */
2631 SpiderGL.Math.Vec4.log2 = function (v) {
2632 	return [SpiderGL.Math.log2(v[0]), SpiderGL.Math.log2(v[1]), SpiderGL.Math.log2(v[2]), SpiderGL.Math.log2(v[3])];
2633 }
2634 
2635 /**
2636  * Component-wise base 10 logarithm of a 4-dimensional vector.
2637  *
2638  * @param {array} v The input vector.
2639  *
2640  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.log10}(v[i]).
2641  */
2642 SpiderGL.Math.Vec4.log10 = function (v) {
2643 	return [SpiderGL.Math.log10(v[0]), SpiderGL.Math.log10(v[1]), SpiderGL.Math.log10(v[2]), SpiderGL.Math.log10(v[3])];
2644 }
2645 
2646 /**
2647  * Component-wise maximum of two 4-dimensional vectors.
2648  *
2649  * @param {array} u The first vector.
2650  * @param {array} v The second vector.
2651  *
2652  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.max}(u[i], v[i]).
2653  */
2654 SpiderGL.Math.Vec4.max = function (u, v) {
2655 	return [SpiderGL.Math.max(u[0], v[0]), SpiderGL.Math.max(u[1], v[1]), SpiderGL.Math.max(u[2], v[2]), SpiderGL.Math.max(u[3], v[3])];
2656 }
2657 
2658 /**
2659  * Component-wise minimum of two 4-dimensional vectors.
2660  *
2661  * @param {array} u The first vector.
2662  * @param {array} v The second vector.
2663  *
2664  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.min}(u[i], v[i]).
2665  */
2666 SpiderGL.Math.Vec4.min = function (u, v) {
2667 	return [SpiderGL.Math.min(u[0], v[0]), SpiderGL.Math.min(u[1], v[1]), SpiderGL.Math.min(u[2], v[2]), SpiderGL.Math.min(u[3], v[3])];
2668 }
2669 
2670 /**
2671  * Component-wise power of two 4-dimensional vectors.
2672  *
2673  * @param {array} u The base vector.
2674  * @param {array} v The exponent vector.
2675  *
2676  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.pow}(u[i], v[i]).
2677  */
2678 SpiderGL.Math.Vec4.pow = function (u, v) {
2679 	return [SpiderGL.Math.pow(u[0], v[0]), SpiderGL.Math.pow(u[1], v[1]), SpiderGL.Math.pow(u[2], v[2]), SpiderGL.Math.pow(u[3], v[3])];
2680 }
2681 
2682 /**
2683  * Component-wise conversion of a 4-dimensional vector from radians to degrees.
2684  *
2685  * @param {array} v The input vector, in degrees.
2686  *
2687  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.pow}(v[i]).
2688  */
2689 SpiderGL.Math.Vec4.radToDeg = function (v) {
2690 	return [SpiderGL.Math.radToDeg(v[0]), SpiderGL.Math.radToDeg(v[1]), SpiderGL.Math.radToDeg(v[2]), SpiderGL.Math.radToDeg(v[3])];
2691 }
2692 
2693 /**
2694  * Creates a random 4-dimensional vector between 0 and 1.
2695  *
2696  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.random}().
2697  */
2698 SpiderGL.Math.Vec4.random = function () {
2699 	return [SpiderGL.Math.random(), SpiderGL.Math.random(), SpiderGL.Math.random(), SpiderGL.Math.random()];
2700 }
2701 
2702 /**
2703  * Creates a random 4-dimensional vector between 0 and 1.
2704  * Same as {@link SpiderGL.Math.Vec4.random}.
2705  *
2706  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.random01}().
2707  */
2708 SpiderGL.Math.Vec4.random01 = function () {
2709 	return [SpiderGL.Math.random01(), SpiderGL.Math.random01(), SpiderGL.Math.random01(), SpiderGL.Math.random01()];
2710 }
2711 
2712 /**
2713  * Creates a random 4-dimensional vector between -1 and 1.
2714  *
2715  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.random11}().
2716  */
2717 SpiderGL.Math.Vec4.random11 = function () {
2718 	return [SpiderGL.Math.random11(), SpiderGL.Math.random11(), SpiderGL.Math.random11(), SpiderGL.Math.random11()];
2719 }
2720 
2721 /**
2722  * Creates a random 4-dimensional vector inside a range.
2723  *
2724  * @param {array} min The range vector lower bound.
2725  * @param {array} max The range vector upper bound.
2726  *
2727  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.randomRange}(min[i], max[i]).
2728  */
2729 SpiderGL.Math.Vec4.randomRange = function (min, max) {
2730 	return [SpiderGL.Math.randomRange(min[0], max[0]), SpiderGL.Math.randomRange(min[1], max[1]), SpiderGL.Math.randomRange(min[2], max[2]), SpiderGL.Math.randomRange(min[3], max[3])];
2731 }
2732 
2733 /**
2734  * Component-wise round of a 4-dimensional vector.
2735  *
2736  * @param {array} v The input vector.
2737  *
2738  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.round}(v[i]).
2739  */
2740 SpiderGL.Math.Vec4.round = function (v) {
2741 	return [SpiderGL.Math.round(v[0]), SpiderGL.Math.round(v[1]), SpiderGL.Math.round(v[2]), SpiderGL.Math.round(v[3])];
2742 }
2743 
2744 /**
2745  * Component-wise sine of a 4-dimensional vector.
2746  *
2747  * @param {array} v The input vector, in radians.
2748  *
2749  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.sin}(v[i]).
2750  */
2751 SpiderGL.Math.Vec4.sin = function (v) {
2752 	return [SpiderGL.Math.sin(v[0]), SpiderGL.Math.sin(v[1]), SpiderGL.Math.sin(v[2]), SpiderGL.Math.sin(v[3])];
2753 }
2754 
2755 /**
2756  * Component-wise square root of a 4-dimensional vector.
2757  *
2758  * @param {array} v The input vector.
2759  *
2760  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.sqrt}(v[i]).
2761  */
2762 SpiderGL.Math.Vec4.sqrt = function (v) {
2763 	return [SpiderGL.Math.sqrt(v[0]), SpiderGL.Math.sqrt(v[1]), SpiderGL.Math.sqrt(v[2]), SpiderGL.Math.sqrt(v[3])];
2764 }
2765 
2766 /**
2767  * Component-wise tangent root of a 4-dimensional vector.
2768  *
2769  * @param {array} v The input vector, in radians.
2770  *
2771  * @returns {array} A new 4-dimensional array r, where r[i] = {@link SpiderGL.Math.tan}(v[i]).
2772  */
2773 SpiderGL.Math.Vec4.tan = function (v) {
2774 	return [SpiderGL.Math.tan(v[0]), SpiderGL.Math.tan(v[1]), SpiderGL.Math.tan(v[2]), SpiderGL.Math.tan(v[3])];
2775 }
2776 
2777 /**
2778  * In-place component-wise copy of two 4-dimensional vectors.
2779  *
2780  * @param {array} u The destination vector.
2781  * @param {array} v The source vector.
2782  *
2783  * @returns {array} The destination vector u, where u[i] = v[i].
2784  */
2785 SpiderGL.Math.Vec4.copy$ = function (u, v) {
2786 	u[0] = v[0];
2787 	u[1] = v[1];
2788 	u[2] = v[2];
2789 	u[3] = v[3];
2790 	return u;
2791 }
2792 
2793 /**
2794  * In-place component-wise negation of a 4-dimensional vector.
2795  *
2796  * @param {array} v The input vector.
2797  *
2798  * @returns {array} The input vector v, where v[i] = -v[i].
2799  */
2800 SpiderGL.Math.Vec4.neg$ = function (v) {
2801 	v[0] = -v[0];
2802 	v[1] = -v[1];
2803 	v[2] = -v[2];
2804 	v[3] = -v[3];
2805 	return v;
2806 }
2807 
2808 /**
2809  * In-place component-wise addition of two 4-dimensional vectors.
2810  *
2811  * @param {array} u The first addition operand.
2812  * @param {array} v The second addition operand
2813  *
2814  * @returns {array} The input vector u, where u[i] = u[i] + v[i].
2815  */
2816 SpiderGL.Math.Vec4.add$ = function (u, v) {
2817 	u[0] += v[0];
2818 	u[1] += v[1];
2819 	u[2] += v[2];
2820 	u[3] += v[3];
2821 	return u;
2822 }
2823 
2824 /**
2825  * In-place component-wise addition of a 4-dimensional vector and a scalar.
2826  *
2827  * @param {array} v The vector addition operand.
2828  * @param {number} s The scalar addition operand
2829  *
2830  * @returns {array} The input vector v, where v[i] = v[i] + s.
2831  */
2832 SpiderGL.Math.Vec4.adds$ = function (v, s) {
2833 	v[0] += s;
2834 	v[1] += s;
2835 	v[2] += s;
2836 	v[3] += s;
2837 	return v;
2838 }
2839 
2840 /**
2841  * In-place component-wise subtraction of two 4-dimensional vectors.
2842  *
2843  * @param {array} u The first addition operand.
2844  * @param {array} v The second addition operand
2845  *
2846  * @returns {array} The input vector u, where u[i] = u[i] - v[i].
2847  */
2848 SpiderGL.Math.Vec4.sub$ = function (u, v) {
2849 	u[0] -= v[0];
2850 	u[1] -= v[1];
2851 	u[2] -= v[2];
2852 	u[3] -= v[3];
2853 	return u;
2854 }
2855 
2856 /**
2857  * In-place component-wise subtraction of a 4-dimensional vector and a scalar.
2858  *
2859  * @param {array} v The vector subtraction operand.
2860  * @param {number} s The scalar subtraction operand
2861  *
2862  * @returns {array} The input vector v, where v[i] = v[i] - s.
2863  */
2864 SpiderGL.Math.Vec4.subs$ = function (v, s) {
2865 	v[0] -= s;
2866 	v[1] -= s;
2867 	v[2] -= s;
2868 	v[3] -= s;
2869 	return v;
2870 }
2871 
2872 /**
2873  * In-place component-wise subtraction of a scalar and a 4-dimensional vector.
2874  *
2875  * @param {number} s The scalar subtraction operand
2876  * @param {array} v The vector subtraction operand.
2877  *
2878  * @returns {array} The input vector v, where v[i] = s - v[i].
2879  */
2880 SpiderGL.Math.Vec4.ssub$ = function (s, v) {
2881 	v[0] = s - v[0];
2882 	v[1] = s - v[1];
2883 	v[2] = s - v[2];
2884 	v[3] = s - v[3];
2885 	return v;
2886 }
2887 
2888 /**
2889  * In-place component-wise multiplication of two 4-dimensional vectors.
2890  *
2891  * @param {array} u The first multiplication operand.
2892  * @param {array} v The second multiplication operand
2893  *
2894  * @returns {array} The input vector u, where u[i] = u[i] * v[i].
2895  */
2896 SpiderGL.Math.Vec4.mul$ = function (u, v) {
2897 	u[0] *= v[0];
2898 	u[1] *= v[1];
2899 	u[2] *= v[2];
2900 	u[3] *= v[3];
2901 	return u;
2902 }
2903 
2904 /**
2905  * In-place component-wise multiplication of a 4-dimensional vector and a scalar.
2906  *
2907  * @param {array} v The first multiplication operand.
2908  * @param {number} s The second multiplication operand
2909  *
2910  * @returns {array} The input vector v, where v[i] = v[i] * s.
2911  */
2912 SpiderGL.Math.Vec4.muls$ = function (v, s) {
2913 	v[0] *= s;
2914 	v[1] *= s;
2915 	v[2] *= s;
2916 	v[3] *= s;
2917 	return v;
2918 }
2919 
2920 /**
2921  * In-place component-wise division of two 4-dimensional vectors.
2922  *
2923  * @param {array} u The numerator vector.
2924  * @param {array} v The denominator vector.
2925  *
2926  * @returns {array} The input vector u, where u[i] = u[i] / v[i].
2927  */
2928 SpiderGL.Math.Vec4.div$ = function (u, v) {
2929 	u[0] /= v[0];
2930 	u[1] /= v[1];
2931 	u[2] /= v[2];
2932 	u[3] /= v[3];
2933 	return u;
2934 }
2935 
2936 /**
2937  * In-place component-wise division of a 4-dimensional vector by a scalar.
2938  *
2939  * @param {array} v The numerator vector.
2940  * @param {number} s The scalar denominator.
2941  *
2942  * @returns {array} The input vector v, where v[i] = v[i] / s.
2943  */
2944 SpiderGL.Math.Vec4.divs$ = function (v, s) {
2945 	v[0] /= s;
2946 	v[1] /= s;
2947 	v[2] /= s;
2948 	v[3] /= s;
2949 	return v;
2950 }
2951 
2952 /**
2953  * In-place component-wise division of a scalar by a 4-dimensional.
2954  *
2955  * @param {number} s The scalar numerator.
2956  * @param {array} v The denominator vector.
2957  *
2958  * @returns {array} The input vector v, where v[i] = s / v[i].
2959  */
2960 SpiderGL.Math.Vec4.sdiv$ = function (v, s) {
2961 	v[0] = s / v[0];
2962 	v[1] = s / v[1];
2963 	v[2] = s / v[2];
2964 	v[3] = s / v[3];
2965 	return v;
2966 }
2967 
2968 /**
2969  * In-place 4-dimensional vector normalization.
2970  *
2971  * @param {array} v The input vector.
2972  *
2973  * @returns {array} The input vector v, where v[i] = v[i] / {@link SpiderGL.Math.Vec4.length}(v)
2974  */
2975 SpiderGL.Math.Vec4.normalize$ = function (v) {
2976 	var f = 1.0 / SpiderGL.Math.Vec4.length(v);
2977 	return SpiderGL.Math.Vec4.muls$(v, f);
2978 }
2979 
2980 /*---------------------------------------------------------*/
2981 
2982 
2983 
2984 // 3x3 matrix
2985 /*---------------------------------------------------------*/
2986 
2987 /**
2988  * The SpiderGL.Math.Mat3 namespace.
2989  * The provided functions operate on 3x3 matrices, represented as standard JavaScript arrays of length 9.
2990  * In general, matrices are considered in column-major format.
2991  *
2992  * @namespace The SpiderGL.Math.Mat3 namespace defines operations on 3x3 matrices.
2993  */
2994 SpiderGL.Math.Mat3 = { };
2995 
2996 /**
2997  * Duplicates the input 3x3 matrix.
2998  *
2999  * @param {array} n The input matrix.
3000  *
3001  * @returns {array} A new 9-component array r, where r[i] = m[i] (same as m.slice(0, 9)).
3002  */
3003 SpiderGL.Math.Mat3.dup = function (m) {
3004 	return m.slice(0, 9);
3005 }
3006 
3007 /**
3008  * Creates a 3x3 matrix initialized with a scalar.
3009  *
3010  * @param {number} s The input scalar.
3011  *
3012  * @returns {array} A new 9-component array r, where r[i] = s.
3013  */
3014 SpiderGL.Math.Mat3.scalar = function (s) {
3015 	return [
3016 		s, s, s,
3017 		s, s, s,
3018 		s, s, s
3019 	];
3020 }
3021 
3022 /**
3023  * Creates a 3x3 matrix initialized with zero.
3024  *
3025  * @returns {array} A new 9-component array r, where r[i] = 0.
3026  */
3027 SpiderGL.Math.Mat3.zero = function () {
3028 	return [
3029 		0, 0, 0,
3030 		0, 0, 0,
3031 		0, 0, 0
3032 	];
3033 }
3034 
3035 /**
3036  * Creates a 3x3 matrix initialized with one.
3037  *
3038  * @returns {array} A new 9-component array r, where r[i] = 1.
3039  */
3040 SpiderGL.Math.Mat3.one = function () {
3041 	return [
3042 		1, 1, 1,
3043 		1, 1, 1,
3044 		1, 1, 1
3045 	];
3046 }
3047 
3048 /**
3049  * Creates a diagonal 3x3 matrix.
3050  *
3051  * @param {array} d A 3-dimensional vector
3052  *
3053  * @returns {array} A new 9-component array representing a 3x3 matrix with diagonal elements set to d.
3054  */
3055 SpiderGL.Math.Mat3.diag = function (d) {
3056 	return [
3057 		d[0],    0,    0,
3058 		0,    d[0],    0,
3059 		0,       0, d[0]
3060 	];
3061 }
3062 
3063 /**
3064  * Creates an identity 3x3 matrix.
3065  *
3066  * @returns {array} A new 9-component array representing an identity 3x3 matrix.
3067  */
3068 SpiderGL.Math.Mat3.identity = function () {
3069 	return [
3070 		1, 0, 0,
3071 		0, 1, 0,
3072 		0, 0, 1
3073 	];
3074 }
3075 
3076 /**
3077  * Extends a 3x3 matrix to a 4x4 matrix.
3078  *
3079  * @param {array} m The input matrix.
3080  *
3081  * @returns {array} A new 16-component array representing a 4x4 matrix r, with the input 3x3 matrix as tue upper-left 3x3 region with [0, 0, 0, 1] as last row and column.
3082  */
3083 SpiderGL.Math.Mat3.to44 = function (m) {
3084 	return [
3085 		m[0], m[1], m[2], 0,
3086 		m[3], m[4], m[5], 0,
3087 		m[6], m[7], m[8], 0,
3088 		   0,    0,    0, 1
3089 	];
3090 }
3091 
3092 /**
3093  * Pre-multiplies a 2-dimensional vector by a column-major 3x3 matrix.
3094  *
3095  * @param {array} m The input column-major 3x3 matrix.
3096  * @param {array} v The input 2-dimensional vector.
3097  * @param {number} [z=0] The 3rd component of the input 2-dimensional vector.
3098  *
3099  * @return {array} A new 2-dimensional vector r, where r = m * v.
3100  */
3101 SpiderGL.Math.Mat3.mul2 = function (m, v, z) {
3102 	z = (z == undefined) ? (0) : (z);
3103 	return [
3104 		m[0]*v[0] + m[3]*v[1] + m[6]*z,
3105 		m[1]*v[0] + m[4]*v[1] + m[7]*z /* ,
3106 		m[2]*v[0] + m[5]*v[1] + m[8]*z */
3107 	];
3108 }
3109 
3110 /**
3111  * Pre-multiplies a 3-dimensional vector by a column-major 3x3 matrix.
3112  *
3113  * @param {array} m The input column-major 3x3 matrix.
3114  * @param {array} v The input 3-dimensional vector.
3115  *
3116  * @return {array} A new 3-dimensional vector r, where r = m * v.
3117  */
3118 SpiderGL.Math.Mat3.mul3 = function (m, v) {
3119 	return [
3120 		m[0]*v[0] + m[3]*v[1] + m[6]*v[2],
3121 		m[1]*v[0] + m[4]*v[1] + m[7]*v[2],
3122 		m[2]*v[0] + m[5]*v[1] + m[8]*v[2]
3123 	];
3124 }
3125 
3126 /**
3127  * Creates the transpose of a 3x3 matrix.
3128  *
3129  * @param {array} m The input matrix.
3130  *
3131  * @returns {array} A new 3x3 matrix representing the transpose of m.
3132  */
3133 SpiderGL.Math.Mat3.transpose = function (m) {
3134 	return [
3135 		m[0], m[3], m[6],
3136 		m[1], m[4], m[7],
3137 		m[2], m[5], m[8]
3138 	];
3139 }
3140 /*---------------------------------------------------------*/
3141 
3142 
3143 
3144 // 4x4 matrix
3145 /*---------------------------------------------------------*/
3146 
3147 /**
3148  * The SpiderGL.Math.Mat4 namespace.
3149  * The provided functions operate on 4x4 matrices, represented as standard JavaScript arrays of length 16.
3150  * In general, matrices are considered in column-major format.
3151  *
3152  * @namespace The SpiderGL.Math.Mat4 namespace defines operations on 4x4 matrices.
3153  */
3154 SpiderGL.Math.Mat4 = { };
3155 
3156 /**
3157  * Duplicates the input 4x4 matrix.
3158  *
3159  * @param {array} n The input matrix.
3160  *
3161  * @returns {array} A new 16-component array r, where r[i] = m[i] (same as m.slice(0, 16)).
3162  */
3163 SpiderGL.Math.Mat4.dup = function (m) {
3164 	return m.slice(0, 16);
3165 }
3166 
3167 /**
3168  * Creates a 4x4 matrix initialized with a scalar.
3169  *
3170  * @param {number} s The input scalar.
3171  *
3172  * @returns {array} A new 16-component array r, where r[i] = s.
3173  */
3174 SpiderGL.Math.Mat4.scalar = function (s) {
3175 	return [
3176 		s, s, s, s,
3177 		s, s, s, s,
3178 		s, s, s, s,
3179 		s, s, s, s
3180 	];
3181 }
3182 
3183 /**
3184  * Creates a 4x4 matrix initialized with zero.
3185  *
3186  * @returns {array} A new 16-component array r, where r[i] = 0.
3187  */
3188 SpiderGL.Math.Mat4.zero = function () {
3189 	return [
3190 		0, 0, 0, 0,
3191 		0, 0, 0, 0,
3192 		0, 0, 0, 0,
3193 		0, 0, 0, 0
3194 	];
3195 }
3196 
3197 /**
3198  * Creates a 4x4 matrix initialized with one.
3199  *
3200  * @returns {array} A new 16-component array r, where r[i] = 1.
3201  */
3202 SpiderGL.Math.Mat4.one = function () {
3203 	return [
3204 		1, 1, 1, 1,
3205 		1, 1, 1, 1,
3206 		1, 1, 1, 1,
3207 		1, 1, 1, 1
3208 	];
3209 }
3210 
3211 /**
3212  * Creates a diagonal 4x4 matrix.
3213  *
3214  * @param {array} d A 4-dimensional vector
3215  *
3216  * @returns {array} A new 16-component array representing a 4x4 matrix with diagonal elements set to d.
3217  */
3218 SpiderGL.Math.Mat4.diag = function (d) {
3219 	return [
3220 		d[0],    0,    0,    0,
3221 		0,    d[0],    0,    0,
3222 		0,       0, d[0],    0,
3223 		0,       0,    0, d[0]
3224 	];
3225 }
3226 
3227 /**
3228  * Creates an identity 4x4 matrix.
3229  *
3230  * @returns {array} A new 16-component array representing an identity 4x4 matrix.
3231  */
3232 SpiderGL.Math.Mat4.identity = function () {
3233 	return [
3234 		1, 0, 0, 0,
3235 		0, 1, 0, 0,
3236 		0, 0, 1, 0,
3237 		0, 0, 0, 1
3238 	];
3239 }
3240 
3241 /**
3242  * Extracts the upper-left 3x3 matrix from a 4x4 matrix.
3243  *
3244  * @param {array} m The input matrix.
3245  *
3246  * @returns {array} A new 9-component array representing the upper-left 3x3 matrix.
3247  */
3248 SpiderGL.Math.Mat4.to33 = function (m) {
3249 	return [
3250 		m[ 0], m[ 1], m[ 2],
3251 		m[ 4], m[ 5], m[ 6],
3252 		m[ 8], m[ 9], m[10]
3253 	];
3254 }
3255 
3256 /**
3257  * Gets an element of a 4x4 matrix.
3258  *
3259  * @param {array} m The input matrix.
3260  * @param {number} row The element row index.
3261  * @param {number} col The element column index.
3262  *
3263  * @returns {number} The value of the (i-th, j-th) element of m.
3264  */
3265 SpiderGL.Math.Mat4.elem = function (m, row, col) {
3266 	return m[row+col*4];
3267 }
3268 
3269 /**
3270  * Sets an element of a 4x4 matrix.
3271  *
3272  * @param {array} m The input matrix.
3273  * @param {number} row The element row index.
3274  * @param {number} col The element column index.
3275  * @param {number} value The element value to set.
3276  */
3277 SpiderGL.Math.Mat4.elem$ = function (m, row, col, value) {
3278 	m[row+col*4] = value;
3279 }
3280 
3281 /**
3282  * Gets a row of a 4x4 matrix.
3283  *
3284  * @param {array} m The input matrix.
3285  * @param {number} row The row index.
3286  *
3287  * @returns {array} A new 4-component array representing the row-th row of m.
3288  */
3289 SpiderGL.Math.Mat4.row = function (m, row) {
3290 	return [m[row+0], m[row+4], m[row+8], m[row+12]];
3291 }
3292 
3293 /**
3294  * Sets a row of a 4x4 matrix.
3295  *
3296  * @param {array} m The input matrix.
3297  * @param {number} row The row index.
3298  * @param {array} v A 4-component array that will be copied to the row-th row of m.
3299  */
3300 SpiderGL.Math.Mat4.row$ = function (m, row, v) {
3301 	m[row+ 0] = v[0];
3302 	m[row+ 4] = v[1];
3303 	m[row+ 8] = v[2];
3304 	m[row+12] = v[3];
3305 }
3306 
3307 /**
3308  * Gets a column of a 4x4 matrix.
3309  *
3310  * @param {array} m The input matrix.
3311  * @param {number} col The column index.
3312  *
3313  * @returns {array} A new 4-component array representing the col-th column of m.
3314  */
3315 SpiderGL.Math.Mat4.col = function (m, col) {
3316 	var i = col * 4;
3317 	return [m[i+0], m[i+1], m[i+2], m[i+3]];
3318 }
3319 
3320 /**
3321  * Sets a column of a 4x4 matrix.
3322  *
3323  * @param {array} m The input matrix.
3324  * @param {number} col The column index.
3325  * @param {array} v A 4-component array that will be copied to the col-th column of m.
3326  */
3327 SpiderGL.Math.Mat4.col$ = function (m, col, v) {
3328 	var i = col * 4;
3329 	m[i+0] = v[0];
3330 	m[i+1] = v[1];
3331 	m[i+2] = v[2];
3332 	m[i+3] = v[3];
3333 }
3334 
3335 /**
3336  * Tests whether a 4x4 matrix is the identity matrix.
3337  *
3338  * @param {array} m The input matrix.
3339  *
3340  * @return {bool} True if the input matrix is the identity matrix, false otherwise.
3341  */
3342 SpiderGL.Math.Mat4.isIdentity = function (m) {
3343 	return ((m[ 0] === 1) && (m[ 1] === 0) && (m[ 2] === 0) && (m[ 3] === 0) &&
3344 	        (m[ 4] === 0) && (m[ 5] === 1) && (m[ 6] === 0) && (m[ 7] === 0) &&
3345 	        (m[ 8] === 0) && (m[ 9] === 0) && (m[10] === 1) && (m[11] === 0) &&
3346 	        (m[12] === 0) && (m[13] === 0) && (m[14] === 0) && (m[15] === 1));
3347 }
3348 
3349 /**
3350  * Component-wise negation of a 4x4 matrix.
3351  *
3352  * @param {array} m The input matrix.
3353  *
3354  * @return {array} A new 4x4 matrix r, where r[i] = -m[i].
3355  */
3356 SpiderGL.Math.Mat4.neg = function (m) {
3357 	return [
3358 		-m[ 0], -m[ 1], -m[ 2], -m[ 3],
3359 		-m[ 4], -m[ 5], -m[ 6], -m[ 7],
3360 		-m[ 8], -m[ 9], -m[10], -m[11],
3361 		-m[12], -m[13], -m[14], -m[15]
3362 	];
3363 }
3364 
3365 /**
3366  * Component-wise addition of two 4x4 matrices.
3367  *
3368  * @param {array} a The first input matrix.
3369  * @param {array} b The first input matrix.
3370  *
3371  * @return {array} A new 4x4 matrix r, where r[i] = a[i] + b[i].
3372  */
3373 SpiderGL.Math.Mat4.add = function (a, b) {
3374 	return [
3375 		a[ 0]+b[ 0], a[ 1]+b[ 1], a[ 2]+b[ 2], a[ 3]+b[ 3],
3376 		a[ 4]+b[ 4], a[ 5]+b[ 5], a[ 6]+b[ 6], a[ 7]+b[ 7],
3377 		a[ 8]+b[ 8], a[ 9]+b[ 9], a[10]+b[10], a[11]+b[11],
3378 		a[12]+b[12], a[13]+b[13], a[14]+b[14], a[15]+b[15]
3379 	];
3380 }
3381 
3382 /**
3383  * Component-wise addition of two 4x4 matrices.
3384  *
3385  * @param {array} a The first input matrix.
3386  * @param {array} b The first input matrix.
3387  *
3388  * @return {array} A new 4x4 matrix r, where r[i] = a[i] - b[i].
3389  */
3390 SpiderGL.Math.Mat4.sub = function (a, b) {
3391 	return [
3392 		a[ 0]-b[ 0], a[ 1]-b[ 1], a[ 2]-b[ 2], a[ 3]-b[ 3],
3393 		a[ 4]-b[ 4], a[ 5]-b[ 5], a[ 6]-b[ 6], a[ 7]-b[ 7],
3394 		a[ 8]-b[ 8], a[ 9]-b[ 9], a[10]-b[10], a[11]-b[11],
3395 		a[12]-b[12], a[13]-b[13], a[14]-b[14], a[15]-b[15]
3396 	];
3397 }
3398 
3399 /**
3400  * Multiplies of two column-major 4x4 matrices.
3401  *
3402  * @param {array} a The first input matrix.
3403  * @param {array} b The first input matrix.
3404  *
3405  * @return {array} A new 4x4 matrix r, result of matrix multiplication r = a * b.
3406  */
3407 SpiderGL.Math.Mat4.mul = function (a, b) {
3408 	var a0  = a[ 0], a1  = a[ 1],  a2 = a[ 2], a3  = a[ 3],
3409 	    a4  = a[ 4], a5  = a[ 5],  a6 = a[ 6], a7  = a[ 7],
3410 	    a8  = a[ 8], a9  = a[ 9], a10 = a[10], a11 = a[11],
3411 	    a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15],
3412 
3413 	    b0  = b[ 0], b1  = b[ 1], b2  = b[ 2], b3  = b[ 3],
3414 	    b4  = b[ 4], b5  = b[ 5], b6  = b[ 6], b7  = b[ 7],
3415 	    b8  = b[ 8], b9  = b[ 9], b10 = b[10], b11 = b[11],
3416 	    b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
3417 
3418 	return [
3419 		a0*b0  + a4*b1  + a8*b2   + a12*b3,
3420 		a1*b0  + a5*b1  + a9*b2   + a13*b3,
3421 		a2*b0  + a6*b1  + a10*b2  + a14*b3,
3422 		a3*b0  + a7*b1  + a11*b2  + a15*b3,
3423 
3424 		a0*b4  + a4*b5  + a8*b6   + a12*b7,
3425 		a1*b4  + a5*b5  + a9*b6   + a13*b7,
3426 		a2*b4  + a6*b5  + a10*b6  + a14*b7,
3427 		a3*b4  + a7*b5  + a11*b6  + a15*b7,
3428 
3429 		a0*b8  + a4*b9  + a8*b10  + a12*b11,
3430 		a1*b8  + a5*b9  + a9*b10  + a13*b11,
3431 		a2*b8  + a6*b9  + a10*b10 + a14*b11,
3432 		a3*b8  + a7*b9  + a11*b10 + a15*b11,
3433 
3434 		a0*b12 + a4*b13 + a8*b14  + a12*b15,
3435 		a1*b12 + a5*b13 + a9*b14  + a13*b15,
3436 		a2*b12 + a6*b13 + a10*b14 + a14*b15,
3437 		a3*b12 + a7*b13 + a11*b14 + a15*b15
3438 	];
3439 }
3440 
3441 /**
3442  * Component-wise multiplication of a 4x4 matrix and a scalar.
3443  *
3444  * @param {array} m The matrix operand.
3445  * @param {number} s The scalar operand.
3446  *
3447  * @returns {array} A new 4x4 matrix r, where r[i] = m[i] * s.
3448  */
3449 SpiderGL.Math.Mat4.muls = function (m, s) {
3450 	return [
3451 		m[ 0]*s, m[ 1]*s, m[ 2]*s, m[ 3]*s,
3452 		m[ 4]*s, m[ 5]*s, m[ 6]*s, m[ 7]*s,
3453 		m[ 8]*s, m[ 9]*s, m[10]*s, m[11]*s,
3454 		m[12]*s, m[13]*s, m[14]*s, m[15]*s
3455 	];
3456 }
3457 
3458 /**
3459  * Pre-multiplies a 3-dimensional vector by a column-major 4x4 matrix.
3460  *
3461  * @param {array} m The input column-major 4x4 matrix.
3462  * @param {array} v The input 3-dimensional vector.
3463  * @param {number} [w=1] The 4th component of the input 3-dimensional vector.
3464  *
3465  * @return {array} A new 3-dimensional vector r, where r = m * v.
3466  */
3467 SpiderGL.Math.Mat4.mul3 = function (m, v, w) {
3468 	w = (w == undefined) ? (1) : (w);
3469 	return [
3470 		m[ 0]*v[0] + m[ 4]*v[1] + m[ 8]*v[2] + m[12]*w,
3471 		m[ 1]*v[0] + m[ 5]*v[1] + m[ 9]*v[2] + m[13]*w,
3472 		m[ 2]*v[0] + m[ 6]*v[1] + m[10]*v[2] + m[14]*w /* ,
3473 		m[ 3]*v[0] + m[ 7]*v[1] + m[11]*v[2] + m[15]*w */
3474 	];
3475 }
3476 
3477 /**
3478  * Pre-multiplies a 4-dimensional vector by a column-major 4x4 matrix.
3479  *
3480  * @param {array} m The input column-major 4x4 matrix.
3481  * @param {array} v The input 4-dimensional vector.
3482  *
3483  * @return {array} A new 4-dimensional vector r, where r = m * v.
3484  */
3485 SpiderGL.Math.Mat4.mul4 = function (m, v) {
3486 	return [
3487 		m[ 0]*v[0] + m[ 4]*v[1] + m[ 8]*v[2] + m[12]*v[3],
3488 		m[ 1]*v[0] + m[ 5]*v[1] + m[ 9]*v[2] + m[13]*v[3],
3489 		m[ 2]*v[0] + m[ 6]*v[1] + m[10]*v[2] + m[14]*v[3],
3490 		m[ 3]*v[0] + m[ 7]*v[1] + m[11]*v[2] + m[15]*v[3]
3491 	];
3492 }
3493 
3494 /**
3495  * Component-wise reciprocal of a 4x4 matrix.
3496  *
3497  * @param {array} m The input matrix.
3498  *
3499  * @returns {array} A new 4x4 matrix r, where r[i] = 1 / m[i].
3500  */
3501 SpiderGL.Math.Mat4.rcp = function (m) {
3502 	return [
3503 		1/m[ 0], 1/m[ 1], 1/m[ 2], 1/m[ 3],
3504 		1/m[ 4], 1/m[ 5], 1/m[ 6], 1/m[ 7],
3505 		1/m[ 8], 1/m[ 9], 1/m[10], 1/m[11],
3506 		1/m[12], 1/m[13], 1/m[14], 1/m[15]
3507 	];
3508 }
3509 
3510 /**
3511  * Component-wise multiplication of two 4x4 matrices.
3512  *
3513  * @param {array} a The first matrix.
3514  * @param {array} b The second matrix.
3515  *
3516  * @returns {array} A new 4x4 matrix r, where r[i] = a[i] * b[i].
3517  */
3518 SpiderGL.Math.Mat4.compMul = function (a, b) {
3519 	return [
3520 		a[ 0]*b[ 0], a[ 1]*b[ 1], a[ 2]*b[ 2], a[ 3]*b[ 3],
3521 		a[ 4]*b[ 4], a[ 5]*b[ 5], a[ 6]*b[ 6], a[ 7]*b[ 7],
3522 		a[ 8]*b[ 8], a[ 9]*b[ 9], a[10]*b[10], a[11]*b[11],
3523 		a[12]*b[12], a[13]*b[13], a[14]*b[14], a[15]*b[15]
3524 	];
3525 }
3526 
3527 /**
3528  * Component-wise division of two 4x4 matrices.
3529  *
3530  * @param {array} a The first matrix.
3531  * @param {array} b The second matrix.
3532  *
3533  * @returns {array} A new 4x4 matrix r, where r[i] = a[i] / b[i].
3534  */
3535 SpiderGL.Math.Mat4.compDiv = function (a, b) {
3536 	return [
3537 		a[ 0]/b[ 0], a[ 1]/b[ 1], a[ 2]/b[ 2], a[ 3]/b[ 3],
3538 		a[ 4]/b[ 4], a[ 5]/b[ 5], a[ 6]/b[ 6], a[ 7]/b[ 7],
3539 		a[ 8]/b[ 8], a[ 9]/b[ 9], a[10]/b[10], a[11]/b[11],
3540 		a[12]/b[12], a[13]/b[13], a[14]/b[14], a[15]/b[15]
3541 	];
3542 }
3543 
3544 /**
3545  * Creates the transpose of a 4x4 matrix.
3546  *
3547  * @param {array} m The input matrix.
3548  *
3549  * @returns {array} A new 4x4 matrix representing the transpose of m.
3550  */
3551 SpiderGL.Math.Mat4.transpose = function (m) {
3552 	return [
3553 		m[ 0], m[ 4], m[ 8], m[12],
3554 		m[ 1], m[ 5], m[ 9], m[13],
3555 		m[ 2], m[ 6], m[10], m[14],
3556 		m[ 3], m[ 7], m[11], m[15]
3557 	];
3558 }
3559 
3560 /**
3561  * Calculates the determinant of a 4x4 matrix.
3562  *
3563  * @param {array} m The input matrix.
3564  *
3565  * @returns {number} The determinant of m.
3566  */
3567 SpiderGL.Math.Mat4.determinant = function (m) {
3568 	var m0  = m[ 0], m1  = m[ 1], m2  = m[ 2], m3  = m[ 3],
3569 	    m4  = m[ 4], m5  = m[ 5], m6  = m[ 6], m7  = m[ 7],
3570 	    m8  = m[ 8], m9  = m[ 9], m10 = m[10], m11 = m[11],
3571 	    m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];
3572 
3573 	return (m12 * m9 * m6 * m3 - m8 * m13 * m6 * m3 - m12 * m5 * m10 * m3 + m4 * m13 * m10 * m3 +
3574 	        m8 * m5 * m14 * m3 - m4 * m9 * m14 * m3 - m12 * m9 * m2 * m7 + m8 * m13 * m2 * m7 +
3575 	        m12 * m1 * m10 * m7 - m0 * m13 * m10 * m7 - m8 * m1 * m14 * m7 + m0 * m9 * m14 * m7 +
3576 	        m12 * m5 * m2 * m11 - m4 * m13 * m2 * m11 - m12 * m1 * m6 * m11 + m0 * m13 * m6 * m11 +
3577 	        m4 * m1 * m14 * m11 - m0 * m5 * m14 * m11 - m8 * m5 * m2 * m15 + m4 * m9 * m2 * m15 +
3578 	        m8 * m1 * m6 * m15 - m0 * m9 * m6 * m15 - m4 * m1 * m10 * m15 + m0 * m5 * m10 * m15);
3579 }
3580 
3581 /**
3582  * Calculates the inverse of a 4x4 matrix.
3583  *
3584  * @param {array} m The input matrix.
3585  *
3586  * @returns {array} A new 4x4 matrix representing the inverse of m.
3587  */
3588 SpiderGL.Math.Mat4.inverse = function (m) {
3589 	var m0  = m[ 0], m1  = m[ 1], m2  = m[ 2], m3  = m[ 3],
3590 	    m4  = m[ 4], m5  = m[ 5], m6  = m[ 6], m7  = m[ 7],
3591 	    m8  = m[ 8], m9  = m[ 9], m10 = m[10], m11 = m[11],
3592 	    m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];
3593 
3594 	var d = 1 / (
3595 		m12 * m9 * m6 * m3 - m8 * m13 * m6 * m3 - m12 * m5 * m10 * m3 + m4 * m13 * m10 * m3 +
3596 		m8 * m5 * m14 * m3 - m4 * m9 * m14 * m3 - m12 * m9 * m2 * m7 + m8 * m13 * m2 * m7 +
3597 		m12 * m1 * m10 * m7 - m0 * m13 * m10 * m7 - m8 * m1 * m14 * m7 + m0 * m9 * m14 * m7 +
3598 		m12 * m5 * m2 * m11 - m4 * m13 * m2 * m11 - m12 * m1 * m6 * m11 + m0 * m13 * m6 * m11 +
3599 		m4 * m1 * m14 * m11 - m0 * m5 * m14 * m11 - m8 * m5 * m2 * m15 + m4 * m9 * m2 * m15 +
3600 		m8 * m1 * m6 * m15 - m0 * m9 * m6 * m15 - m4 * m1 * m10 * m15 + m0 * m5 * m10 * m15);
3601 
3602 	return [
3603 		d * (m9*m14*m7-m13*m10*m7+m13*m6*m11-m5*m14*m11-m9*m6*m15+m5*m10*m15),
3604 		d * (m13*m10*m3-m9*m14*m3-m13*m2*m11+m1*m14*m11+m9*m2*m15-m1*m10*m15),
3605 		d * (m5*m14*m3-m13*m6*m3+m13*m2*m7-m1*m14*m7-m5*m2*m15+m1*m6*m15),
3606 		d * (m9*m6*m3-m5*m10*m3-m9*m2*m7+m1*m10*m7+m5*m2*m11-m1*m6*m11),
3607 
3608 		d * (m12*m10*m7-m8*m14*m7-m12*m6*m11+m4*m14*m11+m8*m6*m15-m4*m10*m15),
3609 		d * (m8*m14*m3-m12*m10*m3+m12*m2*m11-m0*m14*m11-m8*m2*m15+m0*m10*m15),
3610 		d * (m12*m6*m3-m4*m14*m3-m12*m2*m7+m0*m14*m7+m4*m2*m15-m0*m6*m15),
3611 		d * (m4*m10*m3-m8*m6*m3+m8*m2*m7-m0*m10*m7-m4*m2*m11+m0*m6*m11),
3612 
3613 		d * (m8*m13*m7-m12*m9*m7+m12*m5*m11-m4*m13*m11-m8*m5*m15+m4*m9*m15),
3614 		d * (m12*m9*m3-m8*m13*m3-m12*m1*m11+m0*m13*m11+m8*m1*m15-m0*m9*m15),
3615 		d * (m4*m13*m3-m12*m5*m3+m12*m1*m7-m0*m13*m7-m4*m1*m15+m0*m5*m15),
3616 		d * (m8*m5*m3-m4*m9*m3-m8*m1*m7+m0*m9*m7+m4*m1*m11-m0*m5*m11),
3617 
3618 		d * (m12*m9*m6-m8*m13*m6-m12*m5*m10+m4*m13*m10+m8*m5*m14-m4*m9*m14),
3619 		d * (m8*m13*m2-m12*m9*m2+m12*m1*m10-m0*m13*m10-m8*m1*m14+m0*m9*m14),
3620 		d * (m12*m5*m2-m4*m13*m2-m12*m1*m6+m0*m13*m6+m4*m1*m14-m0*m5*m14),
3621 		d * (m4*m9*m2-m8*m5*m2+m8*m1*m6-m0*m9*m6-m4*m1*m10+m0*m5*m10)
3622 	];
3623 }
3624 
3625 /**
3626  * Calculates the inverse transpose of the upper-left 3x3 matrix of a 4x4 matrix.
3627  *
3628  * @param {array} m The input matrix.
3629  *
3630  * @returns {array} A new 3x3 matrix representing the inverse transpose of the upper-left 3x3 matrix of m.
3631  */
3632 SpiderGL.Math.Mat4.inverseTranspose33 = function (m) {
3633 	var m11 = m[ 0], m21 = m[ 1], m31 = m[ 2],
3634 	    m12 = m[ 4], m22 = m[ 5], m32 = m[ 6],
3635 	    m13 = m[ 8], m23 = m[ 9], m33 = m[10];
3636 
3637 	var d =  1 / (m11*(m33*m22 - m32*m23) - m21*(m33*m12 - m32*m13) + m31*(m23*m12 - m22*m13));
3638 
3639 	return [
3640 		d * (m33*m22 - m32*m23), d * (m32*m13 - m33*m12), d * (m23*m12 - m22*m13),
3641 		d * (m31*m23 - m33*m21), d * (m33*m11 - m31*m13), d * (m21*m13 - m23*m11),
3642 		d * (m32*m21 - m31*m22), d * (m31*m12 - m32*m11), d * (m22*m11 - m21*m12)
3643 	];
3644 }
3645 
3646 /**
3647  * Calculates the trace (i.e. the sum of the diagonal elements) of a 4x4 matrix.
3648  *
3649  * @param {array} m The input matrix.
3650  *
3651  * @returns {number} The trace of m.
3652  */
3653 SpiderGL.Math.Mat4.trace = function (m) {
3654 	return (m[0] + m[5] + m[10] + m[15]);
3655 }
3656 
3657 /**
3658  * Creates a column-major 4x4 translation matrix.
3659  * The input translation vector will be placed on the 4th column of an identity matrix.
3660  *
3661  * @param {array} v A 3-dimensional vector with translation offsets.
3662  *
3663  * @returns {array} A new column-major 4x4 translation matrix.
3664  */
3665 SpiderGL.Math.Mat4.translation = function (v) {
3666 	return [
3667 		   1,    0,    0, 0,
3668 		   0,    1,    0, 0,
3669 		   0,    0,    1, 0,
3670 		v[0], v[1], v[2], 1
3671 	];
3672 }
3673 
3674 /**
3675  * Creates a column-major 4x4 rotation matrix.
3676  * The returned matrix will represent a counter-clockwise rotation about the input axis by the input angle in radians.
3677  * The input axis need not to be normalized.
3678  *
3679  * @param {number} angle The counter-clockwise rotation angle, in radians.
3680  * @param {array} axis A 3-dimensional vector representing the rotation axis.
3681  *
3682  * @returns {array} A new column-major 4x4 rotation matrix.
3683  */
3684 SpiderGL.Math.Mat4.rotationAngleAxis = function (angle, axis) {
3685 	var ax = SpiderGL.Math.Vec3.normalize(axis);
3686 	var s  = SpiderGL.Math.sin(angle);
3687 	var c  = SpiderGL.Math.cos(angle);
3688 	var q   = 1 - c;
3689 
3690 	var x = ax[0];
3691 	var y = ax[1];
3692 	var z = ax[2];
3693 
3694 	var xx, yy, zz, xy, yz, zx, xs, ys, zs;
3695 
3696 	xx = x * x;
3697 	yy = y * y;
3698 	zz = z * z;
3699 	xy = x * y;
3700 	yz = y * z;
3701 	zx = z * x;
3702 	xs = x * s;
3703 	ys = y * s;
3704 	zs = z * s;
3705 
3706 	return [
3707 		(q * xx) + c,  (q * xy) + zs, (q * zx) - ys, 0,
3708 		(q * xy) - zs, (q * yy) + c,  (q * yz) + xs, 0,
3709 		(q * zx) + ys, (q * yz) - xs, (q * zz) + c,  0,
3710 		            0,             0,            0,  1
3711 	];
3712 }
3713 
3714 /**
3715  * Creates a column-major 4x4 scaling matrix.
3716  *
3717  * @param {array} v The scaling amount as a 3-dimensional array.
3718  *
3719  * @returns {array} A new column-major 4x4 scaling matrix.
3720  */
3721 SpiderGL.Math.Mat4.scaling = function (v) {
3722 	return [
3723 		v[0],    0,    0, 0,
3724 		   0, v[1],    0, 0,
3725 		   0,    0, v[2], 0,
3726 		   0,    0,    0, 1
3727 	];
3728 }
3729 
3730 /**
3731  * Creates a column-major 4x4 look-at matrix.
3732  *
3733  * @param {array} position The viewer's position as a 3-dimensional vector.
3734  * @param {array} target The viewer's look-at point as a 3-dimensional vector.
3735  * @param {array} position The viewer's up vector as a 3-dimensional vector.
3736  *
3737  * @returns {array} A new column-major 4x4 look-at matrix.
3738  */
3739 SpiderGL.Math.Mat4.lookAt = function (position, target, up) {
3740 	var v = SpiderGL.Math.Vec3.normalize(SpiderGL.Math.Vec3.sub(target, position));
3741 	var u = SpiderGL.Math.Vec3.normalize(up);
3742 	var s = SpiderGL.Math.Vec3.normalize(SpiderGL.Math.Vec3.cross(v, u));
3743 
3744 	u = SpiderGL.Math.Vec3.cross(s, v);
3745 
3746 	var m = [
3747 		 s[0], u[0], -v[0], 0,
3748 		 s[1], u[1], -v[1], 0,
3749 		 s[2], u[2], -v[2], 0,
3750 		    0,    0,    0,  1
3751 	];
3752 
3753 	return SpiderGL.Math.Mat4.translate$(m, SpiderGL.Math.Vec3.neg(position));
3754 }
3755 
3756 /**
3757  * Creates a column-major 4x4 orthographic projection matrix.
3758  *
3759  * @param {array} min A 3-component array with the minimum coordinates of the parallel viewing volume.
3760  * @param {array} max A 3-component array with the maximum coordinates of the parallel viewing volume.
3761  *
3762  * @returns {array} A new column-major 4x4 orthographic projection matrix.
3763  */
3764 SpiderGL.Math.Mat4.ortho = function (min, max) {
3765 	var sum = SpiderGL.Math.Vec3.add(max, min);
3766 	var dif = SpiderGL.Math.Vec3.sub(max, min);
3767 
3768 	return [
3769 		     2 / dif[0],                 0,           0,      0,
3770 		               0,       2 / dif[1],           0,      0,
3771 		               0,                0, -2 / dif[2],      0,
3772 		-sum[0] / dif[0], -sum[1] / dif[1], -sum[2] / dif[2], 1
3773 	];
3774 }
3775 
3776 /**
3777  * Creates a column-major 4x4 frustum matrix.
3778  *
3779  * @param {array} min A 3-component array with the minimum coordinates of the frustum volume.
3780  * @param {array} max A 3-component array with the maximum coordinates of the frustum volume.
3781  *
3782  * @returns {array} A new column-major 4x4 frustum matrix.
3783  */
3784 SpiderGL.Math.Mat4.frustum = function (min, max) {
3785 	var sum = SpiderGL.Math.Vec3.add(max, min);
3786 	var dif = SpiderGL.Math.Vec3.sub(max, min);
3787 	var t   = 2.0 * min[2];
3788 
3789 	return [
3790 		     t / dif[0],               0,                     0,  0,
3791 		              0,      t / dif[1],                     0,  0,
3792 		sum[0] / dif[0], sum[1] / dif[1],      -sum[2] / dif[2], -1,
3793 		              0,               0, -t *  max[2] / dif[2],  0
3794 	];
3795 }
3796 
3797 /**
3798  * Creates a column-major 4x4 perspective projection matrix.
3799  *
3800  * @param {number} fovY The vertical field-of-view angle, in radians.
3801  * @param {number} aspectRatio The projection plane aspect ratio.
3802  * @param {number} zNear The distance of the near clipping plane.
3803  * @param {number} zFar The distance of the far clipping plane.
3804  *
3805  * @returns {array} A new column-major 4x4 perspective projection matrix.
3806  */
3807 SpiderGL.Math.Mat4.perspective = function (fovY, aspectRatio, zNear, zFar) {
3808 	var a = zNear * SpiderGL.Math.tan(fovY / 2);
3809 	var b = a * aspectRatio;
3810 
3811 	return SpiderGL.Math.Mat4.frustum([-b, -a, zNear], [b, a, zFar]);
3812 }
3813 
3814 /**
3815  * Copies a 4x4 matrix.
3816  *
3817  * @param {array} dst The destination 4x4 matrix.
3818  * @param {array} src The source 4x4 matrix.
3819  *
3820  * @returns {array} The input matrix dst, where dst[i] = src[i].
3821  */
3822 SpiderGL.Math.Mat4.copy$ = function (dst, src) {
3823 	for (var i=0; i<16; ++i) {
3824 		dst[i] = src[i];
3825 	}
3826 	return dst;
3827 }
3828 
3829 /**
3830  * Sets a 4x4 matrix as the identity matrix.
3831  *
3832  * @param {array} m The input 4x4 matrix to be set as identity.
3833  *
3834  * @returns {array} The input matrix m.
3835  */
3836 SpiderGL.Math.Mat4.identity$ = function (m) {
3837 	m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0;
3838 	m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0;
3839 	m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0;
3840 	m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
3841 	return m;
3842 }
3843 
3844 /**
3845  * In-place negation of a 4x4 matrix.
3846  *
3847  * @param {array} m The input 4x4 matrix.
3848  *
3849  * @returns {array} The input matrix m, where m[i] = -m[i].
3850  */
3851 SpiderGL.Math.Mat4.neg$ = function (m) {
3852 	for (var i=0; i<16; ++i) {
3853 		m[i] = -m[i];
3854 	}
3855 	return m;
3856 }
3857 
3858 /**
3859  * In-place addition of two 4x4 matrices.
3860  *
3861  * @param {array} a The first 4x4 input matrix.
3862  * @param {array} b The second 4x4 input matrix.
3863  *
3864  * @returns {array} The input matrix a, where a[i] = a[i] + b[i].
3865  */
3866 SpiderGL.Math.Mat4.add$ = function (a, b) {
3867 	for (var i=0; i<16; ++i) {
3868 		a[i] += b[i];
3869 	}
3870 	return a;
3871 }
3872 
3873 /**
3874  * In-place subtraction of two 4x4 matrices.
3875  *
3876  * @param {array} a The first 4x4 input matrix.
3877  * @param {array} b The second 4x4 input matrix.
3878  *
3879  * @returns {array} The input matrix a, where a[i] = a[i] - b[i].
3880  */
3881 SpiderGL.Math.Mat4.sub$ = function (a, b) {
3882 	for (var i=0; i<16; ++i) {
3883 		a[i] -= b[i];
3884 	}
3885 	return a;
3886 }
3887 
3888 /**
3889  * In-place multiplication of two 4x4 matrices.
3890  *
3891  * @param {array} a The first 4x4 input matrix.
3892  * @param {array} b The second 4x4 input matrix.
3893  *
3894  * @returns {array} The input matrix a, where a = a * b.
3895  */
3896 SpiderGL.Math.Mat4.mul$ = function (a, b) {
3897 	var a0  = a[ 0], a1  = a[ 1],  a2 = a[ 2], a3  = a[ 3],
3898 	    a4  = a[ 4], a5  = a[ 5],  a6 = a[ 6], a7  = a[ 7],
3899 	    a8  = a[ 8], a9  = a[ 9], a10 = a[10], a11 = a[11],
3900 	    a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15],
3901 
3902 	    b0  = b[ 0], b1  = b[ 1], b2  = b[ 2], b3  = b[ 3],
3903 	    b4  = b[ 4], b5  = b[ 5], b6  = b[ 6], b7  = b[ 7],
3904 	    b8  = b[ 8], b9  = b[ 9], b10 = b[10], b11 = b[11],
3905 	    b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
3906 
3907 	a[ 0] = a0*b0 + a4*b1 + a8*b2  + a12*b3;
3908 	a[ 1] = a1*b0 + a5*b1 + a9*b2  + a13*b3;
3909 	a[ 2] = a2*b0 + a6*b1 + a10*b2 + a14*b3;
3910 	a[ 3] = a3*b0 + a7*b1 + a11*b2 + a15*b3;
3911 
3912 	a[ 4] = a0*b4 + a4*b5 + a8*b6  + a12*b7;
3913 	a[ 5] = a1*b4 + a5*b5 + a9*b6  + a13*b7;
3914 	a[ 6] = a2*b4 + a6*b5 + a10*b6 + a14*b7;
3915 	a[ 7] = a3*b4 + a7*b5 + a11*b6 + a15*b7;
3916 
3917 	a[ 8] = a0*b8 + a4*b9 + a8*b10  + a12*b11;
3918 	a[ 9] = a1*b8 + a5*b9 + a9*b10  + a13*b11;
3919 	a[10] = a2*b8 + a6*b9 + a10*b10 + a14*b11;
3920 	a[11] = a3*b8 + a7*b9 + a11*b10 + a15*b11;
3921 
3922 	a[12] = a0*b12 + a4*b13 + a8*b14  + a12*b15;
3923 	a[13] = a1*b12 + a5*b13 + a9*b14  + a13*b15;
3924 	a[14] = a2*b12 + a6*b13 + a10*b14 + a14*b15;
3925 	a[15] = a3*b12 + a7*b13 + a11*b14 + a15*b15;
3926 
3927 	return a;
3928 }
3929 
3930 /**
3931  * In-place subtraction of a 4x4 matrix and a scalar.
3932  *
3933  * @param {array} m The 4x4 input matrix.
3934  * @param {number} s The input scalar.
3935  *
3936  * @returns {array} The input matrix m, where m[i] = m[i] * s.
3937  */
3938 SpiderGL.Math.Mat4.muls$ = function (m, s) {
3939 	for (var i=0; i<16; ++i) {
3940 		m[i] *= s;
3941 	}
3942 	return m;
3943 }
3944 
3945 /**
3946  * In-place component-wise multiplication of two 4x4 matrices.
3947  *
3948  * @param {array} a The first 4x4 input matrix.
3949  * @param {array} b The second 4x4 input matrix.
3950  *
3951  * @returns {array} The input matrix a, where a[i] = a[i] * b[i].
3952  */
3953 SpiderGL.Math.Mat4.compMul$ = function (a, b) {
3954 	for (var i=0; i<16; ++i) {
3955 		a[i] *= b[i];
3956 	}
3957 	return a;
3958 }
3959 
3960 /**
3961  * In-place component-wise division of two 4x4 matrices.
3962  *
3963  * @param {array} a The first 4x4 input matrix.
3964  * @param {array} b The second 4x4 input matrix.
3965  *
3966  * @returns {array} The input matrix a, where a[i] = a[i] / b[i].
3967  */
3968 SpiderGL.Math.Mat4.compDiv$ = function (a, b) {
3969 	for (var i=0; i<16; ++i) {
3970 		a[i] /= b[i];
3971 	}
3972 	return a;
3973 }
3974 
3975 /**
3976  * In-place transpose of a 4x4 matrix.
3977  *
3978  * @param {array} m The 4x4 input matrix.
3979  *
3980  * @returns {array} The transposed input matrix m.
3981  */
3982 SpiderGL.Math.Mat4.transpose$ = function (m) {
3983 	var t;
3984 	t = m[ 1]; m[ 1] = m[ 4]; m[ 4] = t;
3985 	t = m[ 2]; m[ 2] = m[ 8]; m[ 8] = t;
3986 	t = m[ 3]; m[ 3] = m[12]; m[12] = t;
3987 	t = m[ 6]; m[ 6] = m[ 9]; m[ 9] = t;
3988 	t = m[ 7]; m[ 7] = m[13]; m[13] = t;
3989 	t = m[11]; m[11] = m[14]; m[14] = t;
3990 	return m;
3991 }
3992 
3993 /**
3994  * In-place inversion of a 4x4 matrix.
3995  *
3996  * @param {array} m The 4x4 input matrix.
3997  *
3998  * @returns {array} The inverted input matrix m.
3999  */
4000 SpiderGL.Math.Mat4.invert$ = function (m) {
4001 	var m0  = m[ 0], m1  = m[ 1], m2  = m[ 2], m3  = m[ 3],
4002 	    m4  = m[ 4], m5  = m[ 5], m6  = m[ 6], m7  = m[ 7],
4003 	    m8  = m[ 8], m9  = m[ 9], m10 = m[10], m11 = m[11],
4004 	    m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];
4005 
4006 	var d = 1.0 / (
4007 		m12 * m9 * m6 * m3 - m8 * m13 * m6 * m3 - m12 * m5 * m10 * m3 + m4 * m13 * m10 * m3 +
4008 		m8 * m5 * m14 * m3 - m4 * m9 * m14 * m3 - m12 * m9 * m2 * m7 + m8 * m13 * m2 * m7 +
4009 		m12 * m1 * m10 * m7 - m0 * m13 * m10 * m7 - m8 * m1 * m14 * m7 + m0 * m9 * m14 * m7 +
4010 		m12 * m5 * m2 * m11 - m4 * m13 * m2 * m11 - m12 * m1 * m6 * m11 + m0 * m13 * m6 * m11 +
4011 		m4 * m1 * m14 * m11 - m0 * m5 * m14 * m11 - m8 * m5 * m2 * m15 + m4 * m9 * m2 * m15 +
4012 		m8 * m1 * m6 * m15 - m0 * m9 * m6 * m15 - m4 * m1 * m10 * m15 + m0 * m5 * m10 * m15);
4013 
4014 	m[ 0] = d * (m9*m14*m7-m13*m10*m7+m13*m6*m11-m5*m14*m11-m9*m6*m15+m5*m10*m15);
4015 	m[ 1] = d * (m13*m10*m3-m9*m14*m3-m13*m2*m11+m1*m14*m11+m9*m2*m15-m1*m10*m15);
4016 	m[ 2] = d * (m5*m14*m3-m13*m6*m3+m13*m2*m7-m1*m14*m7-m5*m2*m15+m1*m6*m15);
4017 	m[ 3] = d * (m9*m6*m3-m5*m10*m3-m9*m2*m7+m1*m10*m7+m5*m2*m11-m1*m6*m11);
4018 
4019 	m[ 4] = d * (m12*m10*m7-m8*m14*m7-m12*m6*m11+m4*m14*m11+m8*m6*m15-m4*m10*m15);
4020 	m[ 5] = d * (m8*m14*m3-m12*m10*m3+m12*m2*m11-m0*m14*m11-m8*m2*m15+m0*m10*m15);
4021 	m[ 6] = d * (m12*m6*m3-m4*m14*m3-m12*m2*m7+m0*m14*m7+m4*m2*m15-m0*m6*m15);
4022 	m[ 7] = d * (m4*m10*m3-m8*m6*m3+m8*m2*m7-m0*m10*m7-m4*m2*m11+m0*m6*m11);
4023 
4024 	m[ 8] = d * (m8*m13*m7-m12*m9*m7+m12*m5*m11-m4*m13*m11-m8*m5*m15+m4*m9*m15);
4025 	m[ 9] = d * (m12*m9*m3-m8*m13*m3-m12*m1*m11+m0*m13*m11+m8*m1*m15-m0*m9*m15);
4026 	m[10] = d * (m4*m13*m3-m12*m5*m3+m12*m1*m7-m0*m13*m7-m4*m1*m15+m0*m5*m15);
4027 	m[11] = d * (m8*m5*m3-m4*m9*m3-m8*m1*m7+m0*m9*m7+m4*m1*m11-m0*m5*m11);
4028 
4029 	m[12] = d * (m12*m9*m6-m8*m13*m6-m12*m5*m10+m4*m13*m10+m8*m5*m14-m4*m9*m14);
4030 	m[13] = d * (m8*m13*m2-m12*m9*m2+m12*m1*m10-m0*m13*m10-m8*m1*m14+m0*m9*m14);
4031 	m[14] = d * (m12*m5*m2-m4*m13*m2-m12*m1*m6+m0*m13*m6+m4*m1*m14-m0*m5*m14);
4032 	m[15] = d * (m4*m9*m2-m8*m5*m2+m8*m1*m6-m0*m9*m6-m4*m1*m10+m0*m5*m10);
4033 
4034 	return m;
4035 }
4036 
4037 /**
4038  * In-place column-major translation of a 4x4 matrix.
4039  *
4040  * @param {array} m The 4x4 input matrix.
4041  * @param {array} v The 3-dimensional translation vector.
4042  *
4043  * @returns {array} The translated input matrix m with the same result as m = m * t, where t is a translation matrix.
4044  */
4045 SpiderGL.Math.Mat4.translate$ = function (m, v) {
4046 	var x = v[0],
4047 	    y = v[1],
4048 	    z = v[2];
4049 
4050 	m[12] = m[ 0]*x + m[ 4]*y + m[ 8]*z + m[12];
4051 	m[13] = m[ 1]*x + m[ 5]*y + m[ 9]*z + m[13];
4052 	m[14] = m[ 2]*x + m[ 6]*y + m[10]*z + m[14];
4053 	m[15] = m[ 3]*x + m[ 7]*y + m[11]*z + m[15];
4054 
4055 	return m;
4056 }
4057 
4058 /**
4059  * In-place column-major rotation of a 4x4 matrix.
4060  * The input matrix m will be post-multiplied by a matrix r representing a counter-clockwise rotation about the input axis by the input angle in radians.
4061  * The input axis need not to be normalized.
4062  *
4063  * @param {array} m The input 4x4 matrix.
4064  * @param {number} angle The counter-clockwise rotation angle, in radians.
4065  * @param {array} axis A 3-dimensional vector representing the rotation axis.
4066  *
4067  * @returns {array} The rotated input matrix m with the same result as m = m * r, where r is a rotation matrix.
4068  */
4069 SpiderGL.Math.Mat4.rotateAngleAxis$ = function (m, angle, axis) {
4070 	var r = SpiderGL.Math.Mat4.rotationAngleAxis(angle, axis);
4071 	return SpiderGL.Math.Mat4.mul$(m, r);
4072 }
4073 
4074 /**
4075  * In-place column-major scaling of a 4x4 matrix.
4076  *
4077  * @param {array} m The 4x4 input matrix.
4078  * @param {array} v The scaling amount as a 3-dimensional array.
4079  *
4080  * @returns {array} The scaled input matrix m with the same result as m = m * s, where s is a scaling matrix.
4081  */
4082 SpiderGL.Math.Mat4.scale$ = function (m, v) {
4083 	var x = v[0],
4084 	    y = v[1],
4085 	    z = v[2];
4086 
4087 	m[ 0] *= x; m[ 1] *= x; m[ 2] *= x; m[ 3] *= x;
4088 	m[ 4] *= y; m[ 5] *= y; m[ 6] *= y; m[ 7] *= y;
4089 	m[ 8] *= z; m[ 9] *= z; m[10] *= z; m[11] *= z;
4090 
4091 	return m;
4092 }
4093 
4094 /*---------------------------------------------------------*/
4095 
4096 
4097 
4098 // quaternion
4099 /*---------------------------------------------------------*/
4100 
4101 /**
4102  * The SpiderGL.Math.Quat namespace.
4103  * The provided functions operate on quaternions, represented as standard JavaScript arrays of length 4.
4104  * The identity quaternion is represented as the vector [0, 0, 0, 1].
4105  *
4106  * @namespace The SpiderGL.Math.Quat namespace defines operations on quaternions.
4107  */
4108 SpiderGL.Math.Quat = { };
4109 
4110 /**
4111  * Duplicates the input quaternion.
4112  *
4113  * @param {array} q The input quaternion.
4114  *
4115  * @returns {array} A new 4-component array r, where r[i] = q[i] (same as q.slice(0, 4)).
4116  */
4117 SpiderGL.Math.Quat.dup = function (q) {
4118 	return q.slice(0, 4);
4119 }
4120 
4121 /**
4122  * Creates an identity quaternion.
4123  * The identity quaternion is represented as the vector [0, 0, 0, 1].
4124  *
4125  * @returns {array} A new 4-component array r, where r = [0, 0, 0, 1].
4126  */
4127 SpiderGL.Math.Quat.identity = function () {
4128 	return [0, 0, 0, 1];
4129 }
4130 
4131 /**
4132  * Inverts a quaternion.
4133  *
4134  * @param {array} q The input quaternion.
4135  *
4136  * @returns {array} A new 4-component array r, where r = [-q[0], -q[1], -q[2], q[3]].
4137  */
4138 SpiderGL.Math.Quat.inverse = function (q) {
4139 	return [-q[0], -q[1], -q[2], q[3]];
4140 }
4141 
4142 /**
4143  * Multiplies two quaternions.
4144  *
4145  * @param {array} p The first quaternion multiplication operand.
4146  * @param {array} q The second quaternion multiplication quaternion.
4147  *
4148  * @returns {array} A new 4-component array r, where r = [-q[0], -q[1], -q[2], q[3]].
4149  */
4150 SpiderGL.Math.Quat.mul = function (p, q) {
4151 	var px = p[0],
4152 	    py = p[1],
4153 	    pz = p[2],
4154 	    pw = p[3];
4155 
4156 	var qx = q[0],
4157 	    qy = q[1],
4158 	    qz = q[2],
4159 	    qw = q[3];
4160 
4161 	return [
4162 		px*qw + pw*qx + pz*qy - py*qz,
4163 		py*qw + pw*qy + px*qz - pz*qx,
4164 		pz*qw + pw*qz + py*qx - px*qy,
4165 		pw*qw - px*qx - py*qy - pz*qz
4166 	];
4167 }
4168 
4169 /**
4170  * Multiplies a quaternion by a scalar.
4171  *
4172  * @param {array} q The first quaternion multiplication operand.
4173  * @param {number} s The second scalar multiplication operand.
4174  *
4175  * @returns {array} A new 4-component array r, where r[i] = q[i]*s.
4176  */
4177 SpiderGL.Math.Quat.muls = function (q, s) {
4178 	return [q[0]*s, q[1]*s, q[2]*s, q[3]*s];
4179 }
4180 
4181 SpiderGL.Math.Quat.normalize = function (q) {
4182 	var s = 1 / SpiderGL.Math.sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
4183 	return SpiderGL.Math.Quat.muls(q, s);
4184 }
4185 
4186 SpiderGL.Math.Quat.from33 = function (m) {
4187 	var m00 = m[0],
4188 	    m10 = m[1],
4189 	    m20 = m[2];
4190 
4191 	var m01 = m[3],
4192 	    m11 = m[4],
4193 	    m21 = m[5];
4194 
4195 	var m02 = m[6],
4196 	    m12 = m[7],
4197 	    m22 = m[8];
4198 
4199 	var t = m00 + m11 + m22;
4200 	var s;
4201 
4202 	if (t > 0) {
4203 		t = t + 1;
4204 		s = 0.5 / SpiderGL.Math.sqrt(t);
4205 		return [
4206 			(m21 - m12) * s,
4207 			(m02 - m20) * s,
4208 			(m10 - m01) * s,
4209 			t * s
4210 		];
4211 	} else if ((m00 > m11) && (m00 > m22)) {
4212 		t = m00 - m11 - m22 + 1;
4213 		s = 0.5 / SpiderGL.Math.sqrt(t);
4214 		return [
4215 			t * s,
4216 			(m10 + m01) * s,
4217 			(m02 + m20) * s,
4218 			(m21 - m12) * s,
4219 		];
4220 	}
4221 	else if (m11 > m22) {
4222 		t = -m00 + m11 - m22 + 1;
4223 		s = 0.5 / SpiderGL.Math.sqrt(t);
4224 		return [
4225 			(m10 + m01) * s,
4226 			t * s,
4227 			(m21 + m12) * s,
4228 			(m02 - m20) * s
4229 		];
4230 	}
4231 	else {
4232 		t = -m00 - m11 + m22 + 1;
4233 		s = 0.5 / SpiderGL.Math.sqrt(t);
4234 		return [
4235 			(m02 + m20) * s,
4236 			(m21 + m12) * s,
4237 			t * s,
4238 			(m10 - m01) * s
4239 		];
4240 	}
4241 
4242 	return null;
4243 }
4244 
4245 SpiderGL.Math.Quat.to33 = function (q) {
4246 	var x  = q[0],
4247 	    y  = q[1],
4248 	    z  = q[2],
4249 	    w  = q[3];
4250 
4251 	var xx = x*x,
4252 	    xy = x*y,
4253 	    xz = x*z,
4254 	    xw = x*w;
4255 
4256 	var yy = y*y,
4257 	    yz = y*z,
4258 	    yw = y*w;
4259 
4260 	var zz = z*z,
4261 	    zw = z*w;
4262 
4263 	return [
4264 		1 - 2 * ( yy + zz ),
4265 		    2 * ( xy + zw ),
4266 		    2 * ( xz - yw ),
4267 
4268 		    2 * ( xy - zw ),
4269 		1 - 2 * ( xx + zz ),
4270 		    2 * ( yz + xw ),
4271 
4272 		    2 * ( xz + yw ),
4273 		    2 * ( yz - xw ),
4274 		1 - 2 * ( xx + yy )
4275 	];
4276 }
4277 
4278 SpiderGL.Math.Quat.from44 = function (m) {
4279 	return SpiderGL.Math.Quat.from33(SpiderGL.Math.Mat4.to33(m));
4280 }
4281 
4282 SpiderGL.Math.Quat.to44 = function (q) {
4283 	return SpiderGL.Math.Mat3.to44(SpiderGL.Math.Quat.to33(q));
4284 }
4285 
4286 SpiderGL.Math.Quat.fromAngleAxis = function (angle, axis) {
4287 	return [0, 0, 0, 1];
4288 }
4289 
4290 SpiderGL.Math.Quat.toAngleAxis = function (q) {
4291 	return [0, 0, 0, 1];
4292 }
4293 
4294 SpiderGL.Math.Quat.fromEulerAngles = function (x, y, z) {
4295 	return [0, 0, 0, 1];
4296 }
4297 
4298 SpiderGL.Math.Quat.toEulerAngles = function (q) {
4299 	return [0, 0, 0, 1];
4300 }
4301 
4302 SpiderGL.Math.Quat.copy$ = function (p, q) {
4303 	p[0] = q[0];
4304 	p[1] = q[1];
4305 	p[2] = q[2];
4306 	p[3] = q[3];
4307 	return p;
4308 }
4309 
4310 SpiderGL.Math.Quat.identity$ = function (q) {
4311 	q[0] = 0;
4312 	q[1] = 0;
4313 	q[2] = 0;
4314 	q[3] = 1;
4315 	return q;
4316 }
4317 
4318 SpiderGL.Math.Quat.invert$ = function (q) {
4319 	q[0] = -q[0];
4320 	q[1] = -q[1];
4321 	q[2] = -q[2];
4322 	return q;
4323 }
4324 
4325 SpiderGL.Math.Quat.mul$ = function (q) {
4326 	var px = p[0],
4327 	    py = p[1],
4328 	    pz = p[2],
4329 	    pw = p[3];
4330 
4331 	var qx = q[0],
4332 	    qy = q[1],
4333 	    qz = q[2],
4334 	    qw = q[3];
4335 
4336 	q[0] = px*qw + pw*qx + pz*qy - py*qz;
4337 	q[1] = py*qw + pw*qy + px*qz - pz*qx;
4338 	q[2] = pz*qw + pw*qz + py*qx - px*qy;
4339 	q[3] = pw*qw - px*qx - py*qy - pz*qz;
4340 
4341 	return q;
4342 }
4343 
4344 SpiderGL.Math.Quat.muls$ = function (q, s) {
4345 	q[0] *= s;
4346 	q[1] *= s;
4347 	q[2] *= s;
4348 	q[3] *= s;
4349 	return q;
4350 }
4351 
4352 SpiderGL.Math.Quat.normalize$ = function (q) {
4353 	var s = 1 / SpiderGL.Math.sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
4354 	return SpiderGL.Math.Quat.muls$(q, s);
4355 }
4356 
4357 /*---------------------------------------------------------*/
4358 
4359 
4360 
4361 // general
4362 /*---------------------------------------------------------*/
4363 
4364 SpiderGL.Math.project = function (xyzw, modelViewProjectionMatrix, viewport, depthRange) {
4365 	var v3 = SpiderGL.Math.Vec3;
4366 	var m4 = SpiderGL.Math.Mat4;
4367 
4368 	var r    = m4.mul4(modelViewProjectionMatrix, xyzw);
4369 	var invW = 1 / r[3];
4370 	r[3]     = invW;
4371 
4372 	v3.muls$(r, invW / 2);
4373 	v3.adds$(r, 0.5);
4374 
4375 	v3.mul$(r, [viewport[2], viewport[3], depthRange[1] - depthRange[0]]);
4376 	v3.add$(r, [viewport[0], viewport[1], depthRange[0]]);
4377 
4378 	return r;
4379 };
4380 
4381 SpiderGL.Math.unproject = function (xyz, modelViewProjectionMatrixInverse, viewport, depthRange) {
4382 	var v3 = SpiderGL.Math.Vec3;
4383 	var m4 = SpiderGL.Math.Mat4;
4384 
4385 	var r = v3.to4(xyz, 1.0);
4386 
4387 	v3.sub$(r, [viewport[0], viewport[1], depthRange[0]]);
4388 	v3.div$(r, [viewport[2], viewport[3], depthRange[1] - depthRange[0]]);
4389 
4390 	v3.muls$(r, 2);
4391 	v3.subs$(r, 1);
4392 
4393 	r        = m4.mul4(modelViewProjectionMatrixInverse, r);
4394 	var invW = 1 / r[3];
4395 	r[3]     = invW;
4396 
4397 	v3.muls$(r, invW);
4398 
4399 	return r;
4400 };
4401 
4402 /*---------------------------------------------------------*/
4403